Extension API: Create System APIs to allow OEM module to override WiFi
scorer in AOSP Create WiFi scorer interface and score change callback interface in WifiManager; Define register and unregister methods for WiFi scorer. Test: atest android.net.wifi Bug: 135573686, 122133502, 136312816, 135572156 Change-Id: Ib51d877a463d1f69b31b9743917ea1b3590a30f7 Signed-off-by: Mingguang Xu <mingguangxu@google.com>
This commit is contained in:
@@ -6132,6 +6132,7 @@ package android.net.wifi {
|
||||
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
|
||||
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinPasspoint(@NonNull String, boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void clearWifiConnectedNetworkScorer();
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
|
||||
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
|
||||
@@ -6175,6 +6176,7 @@ package android.net.wifi {
|
||||
method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
|
||||
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
|
||||
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
|
||||
@@ -6264,6 +6266,11 @@ package android.net.wifi {
|
||||
method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
|
||||
}
|
||||
|
||||
public static interface WifiManager.ScoreChangeCallback {
|
||||
method public void onStatusChange(int, boolean);
|
||||
method public void onTriggerUpdateOfWifiUsabilityStats(int);
|
||||
}
|
||||
|
||||
public static interface WifiManager.SoftApCallback {
|
||||
method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
|
||||
method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
|
||||
@@ -6280,6 +6287,12 @@ package android.net.wifi {
|
||||
field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
|
||||
}
|
||||
|
||||
public static interface WifiManager.WifiConnectedNetworkScorer {
|
||||
method public void setScoreChangeCallback(@NonNull android.net.wifi.WifiManager.ScoreChangeCallback);
|
||||
method public void start(int);
|
||||
method public void stop(int);
|
||||
}
|
||||
|
||||
public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
|
||||
ctor public WifiNetworkConnectionStatistics(int, int);
|
||||
ctor public WifiNetworkConnectionStatistics();
|
||||
|
||||
29
wifi/java/android/net/wifi/IScoreChangeCallback.aidl
Normal file
29
wifi/java/android/net/wifi/IScoreChangeCallback.aidl
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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;
|
||||
|
||||
/**
|
||||
* Interface for Wi-Fi network score callback.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IScoreChangeCallback
|
||||
{
|
||||
void onStatusChange(int sessionId, boolean exiting);
|
||||
|
||||
void onTriggerUpdateOfWifiUsabilityStats(int sessionId);
|
||||
}
|
||||
33
wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
Normal file
33
wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.IScoreChangeCallback;
|
||||
|
||||
/**
|
||||
* Interface for Wi-Fi connected network scorer.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IWifiConnectedNetworkScorer
|
||||
{
|
||||
void start(int sessionId);
|
||||
|
||||
void stop(int sessionId);
|
||||
|
||||
void setScoreChangeCallback(IScoreChangeCallback cbImpl);
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import android.net.wifi.ISoftApCallback;
|
||||
import android.net.wifi.ISuggestionConnectionStatusListener;
|
||||
import android.net.wifi.ITrafficStateCallback;
|
||||
import android.net.wifi.ITxPacketCountListener;
|
||||
import android.net.wifi.IWifiConnectedNetworkScorer;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.SoftApConfiguration;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
@@ -252,4 +253,8 @@ interface IWifiManager
|
||||
int calculateSignalLevel(int rssi);
|
||||
|
||||
List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List<ScanResult> scanResults);
|
||||
|
||||
boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer);
|
||||
|
||||
void clearWifiConnectedNetworkScorer();
|
||||
}
|
||||
|
||||
@@ -5777,4 +5777,186 @@ public class WifiManager {
|
||||
return new SparseArray<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for framework to receive network status changes and trigger of updating
|
||||
* {@link WifiUsabilityStatsEntry}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public interface ScoreChangeCallback {
|
||||
/**
|
||||
* Called by applications to indicate network status.
|
||||
*
|
||||
* @param sessionId The ID to indicate current Wi-Fi network connection obtained from
|
||||
* {@link WifiConnectedNetworkScorer#start(int)}.
|
||||
* @param isUsable The bit to indicate whether current Wi-Fi network is usable or not.
|
||||
* Populated by connected network scorer in applications.
|
||||
*/
|
||||
void onStatusChange(int sessionId, boolean isUsable);
|
||||
|
||||
/**
|
||||
* Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}.
|
||||
* To receive update applications need to add WifiUsabilityStatsEntry listener. See
|
||||
* {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}.
|
||||
*
|
||||
* @param sessionId The ID to indicate current Wi-Fi network connection obtained from
|
||||
* {@link WifiConnectedNetworkScorer#start(int)}.
|
||||
*/
|
||||
void onTriggerUpdateOfWifiUsabilityStats(int sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback proxy for {@link ScoreChangeCallback} objects.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
private class ScoreChangeCallbackProxy implements ScoreChangeCallback {
|
||||
private final IScoreChangeCallback mScoreChangeCallback;
|
||||
|
||||
private ScoreChangeCallbackProxy(IScoreChangeCallback callback) {
|
||||
mScoreChangeCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChange(int sessionId, boolean isUsable) {
|
||||
try {
|
||||
mScoreChangeCallback.onStatusChange(sessionId, isUsable);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTriggerUpdateOfWifiUsabilityStats(int sessionId) {
|
||||
try {
|
||||
mScoreChangeCallback.onTriggerUpdateOfWifiUsabilityStats(sessionId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for Wi-Fi connected network scorer. Should be implemented by applications and set
|
||||
* when calling
|
||||
* {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public interface WifiConnectedNetworkScorer {
|
||||
/**
|
||||
* Called by framework to indicate the start of a network connection.
|
||||
* @param sessionId The ID to indicate current Wi-Fi network connection.
|
||||
*/
|
||||
void start(int sessionId);
|
||||
|
||||
/**
|
||||
* Called by framework to indicate the end of a network connection.
|
||||
* @param sessionId The ID to indicate current Wi-Fi network connection obtained from
|
||||
* {@link WifiConnectedNetworkScorer#start(int)}.
|
||||
*/
|
||||
void stop(int sessionId);
|
||||
|
||||
/**
|
||||
* Framework sets callback for score change events after application sets its scorer.
|
||||
* @param cbImpl The instance for {@link WifiManager#ScoreChangeCallback}. Should be
|
||||
* implemented and instantiated by framework.
|
||||
*/
|
||||
void setScoreChangeCallback(@NonNull ScoreChangeCallback cbImpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback proxy for {@link WifiConnectedNetworkScorer} objects.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub {
|
||||
private Executor mExecutor;
|
||||
private WifiConnectedNetworkScorer mScorer;
|
||||
|
||||
WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) {
|
||||
mExecutor = executor;
|
||||
mScorer = scorer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(int sessionId) {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "WifiConnectedNetworkScorer: " + "start: sessionId=" + sessionId);
|
||||
}
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mScorer.start(sessionId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(int sessionId) {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "WifiConnectedNetworkScorer: " + "stop: sessionId=" + sessionId);
|
||||
}
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mScorer.stop(sessionId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScoreChangeCallback(IScoreChangeCallback cbImpl) {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "WifiConnectedNetworkScorer: "
|
||||
+ "setScoreChangeCallback: cbImpl=" + cbImpl);
|
||||
}
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mScorer.setScoreChangeCallback(
|
||||
new ScoreChangeCallbackProxy(cbImpl)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback for Wi-Fi connected network scorer. See {@link WifiConnectedNetworkScorer}.
|
||||
* Only a single scorer can be set. Caller will be invoked periodically by framework to inform
|
||||
* client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer
|
||||
* using {@link clearWifiConnectedNetworkScorer()}.
|
||||
*
|
||||
* @param executor The executor on which callback will be invoked.
|
||||
* @param scorer Scorer for Wi-Fi network implemented by application.
|
||||
* @return true Scorer is set successfully.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
|
||||
public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull WifiConnectedNetworkScorer scorer) {
|
||||
if (executor == null) throw new IllegalArgumentException("executor cannot be null");
|
||||
if (scorer == null) throw new IllegalArgumentException("scorer cannot be null");
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer);
|
||||
}
|
||||
try {
|
||||
return mService.setWifiConnectedNetworkScorer(new Binder(),
|
||||
new WifiConnectedNetworkScorerProxy(executor, scorer));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow caller to clear a previously set scorer. After calling this method,
|
||||
* client will no longer receive information about start and stop of Wi-Fi connection.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
|
||||
public void clearWifiConnectedNetworkScorer() {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "clearWifiConnectedNetworkScorer");
|
||||
}
|
||||
try {
|
||||
mService.clearWifiConnectedNetworkScorer();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.net.wifi.ISoftApCallback;
|
||||
import android.net.wifi.ISuggestionConnectionStatusListener;
|
||||
import android.net.wifi.ITrafficStateCallback;
|
||||
import android.net.wifi.ITxPacketCountListener;
|
||||
import android.net.wifi.IWifiConnectedNetworkScorer;
|
||||
import android.net.wifi.IWifiManager;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.SoftApConfiguration;
|
||||
@@ -595,4 +596,15 @@ public class BaseWifiService extends IWifiManager.Stub {
|
||||
List<ScanResult> scanResults) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setWifiConnectedNetworkScorer(IBinder binder,
|
||||
IWifiConnectedNetworkScorer scorer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWifiConnectedNetworkScorer() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ import android.net.wifi.WifiManager.ScanResultsCallback;
|
||||
import android.net.wifi.WifiManager.SoftApCallback;
|
||||
import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
|
||||
import android.net.wifi.WifiManager.TrafficStateCallback;
|
||||
import android.net.wifi.WifiManager.WifiConnectedNetworkScorer;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@@ -138,6 +139,7 @@ public class WifiManagerTest {
|
||||
@Mock Executor mExecutor;
|
||||
@Mock Executor mAnotherExecutor;
|
||||
@Mock ActivityManager mActivityManager;
|
||||
@Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
|
||||
|
||||
private Handler mHandler;
|
||||
private TestLooper mLooper;
|
||||
@@ -2219,4 +2221,63 @@ public class WifiManagerTest {
|
||||
assertEquals(testResults, mWifiManager
|
||||
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl.
|
||||
*/
|
||||
@Test
|
||||
public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
|
||||
mExecutor = new SynchronousExecutor();
|
||||
mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
|
||||
verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
|
||||
any(IWifiConnectedNetworkScorer.Stub.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl.
|
||||
*/
|
||||
@Test
|
||||
public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
|
||||
mExecutor = new SynchronousExecutor();
|
||||
mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
|
||||
verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
|
||||
any(IWifiConnectedNetworkScorer.Stub.class));
|
||||
|
||||
mWifiManager.clearWifiConnectedNetworkScorer();
|
||||
verify(mWifiService).clearWifiConnectedNetworkScorer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that Wi-Fi connected scorer receives score change callback after registeration.
|
||||
*/
|
||||
@Test
|
||||
public void verifyScorerReceiveScoreChangeCallbackAfterRegistration() throws Exception {
|
||||
mExecutor = new SynchronousExecutor();
|
||||
mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
|
||||
ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor =
|
||||
ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
|
||||
verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
|
||||
scorerCaptor.capture());
|
||||
scorerCaptor.getValue().setScoreChangeCallback(any());
|
||||
mLooper.dispatchAll();
|
||||
verify(mWifiConnectedNetworkScorer).setScoreChangeCallback(any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that Wi-Fi connected scorer receives session ID when start/stop methods are called.
|
||||
*/
|
||||
@Test
|
||||
public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception {
|
||||
mExecutor = new SynchronousExecutor();
|
||||
mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
|
||||
ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor =
|
||||
ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
|
||||
verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
|
||||
callbackCaptor.capture());
|
||||
callbackCaptor.getValue().start(0);
|
||||
callbackCaptor.getValue().stop(10);
|
||||
mLooper.dispatchAll();
|
||||
verify(mWifiConnectedNetworkScorer).start(0);
|
||||
verify(mWifiConnectedNetworkScorer).stop(10);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user