internal void InitializeUpdateAfterRestart()
        {
            JObject pendingUpdate = SettingsManager.GetPendingUpdate();

            if (pendingUpdate != null)
            {
                var updateIsLoading = (bool)pendingUpdate[CodePushConstants.PendingUpdateIsLoadingKey];
                if (updateIsLoading)
                {
                    // Pending update was initialized, but notifyApplicationReady was not called.
                    // Therefore, deduce that it is a broken update and rollback.
                    CodePushUtils.Log("Update did not finish loading the last time, rolling back to a previous version.");
                    NeedToReportRollback = true;
                    RollbackPackageAsync().Wait();
                }
                else
                {
                    DidUpdate = true;
                    // Clear the React dev bundle cache so that new updates can be loaded.
                    if (MainPage.UseDeveloperSupport)
                    {
                        ClearReactDevBundleCacheAsync().Wait();
                    }
                    // Mark that we tried to initialize the new update, so that if it crashes,
                    // we will know that we need to rollback when the app next starts.
                    SettingsManager.SavePendingUpdate((string)pendingUpdate[CodePushConstants.PendingUpdateHashKey], /* isLoading */ true);
                }
            }
        }
        internal static Task <long> GetBinaryResourcesModifiedTimeAsync(string fileName)
        {
            var pathToAssembly         = CodePushUtils.GetAppFolder();
            var pathToAssemblyResource = Path.Combine(pathToAssembly, CodePushConstants.AssetsBundlePrefix, fileName);
            var lastUpdateTime         = File.GetCreationTime(pathToAssemblyResource);

            return(Task.FromResult(new DateTimeOffset(lastUpdateTime).ToUnixTimeMilliseconds()));
        }
Пример #3
0
        public async Task <string> GetJavaScriptBundleFileAsync(string assetsBundleFileName)
        {
            AssetsBundleFileName = assetsBundleFileName;
            string binaryJsBundleUrl = CodePushUtils.GetAssetsBundlePrefix() + assetsBundleFileName;

            var binaryResourcesModifiedTime = await FileUtils.GetBinaryResourcesModifiedTimeAsync(AssetsBundleFileName).ConfigureAwait(false);

            var packageFile = await UpdateManager.GetCurrentPackageBundleAsync(AssetsBundleFileName).ConfigureAwait(false);

            if (packageFile == null)
            {
                // There has not been any downloaded updates.
                CodePushUtils.LogBundleUrl(binaryJsBundleUrl);
                IsRunningBinaryVersion = true;
                return(binaryJsBundleUrl);
            }

            var packageMetadata = await UpdateManager.GetCurrentPackageAsync().ConfigureAwait(false);

            long?binaryModifiedDateDuringPackageInstall       = null;
            var  binaryModifiedDateDuringPackageInstallString = (string)packageMetadata[CodePushConstants.BinaryModifiedTimeKey];

            if (binaryModifiedDateDuringPackageInstallString != null)
            {
                binaryModifiedDateDuringPackageInstall = long.Parse(binaryModifiedDateDuringPackageInstallString);
            }

            var packageAppVersion = (string)packageMetadata["appVersion"];

            if (binaryModifiedDateDuringPackageInstall != null &&
                binaryModifiedDateDuringPackageInstall == binaryResourcesModifiedTime &&
                AppVersion.Equals(packageAppVersion))
            {
                CodePushUtils.LogBundleUrl(packageFile.Path);
                IsRunningBinaryVersion = false;

                return(CodePushUtils.GetFileBundlePrefix() + CodePushUtils.ExtractSubFolder(packageFile.Path));
            }
            else
            {
                // The binary version is newer.
                DidUpdate = false;
                if (!MainPage.UseDeveloperSupport || !AppVersion.Equals(packageAppVersion))
                {
                    await ClearUpdatesAsync().ConfigureAwait(false);
                }

                CodePushUtils.LogBundleUrl(binaryJsBundleUrl);
                IsRunningBinaryVersion = true;
                return(binaryJsBundleUrl);
            }
        }
Пример #4
0
        public void downloadUpdate(JObject updatePackage, bool notifyProgress, IPromise promise)
        {
            Action downloadAction = async() =>
            {
                try
                {
                    updatePackage[CodePushConstants.BinaryModifiedTimeKey] = "" + await _codePush.GetBinaryResourcesModifiedTime();

                    await _codePush.UpdateManager.DownloadPackage(
                        updatePackage,
                        _codePush.AssetsBundleFileName,
                        new Progress <HttpProgress>(
                            (HttpProgress progress) =>
                    {
                        if (!notifyProgress)
                        {
                            return;
                        }

                        var downloadProgress = new JObject()
                        {
                            { "totalBytes", progress.TotalBytesToReceive },
                            { "receivedBytes", progress.BytesReceived }
                        };

                        _reactContext
                        .GetJavaScriptModule <RCTDeviceEventEmitter>()
                        .emit(CodePushConstants.DownloadProgressEventName, downloadProgress);
                    }
                            )
                        );

                    JObject newPackage = await _codePush.UpdateManager.GetPackage((string)updatePackage[CodePushConstants.PackageHashKey]);

                    promise.Resolve(newPackage);
                }
                catch (InvalidDataException e)
                {
                    CodePushUtils.Log(e.ToString());
                    SettingsManager.SaveFailedUpdate(updatePackage);
                    promise.Reject(e);
                }
                catch (Exception e)
                {
                    CodePushUtils.Log(e.ToString());
                    promise.Reject(e);
                }
            };

            Context.RunOnNativeModulesQueueThread(downloadAction);
        }
Пример #5
0
        public CodePushReactPackage(string deploymentKey, ReactPage mainPage)
        {
            AppVersion    = CodePushUtils.GetAppVersion();
            DeploymentKey = deploymentKey;
            MainPage      = mainPage;
            UpdateManager = new UpdateManager();

            if (CurrentInstance != null)
            {
                CodePushUtils.Log("More than one CodePush instance has been initialized. Please use the instance method codePush.getBundleUrlInternal() to get the correct bundleURL for a particular instance.");
            }

            CurrentInstance = this;
        }
Пример #6
0
        internal async static Task CopyNecessaryFilesFromCurrentPackageAsync(IFile diffManifestFile, IFolder currentPackageFolder, IFolder newPackageFolder)
        {
            await FileUtils.MergeFoldersAsync(currentPackageFolder, newPackageFolder).ConfigureAwait(false);

            JObject diffManifest = await CodePushUtils.GetJObjectFromFileAsync(diffManifestFile).ConfigureAwait(false);

            var deletedFiles = (JArray)diffManifest["deletedFiles"];

            foreach (string fileNameToDelete in deletedFiles)
            {
                var fileToDelete = await newPackageFolder.GetFileAsync(fileNameToDelete).ConfigureAwait(false);

                await fileToDelete.DeleteAsync().ConfigureAwait(false);
            }
        }
Пример #7
0
        internal async static Task CopyNecessaryFilesFromCurrentPackage(StorageFile diffManifestFile, StorageFolder currentPackageFolder, StorageFolder newPackageFolder)
        {
            await FileUtils.MergeFolders(currentPackageFolder, newPackageFolder);

            JObject diffManifest = await CodePushUtils.GetJObjectFromFile(diffManifestFile);

            var deletedFiles = (JArray)diffManifest["deletedFiles"];

            foreach (string fileNameToDelete in deletedFiles)
            {
                StorageFile fileToDelete = await newPackageFolder.GetFileAsync(fileNameToDelete);

                await fileToDelete.DeleteAsync();
            }
        }
        public CodePushReactPackage(string deploymentKey, ReactPage mainPage)
        {
            AppVersion             = Package.Current.Id.Version.Major + "." + Package.Current.Id.Version.Minor + "." + Package.Current.Id.Version.Build;
            DeploymentKey          = deploymentKey;
            MainPage               = mainPage;
            UpdateManager          = new UpdateManager();
            IsRunningBinaryVersion = false;
            // TODO implement telemetryManager
            // _codePushTelemetryManager = new CodePushTelemetryManager(this.applicationContext, CODE_PUSH_PREFERENCES);

            if (CurrentInstance != null)
            {
                CodePushUtils.Log("More than one CodePush instance has been initialized. Please use the instance method codePush.getBundleUrlInternal() to get the correct bundleURL for a particular instance.");
            }

            CurrentInstance = this;
        }
        private async Task <JObject> GetCurrentPackageInfoAsync()
        {
            var statusFile = await GetStatusFileAsync().ConfigureAwait(false);

            var info = await CodePushUtils.GetJObjectFromFileAsync(statusFile).ConfigureAwait(false);

            if (info != null)
            {
                return(info);
            }

            // info file has been corrupted - re-create it
            await statusFile.DeleteAsync().ConfigureAwait(false);

            statusFile = await GetStatusFileAsync().ConfigureAwait(false);

            return(await CodePushUtils.GetJObjectFromFileAsync(statusFile).ConfigureAwait(false));
        }
Пример #10
0
        public void getConfiguration(IPromise promise)
        {
            var config = new JObject
            {
                { "appVersion", _codePush.AppVersion },
                { "clientUniqueId", CodePushUtils.GetDeviceId() },
                { "deploymentKey", _codePush.DeploymentKey },
                { "serverUrl", CodePushConstants.CodePushServerUrl }
            };

            // TODO generate binary hash
            // string binaryHash = CodePushUpdateUtils.getHashForBinaryContents(mainActivity, isDebugMode);

            /*if (binaryHash != null)
             * {
             *  configMap.putString(PACKAGE_HASH_KEY, binaryHash);
             * }*/
            promise.Resolve(config);
        }
        internal async Task <JObject> GetPackageAsync(string packageHash)
        {
            StorageFolder packageFolder = await GetPackageFolderAsync(packageHash, false).ConfigureAwait(false);

            if (packageFolder == null)
            {
                return(null);
            }

            try
            {
                StorageFile packageFile = await packageFolder.GetFileAsync(CodePushConstants.PackageFileName).AsTask().ConfigureAwait(false);

                return(await CodePushUtils.GetJObjectFromFileAsync(packageFile).ConfigureAwait(false));
            }
            catch (IOException)
            {
                return(null);
            }
        }
        internal static JObject GetPendingUpdate()
        {
            var pendingUpdateString = (string)Settings.Values[CodePushConstants.PendingUpdateKey];

            if (pendingUpdateString == null)
            {
                return(null);
            }

            try
            {
                return(JObject.Parse(pendingUpdateString));
            }
            catch (Exception)
            {
                // Should not happen.
                CodePushUtils.Log("Unable to parse pending update metadata " + pendingUpdateString +
                                  " stored in SharedPreferences");
                return(null);
            }
        }
        // internal async static Task CopyNecessaryFilesFromCurrentPackageAsync(IFile diffManifestFile,IFolder unzipedPackageFolder, IFolder currentPackageFolder, IFolder newPackageFolder)
        internal async static Task CopyNecessaryFilesFromCurrentPackageAsync(IFile diffManifestFile, IFolder currentPackageFolder, IFolder newPackageFolder)
        {
            await FileUtils.MergeFoldersAsync(currentPackageFolder, newPackageFolder).ConfigureAwait(false);

            JObject diffManifest = await CodePushUtils.GetJObjectFromFileAsync(diffManifestFile).ConfigureAwait(false);

            var deletedFiles = (JArray)diffManifest["deletedFiles"];

            if (deletedFiles != null)
            {
                foreach (string fileNameToDelete in deletedFiles)
                {
                    var fileToDelete = await newPackageFolder.GetFileAsync(fileNameToDelete).ConfigureAwait(false);

                    await fileToDelete.DeleteAsync().ConfigureAwait(false);
                }
            }

            // var patchedFiles = (JArray)diffManifest["patchedFiles"];
            // if (patchedFiles != null)
            // {
            //     foreach (string fileNameToPatch in patchedFiles)
            //     {
            //         var patchFile = await unzipedPackageFolder.GetFileAsync(fileNameToPatch).ConfigureAwait(false);
            //         var patchFileContent = await patchFile.ReadAllTextAsync().ConfigureAwait(false);

            //         var bundleFile = await newPackageFolder.GetFileAsync(fileNameToPatch.Replace(".patch","")).ConfigureAwait(false);
            //         var bundleFileContent = await bundleFile.ReadAllTextAsync().ConfigureAwait(false);

            //         var dmp = new DiffMatchPatch();


            //         var fileToDelete = await newPackageFolder.GetFileAsync(fileNameToPatch).ConfigureAwait(false);
            //         await fileToDelete.DeleteAsync().ConfigureAwait(false);
            //     }
            // }
        }
        private async Task <JObject> GetCurrentPackageInfoAsync()
        {
            StorageFile statusFile = await GetStatusFileAsync().ConfigureAwait(false);

            return(await CodePushUtils.GetJObjectFromFileAsync(statusFile).ConfigureAwait(false));
        }
Пример #15
0
        internal static async Task <IFolder> GetCodePushFolderAsync()
        {
            var pathToCodePush = Path.Combine(CodePushUtils.GetFileBundlePrefix(), CodePushConstants.CodePushFolderPrefix);

            return(await FileSystem.Current.LocalStorage.CreateFolderAsync(pathToCodePush, CreationCollisionOption.OpenIfExists).ConfigureAwait(false));
        }
        private async Task <JObject> GetCurrentPackageInfo()
        {
            StorageFile statusFile = await GetStatusFile();

            return(await CodePushUtils.GetJObjectFromFile(statusFile));
        }