Beispiel #1
0
        /// <summary>
        /// Report download progress through the database if necessary.
        /// </summary>
        /// <param name="innerState">
        /// The inner State.
        /// </param>
        private void ReportProgress(InnerState innerState)
        {
            long now = PolicyExtensions.GetCurrentMilliseconds();

            if (innerState.BytesSoFar - innerState.BytesNotified > DownloaderService.MinimumProgressStep &&
                now - innerState.TimeLastNotification > DownloaderService.MinimumProgressTime)
            {
                // we store progress updates to the database here
                this.downloadInfo.CurrentBytes = innerState.BytesSoFar;
                DownloadsDatabase.UpdateDownloadCurrentBytes(this.downloadInfo);

                innerState.BytesNotified        = innerState.BytesSoFar;
                innerState.TimeLastNotification = now;

                long totalBytesSoFar = innerState.BytesThisSession + this.downloaderService.BytesSoFar;

                Debug.WriteLine(
                    "DownloadThread : downloaded {0} out of {1}",
                    this.downloadInfo.CurrentBytes,
                    this.downloadInfo.TotalBytes);
                Debug.WriteLine(
                    "DownloadThread :      total {0} out of {1}", totalBytesSoFar, this.downloaderService.TotalLength);

                this.downloaderService.NotifyUpdateBytes(totalBytesSoFar);
            }
        }
Beispiel #2
0
        /// <summary>
        /// The do validate zip files.
        /// </summary>
        /// <param name="state">
        /// The state.
        /// </param>
        private void DoValidateZipFiles(object state)
        {
            var downloads = DownloadsDatabase.GetDownloads().Select(x => Helpers.GenerateSaveFileName(this, x.FileName)).ToArray();

            var result = downloads.Any() && downloads.All(this.IsValidZipFile);

            this.RunOnUiThread(
                delegate
            {
                this.pauseButton.Click += delegate
                {
                    Finish();
                    StartActivity(typeof(ZipTestActivity));
                };

                this.dashboardView.Visibility   = ViewStates.Visible;
                this.useCellDataView.Visibility = ViewStates.Gone;

                if (result)
                {
                    this.statusTextView.SetText(Resource.String.text_validation_complete);
                    this.pauseButton.SetText(Android.Resource.String.Ok);
                }
                else
                {
                    this.statusTextView.SetText(Resource.String.text_validation_failed);
                    this.pauseButton.SetText(Android.Resource.String.Cancel);
                }
            });
        }
        private void DoValidateZipFiles(object state)
        {
            var downloads = DownloadsDatabase.GetDownloads().Select(x => Helpers.GenerateSaveFileName(this, x.FileName)).ToArray();

            var result = downloads.Any() && downloads.All(IsValidZipFile);

            RunOnUiThread(delegate
            {
                pauseButton.Click += delegate
                {
                    HideAllControls();
                    StorehouseInitializationParadigm();
                };

                dashboardView.Visibility   = ViewStates.Visible;
                useCellDataView.Visibility = ViewStates.Gone;

                if (result)
                {
                    statusTextView.SetText(Resource.String.text_validation_complete);
                    pauseButton.SetText(Android.Resource.String.Ok);
                }
                else
                {
                    statusTextView.SetText(Resource.String.text_validation_failed);
                    pauseButton.SetText(Android.Resource.String.Cancel);
                }

                // I ADDED THESE METHODS
                HideAllControls();
                StorehouseInitializationParadigm();
            });
        }
Beispiel #4
0
        /// <summary>
        /// Called when we've reached the end of the HTTP response stream, to update the database and
        /// check for consistency.
        /// </summary>
        /// <param name="state">
        /// The state.
        /// </param>
        /// <param name="innerState">
        /// The inner State.
        /// </param>
        private void HandleEndOfStream(State state, InnerState innerState)
        {
            Debug.WriteLine("HandleEndOfStream");

            this.downloadInfo.CurrentBytes = innerState.BytesSoFar;

            //// this should always be set from the market
            // if (innerState.HeaderContentLength == null)
            // {
            // downloadInfo.TotalBytes = innerState.BytesSoFar;
            // }
            DownloadsDatabase.UpdateDownload(this.downloadInfo);

            bool lengthMismatched = innerState.HeaderContentLength != null &&
                                    innerState.BytesSoFar != int.Parse(innerState.HeaderContentLength);

            if (lengthMismatched)
            {
                string message;
                ExpansionDownloadStatus finalStatus;
                if (CannotResume(innerState))
                {
                    finalStatus = ExpansionDownloadStatus.CannotResume;
                    message     = "mismatched content length";
                }
                else
                {
                    finalStatus = this.GetFinalStatusForHttpError(state);
                    message     = "closed socket before end of file";
                }

                throw new StopRequestException(finalStatus, message);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Read some data from the HTTP response stream, handling I/O errors.
        /// </summary>
        /// <param name="state">
        /// </param>
        /// <param name="innerState">
        /// </param>
        /// <param name="data">
        /// data buffer to use to read data
        /// </param>
        /// <param name="entityStream">
        /// entityStream stream for reading the HTTP response entity
        /// </param>
        /// <returns>
        /// the number of bytes actually read or -1 if the end of the stream has been reached
        /// </returns>
        private int ReadFromResponse(State state, InnerState innerState, byte[] data, Stream entityStream)
        {
            try
            {
                return(entityStream.Read(data, 0, data.Length));
            }
            catch (IOException ex)
            {
                this.LogNetworkState();
                this.downloadInfo.CurrentBytes = innerState.BytesSoFar;
                DownloadsDatabase.UpdateDownload(this.downloadInfo);

                string message;
                ExpansionDownloadStatus finalStatus;
                if (CannotResume(innerState))
                {
                    finalStatus = ExpansionDownloadStatus.CannotResume;
                    message     =
                        string.Format("while reading response: {0}, can't resume interrupted download with no ETag", ex);
                }
                else
                {
                    finalStatus = this.GetFinalStatusForHttpError(state);
                    message     = string.Format("while reading response: {0}", ex);
                }

                throw new StopRequestException(finalStatus, message, ex);
            }
        }
Beispiel #6
0
        public static void DownloadAssetDatabase()
        {
            var sw = new Stopwatch();

            sw.Start();
            string json = new WebClient().DownloadString("https://raw.githubusercontent.com/headassbtw/LootSaber/master/AssetDatabase.json");

            sw.Stop();
            Plugin.Log.Info("Database downloaded in " + sw.ElapsedMilliseconds + "ms");
            DownloadsDatabase items = JsonConvert.DeserializeObject <DownloadsDatabase>(json);

            FileManager.assetDB = items;
        }
        /// <summary>
        /// Starts the download if necessary.
        /// </summary>
        /// <remarks>
        /// This function starts a flow that
        /// does many things:
        ///   1) Checks to see if the APK version has been checked and the
        ///      metadata database updated
        ///   2) If the APK version does not match, checks the new LVL status
        ///      to see if a new download is required
        ///   3) If the APK version does match, then checks to see if the
        ///      download(s) have been completed
        ///   4) If the downloads have been completed, returns
        ///      <see cref="DownloadServiceRequirement.NoDownloadRequired"/>
        /// The idea is that this can be called during the startup of an
        /// application to quickly ascertain if the application needs to wait
        /// to hear about any updated APK expansion files.
        /// This does mean that the application MUST be run with a network
        /// connection for the first time, even if Market delivers all of the
        /// files.
        /// </remarks>
        /// <param name="context">
        /// Your application Context.
        /// </param>
        /// <param name="pendingIntent">
        /// A PendingIntent to start the Activity in your application that
        /// shows the download progress and which will also start the
        /// application when downloadcompletes.
        /// </param>
        /// <param name="serviceType">
        /// The class of your <see cref="DownloaderService"/> implementation.
        /// </param>
        /// <returns>
        /// Whether the service was started and the reason for starting the
        /// service.
        /// Either <see cref="DownloadServiceRequirement.NoDownloadRequired"/>,
        /// <see cref="DownloadServiceRequirement.LvlCheckRequired"/>, or
        /// <see cref="DownloadServiceRequirement.DownloadRequired"/>
        /// </returns>
        public static DownloadServiceRequirement StartDownloadServiceIfRequired(
            Context context, PendingIntent pendingIntent, Type serviceType)
        {
            // first: do we need to do an LVL update?
            // we begin by getting our APK version from the package manager
            PackageInfo pi = context.PackageManager.GetPackageInfo(context.PackageName, 0);

            var status = DownloadServiceRequirement.NoDownloadRequired;

            // we need to update the LVL check and get a successful status to proceed
            if (IsLvlCheckRequired(pi))
            {
                status = DownloadServiceRequirement.LvlCheckRequired;
            }

            // we don't have to update LVL. Do we still have a download to start?
            if (DownloadsDatabase.DownloadStatus == ExpansionDownloadStatus.None)
            {
                List <DownloadInfo>        infos       = DownloadsDatabase.GetDownloads();
                IEnumerable <DownloadInfo> nonExisting =
                    infos.Where(i => !Helpers.DoesFileExist(context, i.FileName, i.TotalBytes, true));

                if (nonExisting.Any())
                {
                    status = DownloadServiceRequirement.DownloadRequired;
                    DownloadsDatabase.DownloadStatus = ExpansionDownloadStatus.Unknown;
                }
            }
            else
            {
                status = DownloadServiceRequirement.DownloadRequired;
            }

            switch (status)
            {
            case DownloadServiceRequirement.DownloadRequired:
            case DownloadServiceRequirement.LvlCheckRequired:
                var fileIntent = new Intent(context.ApplicationContext, serviceType);
                fileIntent.PutExtra(DownloaderServiceExtras.PendingIntent, pendingIntent);
                context.StartService(fileIntent);
                break;
            }

            return(status);
        }
Beispiel #8
0
        public static void SaveJson2(string path)
        {
            var bruh = new List <string> {
                "", ""
            };
            var bruh2 = new Rarity(bruh, bruh, bruh, bruh);
            var bruh3 = new DownloadsDatabase(bruh2, bruh2, bruh2, bruh2, bruh2);

            using (StreamWriter w = new StreamWriter(path))
            {
                JsonSerializer serializer = new JsonSerializer();
                string         contents   = JsonConvert.SerializeObject(bruh3);
                var            jtw        = new JsonTextWriter(w);
                jtw.Formatting = Formatting.Indented;
                serializer.Serialize(jtw, bruh3);
                w.Close();
            }
        }
        /// <summary>
        /// The APK has been updated and a filename has been sent down from the
        /// Market call. If the file has the same name as the previous file, we do
        /// nothing as the file is guaranteed to be the same. If the file does not
        /// have the same name, we download it if it hasn't already been delivered by
        /// Market.
        /// </summary>
        /// <param name="filename">
        /// the name of the new file
        /// </param>
        /// <param name="fileSize">
        /// the size of the new file
        /// </param>
        /// <returns>
        /// The handle file updated.
        /// </returns>
        private bool HandleFileUpdated(string filename, long fileSize)
        {
            DownloadInfo di = DownloadsDatabase.GetDownloadInfo(filename);

            if (di != null && di.FileName != null)
            {
                if (filename == di.FileName)
                {
                    return(false);
                }

                // remove partially downloaded file if it is there
                string deleteFile = Helpers.GenerateSaveFileName(this, di.FileName);
                if (File.Exists(deleteFile))
                {
                    File.Delete(deleteFile);
                }
            }

            return(!Helpers.DoesFileExist(this, filename, fileSize, true));
        }
Beispiel #10
0
        private void CheckDownloadedFile()
        {
            var downloads = DownloadsDatabase.GetDownloads().OrderByDescending(d => d.LastModified);

            if (downloads.Count() == 0)
            {
                return;
            }

            var down = downloads.First();

            if (down.ExpansionFileType != LicenseVerificationLibrary.Policy.ApkExpansionPolicy.ExpansionFileType.MainFile)
            {
                return;
            }

            string fileName = down.FileName;


            //int versionCode = PackageManager.GetPackageInfo(this.PackageName, 0).VersionCode;

            //string fileName = Helpers.GetExpansionApkFileName(this, true, versionCode);

            string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/Android/obb/" + this.PackageName + "/" + fileName;

            if (System.IO.File.Exists(path))
            {
                if (fileName != DataManager.Get <IPreferencesManager>().Preferences.ApkDownloaded)
                {
                    CopyDownloadedFile(path);
                    //Toast.MakeText(this, "Copia", ToastLength.Long).Show();
                }
                else
                {
                    //Toast.MakeText(this, "C'è Già", ToastLength.Long).Show();

                    StartApp();
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// The update download database.
        /// </summary>
        /// <param name="status">
        /// The status.
        /// </param>
        /// <param name="countRetry">
        /// The count retry.
        /// </param>
        /// <param name="retryAfter">
        /// The retry after.
        /// </param>
        /// <param name="redirectCount">
        /// The redirect count.
        /// </param>
        /// <param name="gotData">
        /// The got data.
        /// </param>
        private void UpdateDownloadDatabase(
            ExpansionDownloadStatus status, bool countRetry, int retryAfter, int redirectCount, bool gotData)
        {
            this.downloadInfo.Status        = status;
            this.downloadInfo.RetryAfter    = retryAfter;
            this.downloadInfo.RedirectCount = redirectCount;
            this.downloadInfo.LastModified  = PolicyExtensions.GetCurrentMilliseconds();
            if (!countRetry)
            {
                this.downloadInfo.FailedCount = 0;
            }
            else if (gotData)
            {
                this.downloadInfo.FailedCount = 1;
            }
            else
            {
                this.downloadInfo.FailedCount++;
            }

            DownloadsDatabase.UpdateDownload(this.downloadInfo);
        }
Beispiel #12
0
        /// <summary>
        /// Go through each of the Expansion APK files defined in the project
        /// and determine if the files are present and match the required size.
        /// </summary>
        /// <remarks>
        /// Free applications should definitely consider doing this, as this
        /// allows the application to be launched for the first time without
        /// having a network connection present.
        /// Paid applications that use LVL should probably do at least one LVL
        /// check that requires the network to be present, so this is not as
        /// necessary.
        /// </remarks>
        /// <returns>
        /// True if they are present, otherwise False;
        /// </returns>
        private bool AreExpansionFilesDelivered()
        {
            var downloads = DownloadsDatabase.GetDownloads();

            return(downloads.Any() && downloads.All(x => Helpers.DoesFileExist(this, x.FileName, x.TotalBytes, false)));
        }
Beispiel #13
0
        internal static DownloadRequestResponse DownloadAsset(DownloadsDatabase db)
        {
            DownloadRequestResponse resp = new DownloadRequestResponse();
            var rng = new Random();


            Rarity        rolledRarity       = new Rarity();
            List <String> rolledType         = new List <string>();
            int           amountOfRolledType = 0;

            switch (Random.Range(0, 5))
            {
            case 0:
                rolledRarity = db.Tier1;
                Plugin.Log.Info("Rolled Tier 1");
                resp.tier = 1;
                break;

            case 1:
                rolledRarity = db.Tier2;
                Plugin.Log.Info("Rolled Tier 2");
                resp.tier = 2;
                break;

            case 2:
                rolledRarity = db.Tier3;
                Plugin.Log.Info("Rolled Tier 3");
                resp.tier = 3;
                break;

            case 3:
                rolledRarity = db.Tier4;
                Plugin.Log.Info("Rolled Tier 4");
                resp.tier = 4;
                break;

            case 4:
                rolledRarity = db.Tier5;
                Plugin.Log.Info("Rolled Tier 5");
                resp.tier = 5;
                break;
            }
            string folder  = "";
            int    maxtype = 4;

            if (!AssetModDetection.MenuFonts)
            {
                maxtype = 3;
            }
            var a = Random.Range(0, maxtype);

            if (a.Equals(rollcat1))
            {
                a = Random.Range(0, maxtype);
            }
            rollcat1 = a;
            switch (a)
            {
            case 0:
                rolledType         = rolledRarity.Sabers;
                amountOfRolledType = rolledType.Count;
                folder             = "UserData\\LootSaber\\Asset Cache\\CustomSabers";
                Plugin.Log.Info("Rolled Saber");
                resp.assetType = "Saber";
                break;

            case 1:
                rolledType         = rolledRarity.Notes;
                amountOfRolledType = rolledType.Count;
                folder             = "UserData\\LootSaber\\Asset Cache\\CustomNotes";
                Plugin.Log.Info("Rolled Note");
                resp.assetType = "Note";
                break;

            case 2:
                rolledType         = rolledRarity.Platforms;
                amountOfRolledType = rolledType.Count;
                folder             = "UserData\\LootSaber\\Asset Cache\\CustomPlatforms";
                Plugin.Log.Info("Rolled Platform");
                resp.assetType = "Platform";
                break;

            case 3:
                rolledType         = rolledRarity.MenuFonts;
                amountOfRolledType = rolledType.Count;
                folder             = "UserData\\LootSaber\\Asset Cache\\UserData\\CustomMenuText\\Fonts";
                Plugin.Log.Info("Rolled Menu Font");
                resp.assetType = "Menu Text Font";
                break;
            }
            var URL = rolledType.ElementAt(Random.Range(0, amountOfRolledType));

            var    client    = new WebClient();
            string _realname = URL.Substring(URL.LastIndexOf("/") + 1).Replace("%20", " ");

            if (_realname.Contains("?"))
            {
                _realname = _realname.Substring(0, _realname.IndexOf("?"));
            }



            string fileSavePath = UnityGame.InstallPath + "\\" + folder + "\\" + _realname;

            try
            {
                Plugin.Log.Notice("Downloading " + _realname + " From " + URL);
                client.DownloadFileAsync(
                    new Uri(URL),
                    fileSavePath
                    );
                resp.client = client;
            }
            catch (Exception)
            {
                //if the folder doesn't exist, create it and try again
                Directory.CreateDirectory(UnityGame.InstallPath + "\\" + folder);
                client.DownloadFileAsync(
                    new Uri(URL),
                    fileSavePath
                    );
                resp.client = client;
            }
            resp.filePath = fileSavePath;
            return(resp);
        }
Beispiel #14
0
        //rolls a few dice to give you an asset
        internal static string DiceRoll(DownloadsDatabase db, Random rng)
        {
            Rarity        rolledRarity       = new Rarity();
            List <String> rolledType         = new List <string>();
            int           amountOfRolledType = 0;

            switch (Random.Range(0, 5))
            {
            case 0:
                rolledRarity = db.Tier1;
                Plugin.Log.Info("Rolled Tier 1");
                break;

            case 1:
                rolledRarity = db.Tier2;
                Plugin.Log.Info("Rolled Tier 2");
                break;

            case 2:
                rolledRarity = db.Tier3;
                Plugin.Log.Info("Rolled Tier 3");
                break;

            case 3:
                rolledRarity = db.Tier4;
                Plugin.Log.Info("Rolled Tier 4");
                break;

            case 4:
                rolledRarity = db.Tier5;
                Plugin.Log.Info("Rolled Tier 5");
                break;
            }
            var a = Random.Range(0, 4);

            if (a.Equals(rollcat1))
            {
                a = Random.Range(0, 4);
            }
            rollcat1 = a;
            switch (a)
            {
            case 0:
                rolledType         = rolledRarity.Sabers;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Saber");
                break;

            case 1:
                rolledType         = rolledRarity.Notes;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Note");
                break;

            case 2:
                rolledType         = rolledRarity.Platforms;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Platform");
                break;

            case 3:
                rolledType         = rolledRarity.MenuFonts;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Menu Font");
                break;
            }
            return(rolledType.ElementAt(Random.Range(0, amountOfRolledType)));
        }
        internal async void DownloadAsset(DownloadsDatabase db, Random rng, int slot)
        {
            Rarity        rolledRarity       = new Rarity();
            List <String> rolledType         = new List <string>();
            int           amountOfRolledType = 0;

            switch (rng.Next(0, 5))
            {
            case 0:
                rolledRarity = db.Tier1;
                Plugin.Log.Info("Rolled Tier 1");
                break;

            case 1:
                rolledRarity = db.Tier2;
                Plugin.Log.Info("Rolled Tier 2");
                break;

            case 2:
                rolledRarity = db.Tier3;
                Plugin.Log.Info("Rolled Tier 3");
                break;

            case 3:
                rolledRarity = db.Tier4;
                Plugin.Log.Info("Rolled Tier 4");
                break;

            case 4:
                rolledRarity = db.Tier5;
                Plugin.Log.Info("Rolled Tier 5");
                break;
            }
            var a = rng.Next(0, 4);

            if (a.Equals(rollcat1))
            {
                rng = new Random(3294704);
                a   = rng.Next(0, 4);
            }
            rollcat1 = a;
            switch (a)
            {
            case 0:
                rolledType         = rolledRarity.Sabers;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Saber");
                break;

            case 1:
                rolledType         = rolledRarity.Notes;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Note");
                break;

            case 2:
                rolledType         = rolledRarity.Platforms;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Platform");
                break;

            case 3:
                rolledType         = rolledRarity.MenuFonts;
                amountOfRolledType = rolledType.Count;
                Plugin.Log.Info("Rolled Menu Font");
                break;
            }
            var URL = rolledType.ElementAt(rng.Next(0, amountOfRolledType));

            var    client    = new WebClient();
            string _realname = URL.Substring(URL.LastIndexOf("/")).Replace("%20", " ");

            if (_realname.Contains("?"))
            {
                _realname = _realname.Substring(0, _realname.IndexOf("?"));
            }
            switch (slot)
            {
            case 1:
                client.DownloadProgressChanged += wc_progChange1;
                break;

            case 2:
                client.DownloadProgressChanged += wc_progChange2;
                break;

            case 3:
                client.DownloadProgressChanged += wc_progChange3;
                break;
            }
            string folder = "";

            switch (a)
            {
            case 0:
                folder = "CustomSabers";
                break;

            case 1:
                folder = "CustomNotes";
                break;

            case 2:
                folder = "CustomPlatforms";
                break;

            case 3:
                folder = "UserData\\CustomMenuText\\Fonts";
                break;
            }
            client.DownloadFileAsync(
                new Uri(URL),
                UnityGame.InstallPath + "\\" + folder + "\\" + _realname
                );
        }
                /// <summary>
                /// The allow.
                /// </summary>
                /// <param name="reason">
                /// The reason.
                /// </param>
                /// <exception cref="Java.Lang.RuntimeException">
                /// Error with LVL checking and database integrity
                /// </exception>
                /// <exception cref="Java.Lang.RuntimeException">
                /// Error with getting information from package name
                /// </exception>
                public void Allow(PolicyServerResponse reason)
                {
                    try
                    {
                        int count = this.policy.GetExpansionFilesCount();
                        if (count == 0)
                        {
                            Debug.WriteLine("No expansion packs.");
                        }

                        ExpansionDownloadStatus status = 0;
                        for (int index = 0; index < count; index++)
                        {
                            var type = (ApkExpansionPolicy.ExpansionFileType)index;

                            ApkExpansionPolicy.ExpansionFile expansionFile = this.policy.GetExpansionFile(type);
                            string currentFileName = expansionFile.FileName;
                            if (currentFileName != null)
                            {
                                var di = new DownloadInfo {
                                    ExpansionFileType = type, FileName = currentFileName,
                                };

                                if (this.Context.HandleFileUpdated(currentFileName, expansionFile.FileSize))
                                {
                                    status = ExpansionDownloadStatus.Unknown;
                                    di.ResetDownload();
                                    di.Uri        = expansionFile.Url;
                                    di.TotalBytes = expansionFile.FileSize;
                                    di.Status     = status;
                                    DownloadsDatabase.UpdateDownload(di);
                                }
                                else
                                {
                                    // we need to read the download information from the database
                                    DownloadInfo dbdi = DownloadsDatabase.GetDownloadInfo(di.FileName);
                                    if (dbdi == null)
                                    {
                                        // the file exists already and is the correct size
                                        // was delivered by Market or through another mechanism
                                        Debug.WriteLine(string.Format("file {0} found. Not downloading.", di.FileName));
                                        di.Status       = ExpansionDownloadStatus.Success;
                                        di.TotalBytes   = expansionFile.FileSize;
                                        di.CurrentBytes = expansionFile.FileSize;
                                        di.Uri          = expansionFile.Url;
                                        DownloadsDatabase.UpdateDownload(di);
                                    }
                                    else if (dbdi.Status != ExpansionDownloadStatus.Success)
                                    {
                                        // we just update the URL
                                        dbdi.Uri = expansionFile.Url;
                                        DownloadsDatabase.UpdateDownload(dbdi);
                                        status = ExpansionDownloadStatus.Unknown;
                                    }
                                }
                            }
                        }

                        // first: do we need to do an LVL update?
                        // we begin by getting our APK version from the package manager
                        try
                        {
                            PackageInfo pi = this.Context.PackageManager.GetPackageInfo(this.Context.PackageName, 0);
                            DownloadsDatabase.UpdateMetadata(pi.VersionCode, status);
                            DownloadServiceRequirement required = StartDownloadServiceIfRequired(
                                this.Context, this.Context.pPendingIntent, this.Context.GetType());
                            switch (required)
                            {
                            case DownloadServiceRequirement.NoDownloadRequired:
                                this.Context.downloadNotification.OnDownloadStateChanged(DownloaderState.Completed);
                                break;

                            case DownloadServiceRequirement.LvlCheckRequired:     // DANGER WILL ROBINSON!
                                Debug.WriteLine("In LVL checking loop!");
                                this.Context.downloadNotification.OnDownloadStateChanged(
                                    DownloaderState.FailedUnlicensed);
                                throw new RuntimeException("Error with LVL checking and database integrity");

                            case DownloadServiceRequirement.DownloadRequired:

                                // do nothing: the download will notify the application when things are done
                                break;
                            }
                        }
                        catch (PackageManager.NameNotFoundException e1)
                        {
                            e1.PrintStackTrace();
                            throw new RuntimeException("Error with getting information from package name");
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine("LVL Update Exception: " + ex.Message);
                            throw;
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Allow Exception: " + ex.Message);
                        throw;
                    }
                    finally
                    {
                        this.Context.IsServiceRunning = false;
                    }
                }
Beispiel #17
0
 /// <summary>
 /// Update necessary database fields based on values of HTTP response headers that have been read.
 /// </summary>
 /// <param name="innerState">
 /// The inner State.
 /// </param>
 private void UpdateDatabaseFromHeaders(InnerState innerState)
 {
     this.downloadInfo.ETag = innerState.HeaderETag;
     DownloadsDatabase.UpdateDownload(this.downloadInfo);
 }
        /// <summary>
        /// This is the main thread for the Downloader.
        /// This thread is responsible for queuing up downloads and other goodness.
        /// </summary>
        /// <param name="intent">
        /// The intent that was recieved.
        /// </param>
        protected override void OnHandleIntent(Intent intent)
        {
            Log.Debug(Tag, "DownloaderService.OnHandleIntent");

            this.IsServiceRunning = true;
            try
            {
                var pendingIntent = (PendingIntent)intent.GetParcelableExtra(DownloaderServiceExtras.PendingIntent);

                if (null != pendingIntent)
                {
                    this.downloadNotification.PendingIntent = pendingIntent;
                    this.pPendingIntent = pendingIntent;
                }
                else if (null != this.pPendingIntent)
                {
                    this.downloadNotification.PendingIntent = this.pPendingIntent;
                }
                else
                {
                    Log.Debug(Tag, "LVLDL Downloader started in bad state without notification intent.");
                    return;
                }

                // when the LVL check completes, a successful response will update the service
                if (IsLvlCheckRequired(this.packageInfo))
                {
                    this.UpdateLvl(this);
                    return;
                }

                // get each download
                List <DownloadInfo> infos = DownloadsDatabase.GetDownloads();
                this.BytesSoFar  = 0;
                this.TotalLength = 0;
                this.fileCount   = infos.Count();
                foreach (DownloadInfo info in infos)
                {
                    // We do an (simple) integrity check on each file, just to
                    // make sure and to verify that the file matches the state
                    if (info.Status == ExpansionDownloadStatus.Success &&
                        !Helpers.DoesFileExist(this, info.FileName, info.TotalBytes, true))
                    {
                        info.Status       = ExpansionDownloadStatus.None;
                        info.CurrentBytes = 0;
                    }

                    // get aggregate data
                    this.TotalLength += info.TotalBytes;
                    this.BytesSoFar  += info.CurrentBytes;
                }

                this.PollNetworkState();
                if (this.connectionReceiver == null)
                {
                    // We use this to track network state, such as when WiFi, Cellular, etc. is enabled
                    // when downloads are paused or in progress.
                    this.connectionReceiver = new InnerBroadcastReceiver(this);
                    var intentFilter = new IntentFilter(ConnectivityManager.ConnectivityAction);
                    intentFilter.AddAction(WifiManager.WifiStateChangedAction);
                    this.RegisterReceiver(this.connectionReceiver, intentFilter);
                }

                // loop through all downloads and fetch them
                int types = Enum.GetValues(typeof(ApkExpansionPolicy.ExpansionFileType)).Length;
                for (int index = 0; index < types; index++)
                {
                    DownloadInfo info = infos[index];
                    Log.Debug(Tag, "Starting download of " + info.FileName);

                    long startingCount = info.CurrentBytes;

                    if (info.Status != ExpansionDownloadStatus.Success)
                    {
                        var dt = new DownloadThread(info, this, this.downloadNotification);
                        this.CancelAlarms();
                        this.ScheduleAlarm(ActiveThreadWatchdog);
                        dt.Run();
                        this.CancelAlarms();
                    }

                    DownloadsDatabase.UpdateFromDatabase(ref info);
                    bool            setWakeWatchdog = false;
                    DownloaderState notifyStatus;
                    switch (info.Status)
                    {
                    case ExpansionDownloadStatus.Forbidden:

                        // the URL is out of date
                        this.UpdateLvl(this);
                        return;

                    case ExpansionDownloadStatus.Success:
                        this.BytesSoFar += info.CurrentBytes - startingCount;

                        if (index < infos.Count() - 1)
                        {
                            continue;
                        }

                        DownloadsDatabase.UpdateMetadata(this.packageInfo.VersionCode, ExpansionDownloadStatus.None);
                        this.downloadNotification.OnDownloadStateChanged(DownloaderState.Completed);
                        return;

                    case ExpansionDownloadStatus.FileDeliveredIncorrectly:

                        // we may be on a network that is returning us a web page on redirect
                        notifyStatus      = DownloaderState.PausedNetworkSetupFailure;
                        info.CurrentBytes = 0;
                        DownloadsDatabase.UpdateDownload(info);
                        setWakeWatchdog = true;
                        break;

                    case ExpansionDownloadStatus.PausedByApp:
                        notifyStatus = DownloaderState.PausedByRequest;
                        break;

                    case ExpansionDownloadStatus.WaitingForNetwork:
                    case ExpansionDownloadStatus.WaitingToRetry:
                        notifyStatus    = DownloaderState.PausedNetworkUnavailable;
                        setWakeWatchdog = true;
                        break;

                    case ExpansionDownloadStatus.QueuedForWifi:
                    case ExpansionDownloadStatus.QueuedForWifiOrCellularPermission:

                        // look for more detail here
                        notifyStatus = this.wifiManager != null && !this.wifiManager.IsWifiEnabled
                                               ? DownloaderState.PausedWifiDisabledNeedCellularPermission
                                               : DownloaderState.PausedNeedCellularPermission;
                        setWakeWatchdog = true;
                        break;

                    case ExpansionDownloadStatus.Canceled:
                        notifyStatus    = DownloaderState.FailedCanceled;
                        setWakeWatchdog = true;
                        break;

                    case ExpansionDownloadStatus.InsufficientSpaceError:
                        notifyStatus    = DownloaderState.FailedSdCardFull;
                        setWakeWatchdog = true;
                        break;

                    case ExpansionDownloadStatus.DeviceNotFoundError:
                        notifyStatus    = DownloaderState.PausedSdCardUnavailable;
                        setWakeWatchdog = true;
                        break;

                    default:
                        notifyStatus = DownloaderState.Failed;
                        break;
                    }

                    if (setWakeWatchdog)
                    {
                        this.ScheduleAlarm(WatchdogWakeTimer);
                    }
                    else
                    {
                        this.CancelAlarms();
                    }

                    // failure or pause state
                    this.downloadNotification.OnDownloadStateChanged(notifyStatus);
                    return;
                }

                this.downloadNotification.OnDownloadStateChanged(DownloaderState.Completed);
            }
            catch (Exception ex)
            {
                Log.Error(Tag, ex.Message);
                Log.Error(Tag, ex.StackTrace);
            }
            finally
            {
                this.IsServiceRunning = false;
            }
        }