Loading core/api/system-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -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>); Loading @@ -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); } core/api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityClientCallback.java +19 −0 Original line number Diff line number Diff line Loading @@ -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); } wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java +114 −21 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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}. Loading Loading @@ -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); } } /** Loading @@ -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); } /** Loading @@ -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; Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java +179 −48 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/api/system-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -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>); Loading @@ -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); }
core/api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading
wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityClientCallback.java +19 −0 Original line number Diff line number Diff line Loading @@ -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); }
wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java +114 −21 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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}. Loading Loading @@ -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); } } /** Loading @@ -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); } /** Loading @@ -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; Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading
wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java +179 −48 File changed.Preview size limit exceeded, changes collapsed. Show changes