Chromium Code Reviews| Index: chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceConnectionManager.java |
| diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceConnectionManager.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceConnectionManager.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..853490d8b0868c9ad7d05a1802b5ed02ff4e81d9 |
| --- /dev/null |
| +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceConnectionManager.java |
| @@ -0,0 +1,168 @@ |
| +// 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.ComponentName; |
| +import android.content.Context; |
| +import android.content.Intent; |
| +import android.content.ServiceConnection; |
| +import android.os.AsyncTask; |
| +import android.os.IBinder; |
| +import android.util.Log; |
| + |
| +import org.chromium.webapk.lib.common.IdentityService.IIdentityService; |
| + |
| +import java.util.ArrayList; |
| +import java.util.Hashtable; |
| + |
| +/** |
| + * Manages static global connections between the Chrome application and "WebAPK Identity services". |
| + * Each WebAPK has its own "WebAPK Identity Service". |
| + */ |
| +public class WebApkIdentityServiceConnectionManager { |
|
Yaron
2017/07/10 18:09:07
shoudl we just merge this into WebApkServiceConnec
Xi Han
2017/07/12 13:49:14
I would make WebApkServiceConnectionManager be a b
|
| + /** |
| + * Interface for getting notified once Chrome is connected to the WebAPK Identity Service. |
| + */ |
| + public interface ConnectionCallback { |
| + /** |
| + * Called once Chrome is connected to the WebAPK Identity Service. |
| + * @param service The WebAPK Identity Service. |
| + */ |
| + void onConnected(IIdentityService service); |
| + } |
| + |
| + /** The status of a connection. */ |
| + public enum ConnectionState { WAITINT_FOR_CONNECTION, CONNECTED, DISCONNECTED } |
| + |
| + /** Managed connection to WebAPK Identity service. */ |
| + private static class Connection implements ServiceConnection { |
| + private WebApkIdentityServiceConnectionManager mConnectionManager; |
| + |
| + /** The state of the connection. */ |
| + private ConnectionState mState; |
| + |
| + /** Callbacks to call once the connection is established. */ |
| + private ArrayList<ConnectionCallback> mCallbacks = new ArrayList<ConnectionCallback>(); |
| + |
| + /** WebAPK IBinder interface.*/ |
| + private IIdentityService mIdentityService; |
| + |
| + public ConnectionState getConnectionState() { |
| + return mState; |
| + } |
| + |
| + public IIdentityService getService() { |
| + return mIdentityService; |
| + } |
| + |
| + public void addCallback(ConnectionCallback callback) { |
| + mCallbacks.add(callback); |
| + } |
| + |
| + public Connection(WebApkIdentityServiceConnectionManager manager) { |
| + mConnectionManager = manager; |
| + mState = ConnectionState.WAITINT_FOR_CONNECTION; |
| + } |
| + |
| + @Override |
| + public void onServiceDisconnected(ComponentName name) { |
| + mState = ConnectionState.DISCONNECTED; |
| + mIdentityService = null; |
| + notifyAndClear(); |
|
pkotwicz
2017/07/10 19:06:06
I don't think that onServiceDisconnected() will be
Xi Han
2017/07/12 13:49:14
The goal here is to remove the "unconnected" conne
|
| + mConnectionManager.mConnections.remove(name.getPackageName()); |
|
pkotwicz
2017/07/10 19:06:05
Can we get rid of the ConnectionState.DISCONNECTED
Xi Han
2017/07/12 13:49:14
Done.
|
| + } |
| + |
| + @Override |
| + public void onServiceConnected(ComponentName name, IBinder service) { |
| + mState = ConnectionState.CONNECTED; |
| + mIdentityService = IIdentityService.Stub.asInterface(service); |
| + Log.d(TAG, String.format("Got IIdentityService: %s", mIdentityService)); |
| + notifyAndClear(); |
| + } |
| + |
| + /** Notifies all the callers either the connection is established or failed to connect. */ |
| + private void notifyAndClear() { |
| + if (mCallbacks.isEmpty()) return; |
|
pkotwicz
2017/07/10 19:06:06
Nit: The early return is unnecessary given the cur
Xi Han
2017/07/12 13:49:14
Removed.
|
| + |
| + for (ConnectionCallback callback : mCallbacks) { |
| + callback.onConnected(mIdentityService); |
| + } |
| + mCallbacks.clear(); |
| + } |
| + } |
| + |
| + private static final String CATEGORY_WEBAPK_IDENTITY_SERVICE = |
| + "android.intent.category.WEBAPK_IDENTITY_SERVICE_API"; |
| + private static final String TAG = "cr_WebApk"; |
|
Yaron
2017/07/10 18:09:07
different tag
Xi Han
2017/07/12 13:49:14
Done.
|
| + |
| + private static WebApkIdentityServiceConnectionManager sInstance; |
| + |
| + /** Mapping of WebAPK package to WebAPK Identity Service connection.*/ |
| + private Hashtable<String, Connection> mConnections = new Hashtable<String, Connection>(); |
| + |
| + public static WebApkIdentityServiceConnectionManager getInstance() { |
| + if (sInstance == null) { |
| + sInstance = new WebApkIdentityServiceConnectionManager(); |
| + } |
| + return sInstance; |
| + } |
| + |
| + /** |
| + * Connects Chrome application to WebAPK Identity Service. Can be called from any thread. |
| + * @param appContext Application context. |
| + * @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 Context appContext, final String webApkPackage, |
| + final ConnectionCallback callback) { |
|
pkotwicz
2017/07/10 19:06:06
The WebApkIdentityService currently only has a sin
Xi Han
2017/07/12 13:49:14
Sounds good! Update the callback, and move the log
|
| + Connection connection = mConnections.get(webApkPackage); |
| + if (connection != null) { |
| + switch (connection.getConnectionState()) { |
| + case WAITINT_FOR_CONNECTION: |
| + connection.addCallback(callback); |
| + return; |
| + case CONNECTED: |
| + callback.onConnected(connection.getService()); |
| + return; |
| + default: |
| + break; |
| + } |
| + } |
| + |
| + new AsyncTask<Void, Void, Void>() { |
| + @Override |
| + protected Void doInBackground(Void... params) { |
| + Connection newConnection = |
| + new Connection(WebApkIdentityServiceConnectionManager.this); |
| + newConnection.addCallback(callback); |
| + mConnections.put(webApkPackage, newConnection); |
| + 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; |
| + } |
| + |
| + return null; |
| + } |
| + } |
| + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
pkotwicz
2017/07/10 19:06:06
Is the whitespace correct?
Xi Han
2017/07/12 13:49:14
"git cl format" is always suggested this. Removed.
|
| + } |
| + |
| + WebApkIdentityServiceConnectionManager() {} |
|
pkotwicz
2017/07/10 19:06:06
Did you mean to make the constructor private?
Xi Han
2017/07/12 13:49:14
Done.
|
| + |
| + /** |
| + * Creates intent to connect to WebAPK Identity 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_IDENTITY_SERVICE); |
| + intent.setPackage(webApkPackage); |
| + return intent; |
| + } |
| +} |