[Suggestion API] add network callback API
Add new API that allow apps to get connection event. Bug: 142062781 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I387f620901621feb2b15dff7c696d5d3f9a068b9
This commit is contained in:
@@ -30010,6 +30010,7 @@ package android.net.wifi {
|
||||
method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
|
||||
method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
|
||||
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void addScanResultsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsListener);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
|
||||
method public static int calculateSignalLevel(int, int);
|
||||
method @Deprecated public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
|
||||
method public static int compareSignalLevel(int, int);
|
||||
@@ -30046,6 +30047,7 @@ package android.net.wifi {
|
||||
method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
|
||||
method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", "android.permission.NETWORK_CARRIER_PROVISIONING"}) public void removePasspointConfiguration(String);
|
||||
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeScanResultsListener(@NonNull android.net.wifi.WifiManager.ScanResultsListener);
|
||||
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
|
||||
method @Deprecated public boolean saveConfiguration();
|
||||
method public void setTdlsEnabled(java.net.InetAddress, boolean);
|
||||
method public void setTdlsEnabledWithMacAddress(String, boolean);
|
||||
@@ -30079,6 +30081,10 @@ package android.net.wifi {
|
||||
field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
|
||||
field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
|
||||
field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
|
||||
field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
|
||||
field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; // 0x2
|
||||
field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; // 0x3
|
||||
field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0
|
||||
field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
|
||||
field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
|
||||
field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
|
||||
@@ -30125,6 +30131,10 @@ package android.net.wifi {
|
||||
method public void onScanResultsAvailable();
|
||||
}
|
||||
|
||||
public static interface WifiManager.SuggestionConnectionStatusListener {
|
||||
method public void onConnectionStatus(@NonNull android.net.wifi.WifiNetworkSuggestion, int);
|
||||
}
|
||||
|
||||
public class WifiManager.WifiLock {
|
||||
method public void acquire();
|
||||
method public boolean isHeld();
|
||||
|
||||
@@ -534,7 +534,7 @@ MissingNullability: android.icu.util.VersionInfo#UNICODE_12_1:
|
||||
MissingNullability: android.media.MediaMetadataRetriever#getFrameAtTime(long, int, android.media.MediaMetadataRetriever.BitmapParams):
|
||||
|
||||
MissingNullability: android.media.MediaMetadataRetriever#getScaledFrameAtTime(long, int, int, int, android.media.MediaMetadataRetriever.BitmapParams):
|
||||
|
||||
|
||||
|
||||
|
||||
RequiresPermission: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler):
|
||||
@@ -1160,7 +1160,7 @@ SamShouldBeLast: android.location.LocationManager#registerGnssStatusCallback(jav
|
||||
SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, java.util.concurrent.Executor, android.location.LocationListener):
|
||||
|
||||
SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, java.util.concurrent.Executor, android.location.LocationListener):
|
||||
|
||||
|
||||
|
||||
|
||||
StreamFiles: android.content.res.loader.DirectoryResourceLoader#DirectoryResourceLoader(java.io.File):
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.wifi;
|
||||
|
||||
import android.net.wifi.WifiNetworkSuggestion;
|
||||
|
||||
/**
|
||||
* Interface for suggestion network connection listener.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
oneway interface ISuggestionConnectionStatusListener
|
||||
{
|
||||
void onConnectionStatus(in WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason);
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import android.net.wifi.ILocalOnlyHotspotCallback;
|
||||
import android.net.wifi.INetworkRequestMatchCallback;
|
||||
import android.net.wifi.IScanResultsListener;
|
||||
import android.net.wifi.ISoftApCallback;
|
||||
import android.net.wifi.ISuggestionConnectionStatusListener;
|
||||
import android.net.wifi.ITrafficStateCallback;
|
||||
import android.net.wifi.ITxPacketCountListener;
|
||||
import android.net.wifi.IOnWifiUsabilityStatsListener;
|
||||
@@ -236,4 +237,8 @@ interface IWifiManager
|
||||
void registerScanResultsListener(in IBinder binder, in IScanResultsListener Listener, int listenerIdentifier);
|
||||
|
||||
void unregisterScanResultsListener(int listenerIdentifier);
|
||||
|
||||
void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName);
|
||||
|
||||
void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName);
|
||||
}
|
||||
|
||||
@@ -207,6 +207,33 @@ public class WifiManager {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface NetworkSuggestionsStatusCode {}
|
||||
|
||||
/**
|
||||
* Reason code if suggested network connection attempt failed with an unknown failure.
|
||||
*/
|
||||
public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0;
|
||||
/**
|
||||
* Reason code if suggested network connection attempt failed with association failure.
|
||||
*/
|
||||
public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1;
|
||||
/**
|
||||
* Reason code if suggested network connection attempt failed with an authentication failure.
|
||||
*/
|
||||
public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2;
|
||||
/**
|
||||
* Reason code if suggested network connection attempt failed with an IP provision failure.
|
||||
*/
|
||||
public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"},
|
||||
value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN,
|
||||
STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION,
|
||||
STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION,
|
||||
STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface SuggestionConnectionStatusCode {}
|
||||
|
||||
/**
|
||||
* Broadcast intent action indicating whether Wi-Fi scanning is allowed currently
|
||||
* @hide
|
||||
@@ -5229,7 +5256,7 @@ public class WifiManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for scan results listener. Should be implemented by applications and set when
|
||||
* Interface for scan results listener. Should be implemented by applications and set when
|
||||
* calling {@link WifiManager#addScanResultsListener(Executor, ScanResultsListener)}.
|
||||
*/
|
||||
public interface ScanResultsListener {
|
||||
@@ -5315,4 +5342,108 @@ public class WifiManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for suggestion connection status listener.
|
||||
* Should be implemented by applications and set when calling
|
||||
* {@link WifiManager#addSuggestionConnectionStatusListener(
|
||||
* Executor, SuggestionConnectionStatusListener)}.
|
||||
*/
|
||||
public interface SuggestionConnectionStatusListener {
|
||||
|
||||
/**
|
||||
* Called when the framework attempted to connect to a suggestion provided by the
|
||||
* registering app, but the connection to the suggestion failed.
|
||||
* @param wifiNetworkSuggestion The suggestion which failed to connect.
|
||||
* @param failureReason the connection failure reason code. One of
|
||||
* {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION},
|
||||
* {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION},
|
||||
* {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING}
|
||||
* {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN}
|
||||
*/
|
||||
void onConnectionStatus(
|
||||
@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
|
||||
@SuggestionConnectionStatusCode int failureReason);
|
||||
}
|
||||
|
||||
private class SuggestionConnectionStatusListenerProxy extends
|
||||
ISuggestionConnectionStatusListener.Stub {
|
||||
private final Executor mExecutor;
|
||||
private final SuggestionConnectionStatusListener mListener;
|
||||
|
||||
SuggestionConnectionStatusListenerProxy(@NonNull Executor executor,
|
||||
@NonNull SuggestionConnectionStatusListener listener) {
|
||||
mExecutor = executor;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
|
||||
int failureReason) {
|
||||
mExecutor.execute(() ->
|
||||
mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}.
|
||||
* Caller will receive the event when suggested network have connection failure.
|
||||
* Caller can remove a previously registered listener using
|
||||
* {@link WifiManager#removeSuggestionConnectionStatusListener(
|
||||
* SuggestionConnectionStatusListener)}
|
||||
* Same caller can add multiple listeners to monitor the event.
|
||||
* <p>
|
||||
* Applications should have the
|
||||
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
|
||||
* {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions.
|
||||
* Callers without the permission will trigger a {@link java.lang.SecurityException}.
|
||||
* <p>
|
||||
*
|
||||
* @param executor The executor to execute the listener of the {@code listener} object.
|
||||
* @param listener listener for suggestion network connection failure.
|
||||
*/
|
||||
@RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
|
||||
public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull SuggestionConnectionStatusListener listener) {
|
||||
if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
|
||||
if (executor == null) throw new IllegalArgumentException("Executor cannot be null");
|
||||
Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener
|
||||
+ ", executor=" + executor);
|
||||
try {
|
||||
IWifiManager iWifiManager = getIWifiManager();
|
||||
if (iWifiManager == null) {
|
||||
throw new RemoteException("Wifi service is not running");
|
||||
}
|
||||
iWifiManager.registerSuggestionConnectionStatusListener(new Binder(),
|
||||
new SuggestionConnectionStatusListenerProxy(executor, listener),
|
||||
listener.hashCode(), mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow callers to remove a previously registered listener. After calling this method,
|
||||
* applications will no longer receive suggestion connection events through that listener.
|
||||
*
|
||||
* @param listener listener to remove.
|
||||
*/
|
||||
@RequiresPermission(ACCESS_WIFI_STATE)
|
||||
public void removeSuggestionConnectionStatusListener(
|
||||
@NonNull SuggestionConnectionStatusListener listener) {
|
||||
if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
|
||||
Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener);
|
||||
try {
|
||||
IWifiManager iWifiManager = getIWifiManager();
|
||||
if (iWifiManager == null) {
|
||||
throw new RemoteException("Wifi service is not running");
|
||||
}
|
||||
iWifiManager.unregisterSuggestionConnectionStatusListener(listener.hashCode(),
|
||||
mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.net.wifi.INetworkRequestMatchCallback;
|
||||
import android.net.wifi.IOnWifiUsabilityStatsListener;
|
||||
import android.net.wifi.IScanResultsListener;
|
||||
import android.net.wifi.ISoftApCallback;
|
||||
import android.net.wifi.ISuggestionConnectionStatusListener;
|
||||
import android.net.wifi.ITrafficStateCallback;
|
||||
import android.net.wifi.ITxPacketCountListener;
|
||||
import android.net.wifi.IWifiManager;
|
||||
@@ -540,4 +541,17 @@ public class BaseWifiService extends IWifiManager.Stub {
|
||||
public void unregisterScanResultsListener(int listenerIdentifier) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSuggestionConnectionStatusListener(IBinder binder,
|
||||
ISuggestionConnectionStatusListener listener,
|
||||
int listenerIdentifier, String packageName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterSuggestionConnectionStatusListener(int listenerIdentifier,
|
||||
String packageName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
|
||||
import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener;
|
||||
import android.net.wifi.WifiManager.ScanResultsListener;
|
||||
import android.net.wifi.WifiManager.SoftApCallback;
|
||||
import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
|
||||
import android.net.wifi.WifiManager.TrafficStateCallback;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
@@ -109,12 +110,14 @@ public class WifiManagerTest {
|
||||
@Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
|
||||
@Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
|
||||
@Mock ScanResultsListener mScanResultListener;
|
||||
@Mock SuggestionConnectionStatusListener mListener;
|
||||
@Mock Executor mCallbackExecutor;
|
||||
@Mock Executor mExecutor;
|
||||
|
||||
private Handler mHandler;
|
||||
private TestLooper mLooper;
|
||||
private WifiManager mWifiManager;
|
||||
private WifiNetworkSuggestion mWifiNetworkSuggestion;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -126,6 +129,7 @@ public class WifiManagerTest {
|
||||
when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
|
||||
mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
|
||||
verify(mWifiService).getVerboseLoggingLevel();
|
||||
mWifiNetworkSuggestion = new WifiNetworkSuggestion();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1803,4 +1807,69 @@ public class WifiManagerTest {
|
||||
public void testRemoveScanResultsListenerWithNullListener() throws Exception {
|
||||
mWifiManager.removeScanResultsListener(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an IllegalArgumentException is thrown if executor not provided.
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAddSuggestionConnectionStatusListenerWithNullExecutor() {
|
||||
mWifiManager.addSuggestionConnectionStatusListener(null, mListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an IllegalArgumentException is thrown if listener is not provided.
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAddSuggestionConnectionStatusListenerWithNullListener() {
|
||||
mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify client provided listener is being called to the right listener.
|
||||
*/
|
||||
@Test
|
||||
public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception {
|
||||
int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
|
||||
ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
|
||||
ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
|
||||
Executor executor = new SynchronousExecutor();
|
||||
mWifiManager.addSuggestionConnectionStatusListener(executor, mListener);
|
||||
verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
|
||||
callbackCaptor.capture(), anyInt(), anyString());
|
||||
callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode);
|
||||
verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify client provided listener is being called to the right executor.
|
||||
*/
|
||||
@Test
|
||||
public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception {
|
||||
int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
|
||||
ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
|
||||
ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
|
||||
mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener);
|
||||
verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
|
||||
callbackCaptor.capture(), anyInt(), anyString());
|
||||
callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode);
|
||||
verify(mExecutor).execute(any(Runnable.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an IllegalArgumentException is thrown if listener is not provided.
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testRemoveSuggestionConnectionListenerWithNullListener() {
|
||||
mWifiManager.removeSuggestionConnectionStatusListener(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify removeSuggestionConnectionListener.
|
||||
*/
|
||||
@Test
|
||||
public void testRemoveSuggestionConnectionListener() throws Exception {
|
||||
|
||||
mWifiManager.removeSuggestionConnectionStatusListener(mListener);
|
||||
verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user