| Index: chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
|
| diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c6b08f560a099950ae538ffb0792adee58fc9caa
|
| --- /dev/null
|
| +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
|
| @@ -0,0 +1,164 @@
|
| +// Copyright 2016 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.ComponentName;
|
| +import android.content.Context;
|
| +import android.content.Intent;
|
| +import android.content.ServiceConnection;
|
| +import android.os.AsyncTask;
|
| +import android.os.IBinder;
|
| +
|
| +import org.chromium.base.Callback;
|
| +import org.chromium.base.ContextUtils;
|
| +import org.chromium.base.Log;
|
| +import org.chromium.webapk.lib.runtime_library.IWebApkApi;
|
| +
|
| +import java.util.ArrayList;
|
| +import java.util.Hashtable;
|
| +
|
| +/**
|
| + * Manages static global connections between the Chrome application and "WebAPK services". Each
|
| + * WebAPK has its own "WebAPK service".
|
| + */
|
| +public class WebApkServiceConnectionManager {
|
| + /**
|
| + * Managed connection to WebAPK service.
|
| + */
|
| + private static class Connection implements ServiceConnection {
|
| + /**
|
| + * Whether the connection to the service was established.
|
| + */
|
| + private boolean mHasConnected;
|
| +
|
| + /**
|
| + * Callbacks to call once the connection is established.
|
| + */
|
| + private ArrayList<Callback<IWebApkApi>> mCallbacks = new ArrayList<Callback<IWebApkApi>>();
|
| +
|
| + /**
|
| + * WebAPK IBinder interface.
|
| + */
|
| + private IWebApkApi mApi;
|
| +
|
| + public boolean hasConnected() {
|
| + return mHasConnected;
|
| + }
|
| +
|
| + public IWebApkApi getApi() {
|
| + return mApi;
|
| + }
|
| +
|
| + public void addCallback(Callback<IWebApkApi> callback) {
|
| + mCallbacks.add(callback);
|
| + }
|
| +
|
| + @Override
|
| + public void onServiceDisconnected(ComponentName name) {}
|
| +
|
| + @Override
|
| + public void onServiceConnected(ComponentName name, IBinder service) {
|
| + mHasConnected = true;
|
| + mApi = IWebApkApi.Stub.asInterface(service);
|
| + Log.d(TAG, "Got IWebApkApi: %s", mApi);
|
| +
|
| + for (Callback<IWebApkApi> callback : mCallbacks) {
|
| + callback.onResult(mApi);
|
| + }
|
| + mCallbacks.clear();
|
| + }
|
| + }
|
| +
|
| + private static final String CATEGORY_WEBAPK_API = "android.intent.category.WEBAPK_API";
|
| +
|
| + private static final String TAG = "cr_WebApk";
|
| +
|
| + private static WebApkServiceConnectionManager sInstance;
|
| +
|
| + /**
|
| + * Mapping of WebAPK package to WebAPK service connection.
|
| + */
|
| + private Hashtable<String, Connection> mConnections = new Hashtable<String, Connection>();
|
| +
|
| + public static WebApkServiceConnectionManager getInstance() {
|
| + if (sInstance == null) {
|
| + sInstance = new WebApkServiceConnectionManager();
|
| + }
|
| + return sInstance;
|
| + }
|
| +
|
| + /**
|
| + * Connects Chrome application to WebAPK service. Can be called from any thread.
|
| + * @param webApkPackage WebAPK package to create connection for.
|
| + * @param callback Callback to call after connection has been established. Called synchronously
|
| + * if the connection is already established.
|
| + */
|
| + public void connect(final String webApkPackage, final Callback<IWebApkApi> callback) {
|
| + Connection connection = mConnections.get(webApkPackage);
|
| + if (connection != null) {
|
| + if (connection.hasConnected()) {
|
| + callback.onResult(connection.getApi());
|
| + } else {
|
| + connection.addCallback(callback);
|
| + }
|
| + return;
|
| + }
|
| +
|
| + new AsyncTask<Void, Void, Void>() {
|
| + @Override
|
| + protected Void doInBackground(Void... params) {
|
| + Connection newConnection = new Connection();
|
| + newConnection.addCallback(callback);
|
| + Context appContext = ContextUtils.getApplicationContext();
|
| + Intent intent = createConnectIntent(webApkPackage);
|
| +
|
| + try {
|
| + appContext.bindService(intent, newConnection, Context.BIND_AUTO_CREATE);
|
| +
|
| + } catch (SecurityException e) {
|
| + Log.w(TAG, "Security failed binding.", e);
|
| + return null;
|
| + }
|
| +
|
| + mConnections.put(webApkPackage, newConnection);
|
| + return null;
|
| + }
|
| + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
| + }
|
| +
|
| + /**
|
| + * Disconnects Chrome application from WebAPK service. Can be called from any thread.
|
| + * @param webApkPackage WebAPK package for the service to disconnect from.
|
| + */
|
| + public void disconnect(String webApkPackage) {
|
| + final Connection connection = mConnections.remove(webApkPackage);
|
| + if (connection == null) {
|
| + return;
|
| + }
|
| +
|
| + new AsyncTask<Void, Void, Void>() {
|
| + @Override
|
| + protected Void doInBackground(Void... params) {
|
| + Context appContext = ContextUtils.getApplicationContext();
|
| + appContext.unbindService(connection);
|
| + return null;
|
| + }
|
| + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
| + }
|
| +
|
| + WebApkServiceConnectionManager() {
|
| + }
|
| +
|
| + /**
|
| + * Creates intent to connect to WebAPK service.
|
| + * @param webApkPackage The package name of the WebAPK to connect to.
|
| + */
|
| + private static Intent createConnectIntent(String webApkPackage) {
|
| + Intent intent = new Intent();
|
| + intent.addCategory(CATEGORY_WEBAPK_API);
|
| + intent.setPackage(webApkPackage);
|
| + return intent;
|
| + }
|
| +}
|
|
|