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

Commit c50d3d61 authored by Matt Walliser's avatar Matt Walliser
Browse files

Retry bind to SharedConnectivityService for manager created before login.

Bug: 299187614
Fixes: 299187614
Test: atest -c android.net.wifi.sharedconnectivity.cts.app.SharedConnectivityManagerTest
Change-Id: If00d686f8f95433d951f80faafb99d94ee758805
parent 07c97efe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2115,6 +2115,7 @@ package android.net.wifi.sharedconnectivity.app {

  public class SharedConnectivityManager {
    method @Nullable public static android.net.wifi.sharedconnectivity.app.SharedConnectivityManager create(@NonNull android.content.Context, @NonNull String, @NonNull String);
    method @NonNull public android.content.BroadcastReceiver getBroadcastReceiver();
    method @Nullable public android.content.ServiceConnection getServiceConnection();
    method public void setService(@Nullable android.os.IInterface);
  }
+51 −2
Original line number Diff line number Diff line
@@ -23,9 +23,11 @@ import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Resources;
import android.net.wifi.sharedconnectivity.service.ISharedConnectivityCallback;
@@ -35,6 +37,7 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;

@@ -67,7 +70,7 @@ import java.util.concurrent.Executor;
@SystemApi
public class SharedConnectivityManager {
    private static final String TAG = SharedConnectivityManager.class.getSimpleName();
    private static final boolean DEBUG = true;
    private static final boolean DEBUG = false;

    private static final class SharedConnectivityCallbackProxy extends
            ISharedConnectivityCallback.Stub {
@@ -172,6 +175,7 @@ public class SharedConnectivityManager {
    private final String mServicePackageName;
    private final String mIntentAction;
    private ServiceConnection mServiceConnection;
    private UserManager mUserManager;

    /**
     * Creates a new instance of {@link SharedConnectivityManager}.
@@ -217,12 +221,14 @@ public class SharedConnectivityManager {
        mContext = context;
        mServicePackageName = servicePackageName;
        mIntentAction = serviceIntentAction;
        mUserManager = context.getSystemService(UserManager.class);
    }

    private void bind() {
        mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                if (DEBUG) Log.i(TAG, "onServiceConnected");
                mService = ISharedConnectivityService.Stub.asInterface(service);
                synchronized (mProxyDataLock) {
                    if (!mCallbackProxyCache.isEmpty()) {
@@ -253,9 +259,45 @@ public class SharedConnectivityManager {
            }
        };

        mContext.bindService(
        boolean result = mContext.bindService(
                new Intent().setPackage(mServicePackageName).setAction(mIntentAction),
                mServiceConnection, Context.BIND_AUTO_CREATE);
        if (!result) {
            if (DEBUG) Log.i(TAG, "bindService failed");
            mServiceConnection = null;
            if (mUserManager != null && !mUserManager.isUserUnlocked()) {  // In direct boot mode
                IntentFilter intentFilter = new IntentFilter();
                intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
                mContext.registerReceiver(mBroadcastReceiver, intentFilter);
            } else {
                synchronized (mProxyDataLock) {
                    if (!mCallbackProxyCache.isEmpty()) {
                        mCallbackProxyCache.keySet().forEach(
                                callback -> callback.onRegisterCallbackFailed(
                                        new IllegalStateException(
                                                "Failed to bind after user unlock")));
                        mCallbackProxyCache.clear();
                    }
                }
            }
        }
    }

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            context.unregisterReceiver(mBroadcastReceiver);
            bind();
        }
    };

    /**
     * @hide
     */
    @TestApi
    @NonNull
    public BroadcastReceiver getBroadcastReceiver() {
        return mBroadcastReceiver;
    }

    private void registerCallbackInternal(SharedConnectivityClientCallback callback,
@@ -357,6 +399,13 @@ public class SharedConnectivityManager {
            return false;
        }

        // Try to unregister the broadcast receiver to guard against memory leaks.
        try {
            mContext.unregisterReceiver(mBroadcastReceiver);
        } catch (IllegalArgumentException e) {
            // This is fine, it means the receiver was never registered or was already unregistered.
        }

        if (mService == null) {
            boolean shouldUnbind;
            synchronized (mProxyDataLock) {