Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53de211e authored by Isaac Katzenelson's avatar Isaac Katzenelson Committed by Android (Google) Code Review
Browse files

Merge "Notify client via callback when service is connected."

parents 58389631 6e8fc027
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -10045,6 +10045,9 @@ package android.net.wifi.sharedconnectivity.app {
  public interface SharedConnectivityClientCallback {
    method public void onKnownNetworkConnectionStatusChanged(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus);
    method public void onKnownNetworksUpdated(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.KnownNetwork>);
    method public void onRegisterCallbackFailed(@NonNull Exception);
    method public void onServiceConnected();
    method public void onServiceDisconnected();
    method public void onSharedConnectivitySettingsChanged(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState);
    method public void onTetherNetworkConnectionStatusChanged(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus);
    method public void onTetherNetworksUpdated(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.TetherNetwork>);
@@ -10055,7 +10058,7 @@ package android.net.wifi.sharedconnectivity.app {
    method public boolean connectTetherNetwork(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetwork);
    method public boolean disconnectTetherNetwork();
    method public boolean forgetKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
    method public boolean registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback);
    method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback);
    method public boolean unregisterCallback(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback);
  }
+1 −0
Original line number Diff line number Diff line
@@ -1949,6 +1949,7 @@ package android.net {
package android.net.wifi.sharedconnectivity.app {

  public class SharedConnectivityManager {
    method @Nullable public android.content.ServiceConnection getServiceConnection();
    method public void setService(@Nullable android.os.IInterface);
  }

+19 −0
Original line number Diff line number Diff line
@@ -64,5 +64,24 @@ public interface SharedConnectivityClientCallback {
     * @param status The new status.
     */
    void onKnownNetworkConnectionStatusChanged(@NonNull KnownNetworkConnectionStatus status);

    /**
     * This method is being called when the service is ready to be used.
     */
    void onServiceConnected();

    /**
     * This method is being called when the service is no longer available.
     */
    void onServiceDisconnected();

    /**
     * This method is called when the registration of the callback with the shared connectivity
     * service failed.
     *
     * @param exception The exception received from the system when trying to connect to the
     *                  service.
     */
    void onRegisterCallbackFailed(@NonNull Exception exception);
}
+114 −21
Original line number Diff line number Diff line
@@ -47,6 +47,12 @@ import java.util.concurrent.Executor;
 * This class is the library used by consumers of Shared Connectivity data to bind to the service,
 * receive callbacks from, and send user actions to the service.
 *
 * The methods {@link #connectTetherNetwork}, {@link #disconnectTetherNetwork},
 * {@link #connectKnownNetwork} and {@link #forgetKnownNetwork} are not valid and will return false
 * if not called between {@link SharedConnectivityClientCallback#onServiceConnected()}
 * and {@link SharedConnectivityClientCallback#onServiceDisconnected()} or if
 * {@link SharedConnectivityClientCallback#onRegisterCallbackFailed} was called.
 *
 * @hide
 */
@SystemApi
@@ -135,6 +141,10 @@ public class SharedConnectivityManager {
    private ISharedConnectivityService mService;
    private final Map<SharedConnectivityClientCallback, SharedConnectivityCallbackProxy>
            mProxyMap = new HashMap<>();
    private final Map<SharedConnectivityClientCallback, SharedConnectivityCallbackProxy>
            mCallbackProxyCache = new HashMap<>();
    // Used for testing
    private final ServiceConnection mServiceConnection;

    /**
     * Creates a new instance of {@link SharedConnectivityManager}.
@@ -164,23 +174,58 @@ public class SharedConnectivityManager {

    private SharedConnectivityManager(@NonNull Context context, String servicePackageName,
            String serviceIntentAction) {
        ServiceConnection serviceConnection = new ServiceConnection() {
        mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mService = ISharedConnectivityService.Stub.asInterface(service);
                if (!mCallbackProxyCache.isEmpty()) {
                    synchronized (mCallbackProxyCache) {
                        mCallbackProxyCache.keySet().forEach(callback -> {
                            registerCallbackInternal(callback, mCallbackProxyCache.get(callback));
                        });
                        mCallbackProxyCache.clear();
                    }
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                if (DEBUG) Log.i(TAG, "onServiceDisconnected");
                mService = null;
                if (!mCallbackProxyCache.isEmpty()) {
                    synchronized (mCallbackProxyCache) {
                        mCallbackProxyCache.keySet().forEach(
                                SharedConnectivityClientCallback::onServiceDisconnected);
                        mCallbackProxyCache.clear();
                    }
                }
                if (!mProxyMap.isEmpty()) {
                    synchronized (mProxyMap) {
                        mProxyMap.keySet().forEach(
                                SharedConnectivityClientCallback::onServiceDisconnected);
                        mProxyMap.clear();
                    }
                }
            }
        };

        context.bindService(
                new Intent().setPackage(servicePackageName).setAction(serviceIntentAction),
                serviceConnection, Context.BIND_AUTO_CREATE);
                mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    private void registerCallbackInternal(SharedConnectivityClientCallback callback,
            SharedConnectivityCallbackProxy proxy) {
        try {
            mService.registerCallback(proxy);
            synchronized (mProxyMap) {
                mProxyMap.put(callback, proxy);
            }
            callback.onServiceConnected();
        } catch (RemoteException e) {
            Log.e(TAG, "Exception in registerCallback", e);
            callback.onRegisterCallbackFailed(e);
        }
    }

    /**
@@ -191,30 +236,46 @@ public class SharedConnectivityManager {
        mService = (ISharedConnectivityService) service;
    }

    /**
     * @hide
     */
    @TestApi
    @Nullable
    public ServiceConnection getServiceConnection() {
        return mServiceConnection;
    }

    /**
     * Registers a callback for receiving updates to the list of Tether Networks and Known Networks.
     * The {@link SharedConnectivityClientCallback#onRegisterCallbackFailed} will be called if the
     * registration failed.
     *
     * @param executor The Executor used to invoke the callback.
     * @param callback The callback of type {@link SharedConnectivityClientCallback} that is invoked
     *                 when the service updates either the list of Tether Networks or Known
     *                 Networks.
     * @return Returns true if the registration was successful, false otherwise.
     */
    public boolean registerCallback(@NonNull @CallbackExecutor Executor executor,
    public void registerCallback(@NonNull @CallbackExecutor Executor executor,
            @NonNull SharedConnectivityClientCallback callback) {
        Objects.requireNonNull(executor, "executor cannot be null");
        Objects.requireNonNull(callback, "callback cannot be null");
        if (mService == null || mProxyMap.containsKey(callback)) return false;
        try {

        if (mProxyMap.containsKey(callback) || mCallbackProxyCache.containsKey(callback)) {
            Log.e(TAG, "Callback already registered");
            callback.onRegisterCallbackFailed(new IllegalStateException(
                    "Callback already registered"));
            return;
        }

        SharedConnectivityCallbackProxy proxy =
                new SharedConnectivityCallbackProxy(executor, callback);
            mService.registerCallback(proxy);
            mProxyMap.put(callback, proxy);
        } catch (RemoteException e) {
            Log.e(TAG, "Exception in registerCallback", e);
            return false;
        if (mService == null) {
            synchronized (mCallbackProxyCache) {
                mCallbackProxyCache.put(callback, proxy);
            }
        return true;
            return;
        }
        registerCallbackInternal(callback, proxy);
    }

    /**
@@ -225,10 +286,24 @@ public class SharedConnectivityManager {
    public boolean unregisterCallback(
            @NonNull SharedConnectivityClientCallback callback) {
        Objects.requireNonNull(callback, "callback cannot be null");
        if (mService == null || !mProxyMap.containsKey(callback)) return false;

        if (!mProxyMap.containsKey(callback) && !mCallbackProxyCache.containsKey(callback)) {
            Log.e(TAG, "Callback not found, cannot unregister");
            return false;
        }

        if (mService == null) {
            synchronized (mCallbackProxyCache) {
                mCallbackProxyCache.remove(callback);
            }
            return true;
        }

        try {
            mService.unregisterCallback(mProxyMap.get(callback));
            synchronized (mProxyMap) {
                mProxyMap.remove(callback);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Exception in unregisterCallback", e);
            return false;
@@ -246,7 +321,12 @@ public class SharedConnectivityManager {
     *         connection was successful.
     */
    public boolean connectTetherNetwork(@NonNull TetherNetwork network) {
        if (mService == null) return false;
        Objects.requireNonNull(network, "Tether network cannot be null");

        if (mService == null) {
            return false;
        }

        try {
            mService.connectTetherNetwork(network);
        } catch (RemoteException e) {
@@ -264,7 +344,10 @@ public class SharedConnectivityManager {
     *         disconnection was successful.
     */
    public boolean disconnectTetherNetwork() {
        if (mService == null) return false;
        if (mService == null) {
            return false;
        }

        try {
            mService.disconnectTetherNetwork();
        } catch (RemoteException e) {
@@ -284,7 +367,12 @@ public class SharedConnectivityManager {
     *         connection was successful.
     */
    public boolean connectKnownNetwork(@NonNull KnownNetwork network) {
        if (mService == null) return false;
        Objects.requireNonNull(network, "Known network cannot be null");

        if (mService == null) {
            return false;
        }

        try {
            mService.connectKnownNetwork(network);
        } catch (RemoteException e) {
@@ -302,7 +390,12 @@ public class SharedConnectivityManager {
     *         forget action was successful.
     */
    public boolean forgetKnownNetwork(@NonNull KnownNetwork network) {
        if (mService == null) return false;
        Objects.requireNonNull(network, "Known network cannot be null");

        if (mService == null) {
            return false;
        }

        try {
            mService.forgetKnownNetwork(network);
        } catch (RemoteException e) {
+179 −48

File changed.

Preview size limit exceeded, changes collapsed.