Commit 8ef0da96 authored by Hazem Ashmawy's avatar Hazem Ashmawy Committed by Commit Bot

Show and hide WebView developer UI launcher icon in runtime

Schedule a low priority (best effort) non-blocking PostTask when chrome
comes to the foreground or when a WebView MonoChrome process is created.
The task is responsible to show a launcher icon to open WebView DevTools
if monochrome is the current selected system webview provider otherwise
it hides the launcher icon.

The component (activity-alias) that shows the icon is disabled by
default and is only added to the manifest in build-time when GN argument
`webview_devui_show_icon=true` which is enabled by default for dev and
canary channels.

icon_webview is added to the activity-alias for monochrome so the
launcher icon for DevTools will be WebView icon not Monochrome. However, the icon the
application switcher will still show monochrome icon.

Bug: 1026062
Bug: 1026060
Test: select monochrome as webview implementation and launch monochrome browser, observe icon appearing
Test: select monochrome as webview implementation and launch webview shell browser, observe icon appearing
Test: select different webview implementation, launch monochrome and observe icon disappearing
Change-Id: I9c05aa9d8bcdddc016a06b62a5e76e2aa20f30a6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2000724
Commit-Queue: Hazem Ashmawy <hazems@chromium.org>
Reviewed-by: default avatarNate Fischer <ntfschr@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#733974}
parent 307c52da
...@@ -127,6 +127,7 @@ android_resources("devui_launcher_icon_resources") { ...@@ -127,6 +127,7 @@ android_resources("devui_launcher_icon_resources") {
android_resources("monochrome_devui_launcher_icon_resources") { android_resources("monochrome_devui_launcher_icon_resources") {
resource_dirs = [] resource_dirs = []
android_manifest = "java/MonochromeDeveloperUiLauncherManifest.xml" android_manifest = "java/MonochromeDeveloperUiLauncherManifest.xml"
deps = [ ":icon_resources" ]
custom_package = "org.chromium.android_webview.devui.icon" custom_package = "org.chromium.android_webview.devui.icon"
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<activity-alias android:name="org.chromium.android_webview.devui.MonochromeLauncherActivity" <activity-alias android:name="org.chromium.android_webview.devui.MonochromeLauncherActivity"
android:targetActivity="org.chromium.android_webview.devui.MainActivity" android:targetActivity="org.chromium.android_webview.devui.MainActivity"
android:label="WebView DevTools" android:label="WebView DevTools"
android:icon="@drawable/icon_webview"
android:exported="true" android:exported="true"
android:enabled="false"> android:enabled="false">
<intent-filter> <intent-filter>
......
...@@ -120,6 +120,18 @@ public final class WebViewPackageHelper { ...@@ -120,6 +120,18 @@ public final class WebViewPackageHelper {
} }
} }
/**
* Check if the given context is a WebView package and if it's currently selected as system's
* WebView implementation.
*
* @param context the {@link Context} to check its package.
*/
public static boolean isCurrentSystemWebViewImplementation(Context context) {
PackageInfo systemWebViewPackage = getCurrentWebViewPackage(context);
if (systemWebViewPackage == null) return false;
return context.getPackageName().equals(systemWebViewPackage.packageName);
}
// Do not instantiate this class. // Do not instantiate this class.
private WebViewPackageHelper() {} private WebViewPackageHelper() {}
} }
...@@ -5,16 +5,21 @@ ...@@ -5,16 +5,21 @@
package org.chromium.android_webview.nonembedded; package org.chromium.android_webview.nonembedded;
import android.app.Application; import android.app.Application;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager;
import org.chromium.android_webview.AwLocaleConfig; import org.chromium.android_webview.AwLocaleConfig;
import org.chromium.android_webview.common.CommandLineUtil; import org.chromium.android_webview.common.CommandLineUtil;
import org.chromium.android_webview.devui.util.WebViewPackageHelper;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.PathUtils; import org.chromium.base.PathUtils;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.task.PostTask;
import org.chromium.base.task.TaskTraits;
import org.chromium.components.embedder_support.application.FontPreloadingWorkaround; import org.chromium.components.embedder_support.application.FontPreloadingWorkaround;
import org.chromium.ui.base.ResourceBundle; import org.chromium.ui.base.ResourceBundle;
...@@ -69,6 +74,40 @@ public class WebViewApkApplication extends Application { ...@@ -69,6 +74,40 @@ public class WebViewApkApplication extends Application {
return ContextUtils.getProcessName().contains(":webview_"); return ContextUtils.getProcessName().contains(":webview_");
} }
/**
* Post a non-blocking, low priority background task that shows a launcher icon for WebView
* DevTools if this Monochrome package is the current selected WebView provider for the system
* otherwise it hides that icon. This works only for Monochrome and shouldn't be used for other
* WebView providers. Other WebView Providers (Standalone and Trichrome) will always have
* launcher icons whether they are the current selected providers or not.
*
* Should be guarded by process type checks and should only be called if it's a webview process
* or a browser process.
*/
public static void postDeveloperUiLauncherIconTask() {
PostTask.postTask(TaskTraits.BEST_EFFORT, () -> {
Context context = ContextUtils.getApplicationContext();
try {
ComponentName devToolsLauncherActivity = new ComponentName(
context, "org.chromium.android_webview.devui.MonochromeLauncherActivity");
if (WebViewPackageHelper.isCurrentSystemWebViewImplementation(context)) {
// Enable the component to show the launcher icon.
context.getPackageManager().setComponentEnabledSetting(devToolsLauncherActivity,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
} else {
// Disable the component to hide the launcher icon.
context.getPackageManager().setComponentEnabledSetting(devToolsLauncherActivity,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
PackageManager.DONT_KILL_APP);
}
} catch (IllegalArgumentException e) {
// If MonochromeLauncherActivity doesn't exist, Dynamically showing/hiding DevTools
// launcher icon is not enabled in this package; e.g when it is a stable channel.
}
});
}
/** /**
* Performs minimal native library initialization required when running as a stand-alone APK. * Performs minimal native library initialization required when running as a stand-alone APK.
* @return True if the library was loaded, false if running as webview stub. * @return True if the library was loaded, false if running as webview stub.
......
...@@ -7,7 +7,8 @@ import("//weblayer/variables.gni") ...@@ -7,7 +7,8 @@ import("//weblayer/variables.gni")
declare_args() { declare_args() {
# Show a launcher icon to open WebView developer UI, enabled by default for dev and canary # Show a launcher icon to open WebView developer UI, enabled by default for dev and canary
# channels. The icon for Monochrome is always hidden by default (https://crbug.com/1026062) # channels. The icon for Monochrome is shown dynamically at runtime if Monochrome is the current
# selected system WebView implementation or hidden otherwise.
# TODO(https://crbug.com/1002589): add beta channel when approved # TODO(https://crbug.com/1002589): add beta channel when approved
webview_devui_show_icon = webview_devui_show_icon =
android_channel == "canary" || android_channel == "dev" android_channel == "canary" || android_channel == "dev"
......
...@@ -180,7 +180,7 @@ public class ChromeApplication extends Application { ...@@ -180,7 +180,7 @@ public class ChromeApplication extends Application {
return FeatureUtilities.isCommandLineOnNonRootedEnabled(); return FeatureUtilities.isCommandLineOnNonRootedEnabled();
} }
private static boolean isBrowserProcess() { protected static boolean isBrowserProcess() {
return !ContextUtils.getProcessName().contains(":"); return !ContextUtils.getProcessName().contains(":");
} }
......
...@@ -9,6 +9,8 @@ import android.content.Context; ...@@ -9,6 +9,8 @@ import android.content.Context;
import com.android.webview.chromium.MonochromeLibraryPreloader; import com.android.webview.chromium.MonochromeLibraryPreloader;
import org.chromium.android_webview.nonembedded.WebViewApkApplication; import org.chromium.android_webview.nonembedded.WebViewApkApplication;
import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.content_public.browser.ChildProcessCreationParams; import org.chromium.content_public.browser.ChildProcessCreationParams;
...@@ -44,6 +46,31 @@ public class MonochromeApplication extends ChromeApplication { ...@@ -44,6 +46,31 @@ public class MonochromeApplication extends ChromeApplication {
LibraryProcessType.PROCESS_CHILD, bindToCaller, ignoreVisibilityForImportance); LibraryProcessType.PROCESS_CHILD, bindToCaller, ignoreVisibilityForImportance);
} }
@Override
public void onCreate() {
super.onCreate();
// TODO(https://crbug.com/1002589): remove beta channel check when approved
if (!ChromeVersionInfo.isStableBuild() && !ChromeVersionInfo.isBetaBuild()) {
// Performing Monochrome WebView DevTools Launcher icon showing/hiding logic in onCreate
// rather than in attachBaseContext() because it depends on application context being
// initiatied.
if (isWebViewProcess()) {
// Whenever a monochrome webview process is launched (WebView service or developer
// UI), post a background task to show/hide the DevTools icon.
WebViewApkApplication.postDeveloperUiLauncherIconTask();
} else if (isBrowserProcess()) {
// Frequently check current system webview provider and show/hide the icon
// accordingly by listening to Monochrome browser Activities status (whenever a
// browser activity comes to the foreground).
ApplicationStatus.registerStateListenerForAllActivities((activity, state) -> {
if (state == ActivityState.RESUMED) {
WebViewApkApplication.postDeveloperUiLauncherIconTask();
}
});
}
}
}
@Override @Override
protected boolean isWebViewProcess() { protected boolean isWebViewProcess() {
return WebViewApkApplication.isWebViewProcess(); return WebViewApkApplication.isWebViewProcess();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment