Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3697)

Unified Diff: chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java

Issue 2974573002: Refactor WebApkServiceConnectionManager. (Closed)
Patch Set: yfriedman@'s comments. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b1d2026e1df446a2794e836b2ee4bd34c4cb983
--- /dev/null
+++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java
@@ -0,0 +1,148 @@
+// Copyright 2017 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.webapk.lib.client;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.chromium.webapk.lib.common.WebApkMetaDataKeys;
+import org.chromium.webapk.lib.common.identity_service.IIdentityService;
+
+/**
+ * Provides APIs for browsers to communicate with WebAPK Identity services. Each WebAPK has its own
+ * "WebAPK Identity service".
+ */
+public class WebApkIdentityServiceClient {
+ /** Used to notify the consumer after checking whether the caller browser backs the WebAPK. */
+ public interface CheckBrowserBacksWebApkCallback {
+ void onChecked(boolean doesBrowserBackWebApk);
+ }
+
+ /**
+ * Before shell APK version 6, all WebAPKs are installed from browsers, and that browser is the
+ * runtime host and specified in the WebAPK's AndroidManifest.xml. In shell APK version 6, we
+ * introduced logic to allow user to choose runtime host browser for WebAPKs not bound to any
+ * browser, and for WebAPKs installed from browsers when the browser is subsequently
+ * uninstalled. However, the browser cannot track of WebAPKs which are backed by the browser
+ * because the browser is not notified if a user changes the runtime host of a WebAPK by
+ * clearing the WebAPK's data. Besides, the browser loses the knowledge of WebAPKs if a user
+ * clears the browser's data. Therefore, a browser doesn't know whether it is the runtime host
+ * of a WebAPK without asking the WebAPK. An Identity service is introduced in shell APK version
+ * 16 to allow browsers to query the runtime host of a WebAPK.
+ */
+ public static final int SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST = 6;
+
+ private static final String ACTION_WEBAPK_IDENTITY_SERVICE = "org.webapk.IDENTITY_SERVICE_API";
+ private static final String TAG = "cr_WebApkIdentityService";
+
+ private static WebApkIdentityServiceClient sInstance;
+
+ /** Manages connections between the browser application and WebAPK Identity services. */
+ private WebApkServiceConnectionManager mConnectionManager;
+
+ public static WebApkIdentityServiceClient getInstance() {
+ if (sInstance == null) {
+ sInstance = new WebApkIdentityServiceClient();
+ }
+ return sInstance;
+ }
+
+ private WebApkIdentityServiceClient() {
+ mConnectionManager = new WebApkServiceConnectionManager(
+ null /* category */, ACTION_WEBAPK_IDENTITY_SERVICE);
+ }
+
+ /**
+ * Checks whether a WebAPK is backed by the browser with {@link browserContext}.
+ * @param browserContext The browser context.
+ * @param webApkPackageName The package name of the WebAPK.
+ * @param callback The callback to be called after querying the runtime host is done.
+ */
+ public void checkBrowserBacksWebApkAsync(final Context browserContext,
+ final String webApkPackageName, final CheckBrowserBacksWebApkCallback callback) {
+ WebApkServiceConnectionManager.ConnectionCallback connectionCallback =
+ new WebApkServiceConnectionManager.ConnectionCallback() {
+ @Override
+ public void onConnected(IBinder service) {
+ String browserPackageName = browserContext.getPackageName();
+ if (service == null) {
+ onGotWebApkRuntimeHost(browserPackageName,
+ maybeExtractRuntimeHostFromMetaData(
+ browserContext, webApkPackageName),
+ callback);
+ return;
+ }
+
+ IIdentityService identityService =
+ IIdentityService.Stub.asInterface(service);
+ String runtimeHost = null;
+ try {
+ // The runtime host could be null if the WebAPK hasn't bound to any
+ // browser yet.
+ runtimeHost = identityService.getRuntimeHostBrowserPackageName();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to get runtime host from the Identity service.");
+ }
+ onGotWebApkRuntimeHost(browserPackageName, runtimeHost, callback);
+ }
+ };
+ mConnectionManager.connect(browserContext, webApkPackageName, connectionCallback);
+ }
+
+ /**
+ * Called after fetching the WebAPK's backing browser.
+ * @param browserPackageName The browser's package name.
+ * @param webApkBackingBrowserPackageName The package name of the WebAPK's backing browser.
+ * @param callback The callback to notify whether {@link browserPackageName} backs the WebAPK.
+ */
+ private static void onGotWebApkRuntimeHost(String browserPackageName,
+ String webApkBackingBrowserPackageName, CheckBrowserBacksWebApkCallback callback) {
+ callback.onChecked(TextUtils.equals(webApkBackingBrowserPackageName, browserPackageName));
+ }
+
+ /**
+ * Extracts the backing browser from the WebAPK's meta data.
+ * See {@link WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST} for
+ * more details.
+ */
+ private static String maybeExtractRuntimeHostFromMetaData(
+ Context context, String webApkPackageName) {
+ Bundle metadata = readMetaData(context, webApkPackageName);
+ if (metadata == null
+ || metadata.getInt(WebApkMetaDataKeys.SHELL_APK_VERSION)
+ >= SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST) {
+ // The backing browser in the WebAPK's meta data may not be the one which actually backs
+ // the WebAPK. The user may have switched the backing browser.
+ return null;
+ }
+
+ return metadata.getString(WebApkMetaDataKeys.RUNTIME_HOST);
+ }
+
+ /** Returns the <meta-data> in the Android Manifest of the given package name. */
+ private static Bundle readMetaData(Context context, String packageName) {
+ ApplicationInfo ai = null;
+ try {
+ ai = context.getPackageManager().getApplicationInfo(
+ packageName, PackageManager.GET_META_DATA);
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+ return ai.metaData;
+ }
+
+ /** Disconnects all the connections to WebAPK Identity services. */
+ public static void disconnectAll(Context appContext) {
+ if (sInstance == null) return;
+
+ sInstance.mConnectionManager.disconnectAll(appContext);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698