diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-02-13 16:23:34 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-02-14 10:37:21 +0000 |
commit | 38a9a29f4f9436cace7f0e7abf9c586057df8a4e (patch) | |
tree | c4e8c458dc595bc0ddb435708fa2229edfd00bd4 /chromium/components/module_installer | |
parent | e684a3455bcc29a6e3e66a004e352dea4e1141e7 (diff) | |
download | qtwebengine-chromium-38a9a29f4f9436cace7f0e7abf9c586057df8a4e.tar.gz |
BASELINE: Update Chromium to 73.0.3683.37
Change-Id: I08c9af2948b645f671e5d933aca1f7a90ea372f2
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/module_installer')
7 files changed, 157 insertions, 7 deletions
diff --git a/chromium/components/module_installer/android/BUILD.gn b/chromium/components/module_installer/android/BUILD.gn index 254ec93430d..556604defac 100644 --- a/chromium/components/module_installer/android/BUILD.gn +++ b/chromium/components/module_installer/android/BUILD.gn @@ -14,6 +14,9 @@ android_library("module_installer_java") { "java/src-common/org/chromium/components/module_installer/OnModuleInstallFinishedListener.java", ] jar_excluded_patterns = [ "*/ModuleInstaller.class" ] + deps = [ + "//base:base_java", + ] } # Contains stub implementation to be used for builds not supporting modules @@ -22,6 +25,7 @@ android_library("module_installer_stub_java") { java_files = [ "java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java" ] deps = [ ":module_installer_java", + "//base:base_java", ] } @@ -41,3 +45,11 @@ android_library("module_installer_impl_java") { "//third_party/google_android_play_core:com_google_android_play_core_java", ] } + +android_library("module_installer_test_java") { + java_files = [ "java/src-test/org/chromium/components/module_installer/ModuleInstaller.java" ] + deps = [ + ":module_installer_java", + "//base:base_java", + ] +} diff --git a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java index cbae643e7c2..84785b31354 100644 --- a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java +++ b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java @@ -5,6 +5,7 @@ package org.chromium.components.module_installer; import android.content.Context; +import android.content.pm.PackageManager; import com.google.android.play.core.splitcompat.SplitCompat; import com.google.android.play.core.splitcompat.ingestion.Verifier; @@ -60,6 +61,9 @@ class FakeModuleInstallerBackend extends ModuleInstallerBackend { } @Override + public void installDeferred(String moduleName) {} + + @Override public void close() { // No open resources. Nothing to be done here. } @@ -90,8 +94,12 @@ class FakeModuleInstallerBackend extends ModuleInstallerBackend { } // Check that the module's signature matches Chrome's. - Verifier verifier = new Verifier(context); - if (!verifier.verifySplits()) { + try { + Verifier verifier = new Verifier(context); + if (!verifier.verifySplits()) { + return false; + } + } catch (IOException | PackageManager.NameNotFoundException e) { return false; } diff --git a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java index f84f566cd4e..85d1b67997f 100644 --- a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java +++ b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java @@ -110,6 +110,18 @@ public class ModuleInstaller { getBackend().install(moduleName); } + /** + * Asynchronously installs module in the background when on unmetered connection and charging. + * Install is best effort and may fail silently. Upon success, the module will only be available + * after Chrome restarts. + * + * @param moduleName Name of the module. + */ + public static void installDeferred(String moduleName) { + ThreadUtils.assertOnUiThread(); + getBackend().installDeferred(moduleName); + } + private static void onFinished(boolean success, List<String> moduleNames) { ThreadUtils.assertOnUiThread(); diff --git a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstallerBackend.java b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstallerBackend.java index bba2ec2a7da..3d7a5bf7750 100644 --- a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstallerBackend.java +++ b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstallerBackend.java @@ -34,6 +34,12 @@ import java.util.List; public abstract void install(String moduleName); /** + * Asynchronously installs module in the background. + * @param moduleName Name of the module. + */ + public abstract void installDeferred(String moduleName); + + /** * Releases resources of this backend. Calling this method an install is in progress results in * undefined behavior. Calling any other method on this backend after closing results in * undefined behavior, too. diff --git a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java index 8e3b2f837b2..4061ba538bd 100644 --- a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java +++ b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java @@ -4,6 +4,9 @@ package org.chromium.components.module_installer; +import android.content.SharedPreferences; +import android.util.Pair; + import com.google.android.play.core.splitinstall.SplitInstallManager; import com.google.android.play.core.splitinstall.SplitInstallManagerFactory; import com.google.android.play.core.splitinstall.SplitInstallRequest; @@ -13,9 +16,16 @@ import com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.components.module_installer.ModuleInstallerBackend.OnFinishedListener; -import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; /** * Backend that uses the Play Core SDK to download a module from Play and install it subsequently. @@ -23,9 +33,22 @@ import java.util.Arrays; /* package */ class PlayCoreModuleInstallerBackend extends ModuleInstallerBackend implements SplitInstallStateUpdatedListener { private static final String TAG = "PlayCoreModInBackend"; + private static final String KEY_MODULES_REQUESTED_PREVIOUSLY = + "key_modules_requested_previously"; + private final Map<String, Pair<Long, Boolean>> mInstallStartTimeMap = new HashMap<>(); private final SplitInstallManager mManager; private boolean mIsClosed; + // FeatureModuleInstallStatus defined in //tools/metrics/histograms/enums.xml. + // These values are persisted to logs. Entries should not be renumbered and numeric values + // should never be reused. + private static final int INSTALL_STATUS_SUCCESS = 0; + private static final int INSTALL_STATUS_FAILURE = 1; + private static final int INSTALL_STATUS_REQUEST_ERROR = 2; + private static final int INSTALL_STATUS_CANCELLATION = 3; + // Keep this one at the end and increment appropriately when adding new status. + private static final int INSTALL_STATUS_COUNT = 4; + public PlayCoreModuleInstallerBackend(OnFinishedListener listener) { super(listener); mManager = SplitInstallManagerFactory.create(ContextUtils.getApplicationContext()); @@ -35,17 +58,42 @@ import java.util.Arrays; @Override public void install(String moduleName) { assert !mIsClosed; + + // Record start time in order to later report the install duration via UMA. We want to make + // a difference between modules that have been requested first before and after the last + // Chrome start. Modules that have been requested before may install quicker as they may be + // installed form cache. To do this, we use shared prefs to track modules previously + // requested. + assert !mInstallStartTimeMap.containsKey(moduleName); + SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); + Set<String> modulesRequestedPreviously = + prefs.getStringSet(KEY_MODULES_REQUESTED_PREVIOUSLY, new HashSet<String>()); + mInstallStartTimeMap.put(moduleName, + Pair.create(System.currentTimeMillis(), + modulesRequestedPreviously.contains(moduleName))); + Set<String> newModulesRequestedPreviously = new HashSet<>(modulesRequestedPreviously); + newModulesRequestedPreviously.add(moduleName); + SharedPreferences.Editor editor = prefs.edit(); + editor.putStringSet(KEY_MODULES_REQUESTED_PREVIOUSLY, newModulesRequestedPreviously); + editor.apply(); + SplitInstallRequest request = SplitInstallRequest.newBuilder().addModule(moduleName).build(); mManager.startInstall(request).addOnFailureListener(errorCode -> { Log.e(TAG, "Failed to request module '%s': error code %s", moduleName, errorCode); // If we reach this error condition |onStateUpdate| won't be called. Thus, call // |onFinished| here. - onFinished(false, Arrays.asList(moduleName)); + finish(false, Collections.singletonList(moduleName), INSTALL_STATUS_REQUEST_ERROR); }); } @Override + public void installDeferred(String moduleName) { + assert !mIsClosed; + mManager.deferredInstall(Collections.singletonList(moduleName)); + } + + @Override public void close() { assert !mIsClosed; mManager.unregisterListener(this); @@ -57,14 +105,36 @@ import java.util.Arrays; assert !mIsClosed; switch (state.status()) { case SplitInstallSessionStatus.INSTALLED: - onFinished(true, state.moduleNames()); + finish(true, state.moduleNames(), INSTALL_STATUS_SUCCESS); break; case SplitInstallSessionStatus.CANCELED: case SplitInstallSessionStatus.FAILED: Log.e(TAG, "Failed to install modules '%s': error code %s", state.moduleNames(), state.status()); - onFinished(false, state.moduleNames()); + int status = state.status() == SplitInstallSessionStatus.CANCELED + ? INSTALL_STATUS_CANCELLATION + : INSTALL_STATUS_FAILURE; + finish(false, state.moduleNames(), status); break; } } + + private void finish(boolean success, List<String> moduleNames, int eventId) { + for (String name : moduleNames) { + RecordHistogram.recordEnumeratedHistogram( + "Android.FeatureModules.InstallStatus." + name, eventId, INSTALL_STATUS_COUNT); + + assert mInstallStartTimeMap.containsKey(name); + if (success) { + Pair<Long, Boolean> moduleInfo = mInstallStartTimeMap.get(name); + long installDurationMs = System.currentTimeMillis() - moduleInfo.first; + String histogramSubname = + moduleInfo.second ? "CachedInstallDuration" : "UncachedInstallDuration"; + RecordHistogram.recordLongTimesHistogram( + "Android.FeatureModules." + histogramSubname + "." + name, + installDurationMs, TimeUnit.MILLISECONDS); + } + } + onFinished(success, moduleNames); + } } diff --git a/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java b/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java index 34af27fd291..65ee45b16b6 100644 --- a/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java +++ b/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java @@ -4,16 +4,26 @@ package org.chromium.components.module_installer; +import org.chromium.base.VisibleForTesting; + /** Dummy fallback of ModuleInstaller for APK builds. */ public class ModuleInstaller { public static void init() {} public static void updateCrashKeys(){}; - /** Should never be called for APK builds. */ public static void install( String moduleName, OnModuleInstallFinishedListener onFinishedListener) { throw new UnsupportedOperationException("Cannot install module if APK"); } + public static void installDeferred(String moduleName) { + throw new UnsupportedOperationException("Cannot deferred install module if APK"); + } + + @VisibleForTesting + public static boolean didRequestDeferred(String moduleName) { + throw new UnsupportedOperationException(); + } + private ModuleInstaller() {} } diff --git a/chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java b/chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java new file mode 100644 index 00000000000..9df2a242004 --- /dev/null +++ b/chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java @@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.module_installer; + +import org.chromium.base.VisibleForTesting; + +import java.util.HashSet; +import java.util.Set; + +/** Mock ModuleInstaller for use in tests. */ +public class ModuleInstaller { + private static Set<String> sModulesRequestedDeffered = new HashSet<>(); + + public static void init() {} + public static void updateCrashKeys(){}; + + public static void install( + String moduleName, OnModuleInstallFinishedListener onFinishedListener) {} + + public static void installDeferred(String moduleName) { + sModulesRequestedDeffered.add(moduleName); + } + + @VisibleForTesting + public static boolean didRequestDeferred(String moduleName) { + return sModulesRequestedDeffered.contains(moduleName); + } + + private ModuleInstaller() {} +} |