| 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..6e7de61b3e4fb280ce18196c2e9bbaa03962f538
|
| --- /dev/null
|
| +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java
|
| @@ -0,0 +1,116 @@
|
| +// 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.IdentityService.IIdentityService;
|
| +import org.chromium.webapk.lib.common.WebApkMetaDataKeys;
|
| +
|
| +/**
|
| + * Manages static global connections between the Chrome application and "WebAPK Identity Service".
|
| + * Each WebAPK has its own "WebAPK Identity Service".
|
| + */
|
| +public class WebApkIdentityServiceClient extends WebApkServiceConnectionManager {
|
| + /** Used to notified the consumer after checking the WebAPK's runtime host asynchronously. */
|
| + public interface CheckRuntimeHostCallback { void onCheckedRuntimeHost(boolean isValid); }
|
| +
|
| + private static final String CATEGORY_WEBAPK_IDENTITY_SERVICE =
|
| + "org.webapk.IDENTITY_SERVICE_API";
|
| + private static final String TAG = "cr_WebApkIdentityService";
|
| + private static final int SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST = 6;
|
| +
|
| + private static WebApkIdentityServiceClient sInstance;
|
| +
|
| + public static WebApkIdentityServiceClient getInstance() {
|
| + if (sInstance == null) {
|
| + sInstance = new WebApkIdentityServiceClient();
|
| + }
|
| + return sInstance;
|
| + }
|
| +
|
| + private WebApkIdentityServiceClient() {
|
| + super(CATEGORY_WEBAPK_IDENTITY_SERVICE);
|
| + }
|
| +
|
| + /**
|
| + * Checks the runtime host of a WebAPK and notifies the caller. The runtime host could be null
|
| + * if the WebAPK either doesn't have an Identity Service or hasn't bind to any browser yet.
|
| + * @param context The app context.
|
| + * @param webApkPackageName The package name of the WebAPK.
|
| + * @param callback The callback to be called after querying the runtime host is done.
|
| + */
|
| + public static void checkWebApkRuntimeHostAsync(final Context context,
|
| + final String webApkPackageName, final CheckRuntimeHostCallback callback) {
|
| + final String packageName = context.getPackageName();
|
| + WebApkServiceConnectionManager.ConnectionCallback connectionCallback =
|
| + new ConnectionCallback() {
|
| + @Override
|
| + public void onConnected(IBinder service) {
|
| + if (service == null) {
|
| + WebApkIdentityServiceClient.notify(packageName, callback,
|
| + maybeExtractRuntimeHostFromMetaData(
|
| + context, webApkPackageName));
|
| + return;
|
| + }
|
| +
|
| + IIdentityService identityService =
|
| + IIdentityService.Stub.asInterface(service);
|
| + String runtimeHost = null;
|
| + try {
|
| + runtimeHost = identityService.getRuntimeHostBrowserPackageName();
|
| + } catch (RemoteException e) {
|
| + Log.w(TAG, "Failed to get runtime host from the Identity Service.");
|
| + } finally {
|
| + WebApkIdentityServiceClient.notify(packageName, callback, runtimeHost);
|
| + }
|
| + }
|
| + };
|
| + getInstance().connect(context, webApkPackageName, connectionCallback);
|
| + }
|
| +
|
| + /** Notifies the caller whether the runtime host matches the current app. */
|
| + public static void notify(
|
| + String appPackageName, CheckRuntimeHostCallback callback, String runtimeHost) {
|
| + callback.onCheckedRuntimeHost(
|
| + !TextUtils.isEmpty(runtimeHost) && runtimeHost.contentEquals(appPackageName));
|
| + }
|
| +
|
| + /**
|
| + * Only returns the runtime host if
|
| + * - the runtime host specified in the AndroidManifest.xml matches the current app name.
|
| + * AND
|
| + * - The shell Apk version is less than SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST.
|
| + */
|
| + private static String maybeExtractRuntimeHostFromMetaData(
|
| + Context context, String webApkPackageName) {
|
| + Bundle metadata = readMetaData(context, webApkPackageName);
|
| + if (metadata.getInt(WebApkMetaDataKeys.SHELL_APK_VERSION)
|
| + >= SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST) {
|
| + 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;
|
| + }
|
| +}
|
|
|