diff options
| author | 2023-09-14 22:22:15 +0000 | |
|---|---|---|
| committer | 2023-09-14 22:22:15 +0000 | |
| commit | 1df8c205c51773b65aee2e75bed003bb4e28ba78 (patch) | |
| tree | c6dfecf3fe46582af8823c6c8756f332aaf072a4 | |
| parent | 9e55b80840eb64712e6f391515bdf37b339a4f10 (diff) | |
| parent | c50d3d6143c9e8d94bc4a96541f0865eb588e8d7 (diff) | |
Merge "Retry bind to SharedConnectivityService for manager created before login." into main
| -rw-r--r-- | core/api/test-current.txt | 1 | ||||
| -rw-r--r-- | wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java | 53 |
2 files changed, 52 insertions, 2 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 642813f36a58..37162f5ad836 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -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); } diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java index d41c0197addc..bc41829f16d2 100644 --- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java +++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java @@ -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) { |