Merge changes from topic 'experio-scoring' into oc-dev
* changes: Remove Settings.CURATE_SAVED_OPEN_NETWORKS Remove request recommendation from AIDL files. Remove the recommendation request impl and test code. Deprecate the recommendation request code.
This commit is contained in:
committed by
Android (Google) Code Review
commit
bad4573bd4
@@ -27954,13 +27954,13 @@ package android.net {
|
||||
ctor public deprecated NetworkRecommendationProvider(android.os.Handler);
|
||||
ctor public NetworkRecommendationProvider(android.content.Context, java.util.concurrent.Executor);
|
||||
method public final android.os.IBinder getBinder();
|
||||
method public abstract void onRequestRecommendation(android.net.RecommendationRequest, android.net.NetworkRecommendationProvider.ResultCallback);
|
||||
method public deprecated void onRequestRecommendation(android.net.RecommendationRequest, android.net.NetworkRecommendationProvider.ResultCallback);
|
||||
method public abstract void onRequestScores(android.net.NetworkKey[]);
|
||||
field public static final java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
|
||||
field public static final java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
|
||||
field public static final deprecated java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
|
||||
field public static final deprecated java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
|
||||
}
|
||||
|
||||
public static class NetworkRecommendationProvider.ResultCallback {
|
||||
public static deprecated class NetworkRecommendationProvider.ResultCallback {
|
||||
method public void onResult(android.net.RecommendationResult);
|
||||
}
|
||||
|
||||
@@ -28027,7 +28027,7 @@ package android.net {
|
||||
field public static final android.os.Parcelable.Creator<android.net.ProxyInfo> CREATOR;
|
||||
}
|
||||
|
||||
public final class RecommendationRequest implements android.os.Parcelable {
|
||||
public final deprecated class RecommendationRequest implements android.os.Parcelable {
|
||||
ctor protected RecommendationRequest(android.os.Parcel);
|
||||
method public int describeContents();
|
||||
method public android.net.wifi.WifiConfiguration[] getConnectableConfigs();
|
||||
@@ -28042,7 +28042,7 @@ package android.net {
|
||||
field public static final android.os.Parcelable.Creator<android.net.RecommendationRequest> CREATOR;
|
||||
}
|
||||
|
||||
public static final class RecommendationRequest.Builder {
|
||||
public static final deprecated class RecommendationRequest.Builder {
|
||||
ctor public RecommendationRequest.Builder();
|
||||
method public android.net.RecommendationRequest build();
|
||||
method public android.net.RecommendationRequest.Builder setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
|
||||
@@ -28052,7 +28052,7 @@ package android.net {
|
||||
method public android.net.RecommendationRequest.Builder setScanResults(android.net.wifi.ScanResult[]);
|
||||
}
|
||||
|
||||
public final class RecommendationResult implements android.os.Parcelable {
|
||||
public final deprecated class RecommendationResult implements android.os.Parcelable {
|
||||
method public static android.net.RecommendationResult createConnectRecommendation(android.net.wifi.WifiConfiguration);
|
||||
method public static android.net.RecommendationResult createDoNotConnectRecommendation();
|
||||
method public int describeContents();
|
||||
@@ -38082,7 +38082,6 @@ package android.provider {
|
||||
field public static final java.lang.String BOOT_COUNT = "boot_count";
|
||||
field public static final java.lang.String CONTACT_METADATA_SYNC_ENABLED = "contact_metadata_sync_enabled";
|
||||
field public static final android.net.Uri CONTENT_URI;
|
||||
field public static final java.lang.String CURATE_SAVED_OPEN_NETWORKS = "curate_saved_open_networks";
|
||||
field public static final java.lang.String DATA_ROAMING = "data_roaming";
|
||||
field public static final java.lang.String DEBUG_APP = "debug_app";
|
||||
field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
package android.net;
|
||||
|
||||
import android.net.NetworkKey;
|
||||
import android.net.RecommendationRequest;
|
||||
import android.os.IRemoteCallback;
|
||||
|
||||
/**
|
||||
* The service responsible for answering network recommendation requests.
|
||||
@@ -26,20 +24,6 @@ import android.os.IRemoteCallback;
|
||||
*/
|
||||
oneway interface INetworkRecommendationProvider {
|
||||
|
||||
/**
|
||||
* Request a recommendation for the best network to connect to
|
||||
* taking into account the inputs from the {@link RecommendationRequest}.
|
||||
*
|
||||
* @param request a {@link RecommendationRequest} instance containing the details of the request
|
||||
* @param callback a {@link IRemoteCallback} instance to invoke when the recommendation
|
||||
* is available
|
||||
* @param sequence an internal number used for tracking the request
|
||||
* @hide
|
||||
*/
|
||||
void requestRecommendation(in RecommendationRequest request,
|
||||
in IRemoteCallback callback,
|
||||
int sequence);
|
||||
|
||||
/**
|
||||
* Request scoring for networks.
|
||||
*
|
||||
|
||||
@@ -19,10 +19,7 @@ package android.net;
|
||||
import android.net.INetworkScoreCache;
|
||||
import android.net.NetworkKey;
|
||||
import android.net.NetworkScorerAppData;
|
||||
import android.net.RecommendationRequest;
|
||||
import android.net.RecommendationResult;
|
||||
import android.net.ScoredNetwork;
|
||||
import android.os.RemoteCallback;
|
||||
|
||||
/**
|
||||
* A service for updating network scores from a network scorer application.
|
||||
@@ -80,16 +77,6 @@ interface INetworkScoreService
|
||||
*/
|
||||
void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);
|
||||
|
||||
/**
|
||||
* Request a recommendation for the best network to connect to
|
||||
* taking into account the inputs from the {@link RecommendationRequest}.
|
||||
*
|
||||
* @param request a {@link RecommendationRequest} instance containing the details of the request
|
||||
* @return a {@link RecommendationResult} containing the recommended network to connect to
|
||||
* @throws SecurityException if the caller is not the system
|
||||
*/
|
||||
RecommendationResult requestRecommendation(in RecommendationRequest request);
|
||||
|
||||
/**
|
||||
* Request scoring for networks.
|
||||
*
|
||||
@@ -119,18 +106,6 @@ interface INetworkScoreService
|
||||
* scorer.
|
||||
*/
|
||||
String getActiveScorerPackage();
|
||||
|
||||
/**
|
||||
* Request a recommendation for the best network to connect to
|
||||
* taking into account the inputs from the {@link RecommendationRequest}.
|
||||
*
|
||||
* @param request a {@link RecommendationRequest} instance containing the details of the request
|
||||
* @param remoteCallback a {@link RemoteCallback} instance to invoke when the recommendation
|
||||
* is available.
|
||||
* @throws SecurityException if the caller is not the system
|
||||
*/
|
||||
oneway void requestRecommendationAsync(in RecommendationRequest request,
|
||||
in RemoteCallback remoteCallback);
|
||||
|
||||
/**
|
||||
* Returns metadata about the active scorer or <code>null</code> if there is no active scorer.
|
||||
|
||||
@@ -39,10 +39,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
public abstract class NetworkRecommendationProvider {
|
||||
private static final String TAG = "NetworkRecProvider";
|
||||
private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
|
||||
/** The key into the callback Bundle where the RecommendationResult will be found. */
|
||||
/** The key into the callback Bundle where the RecommendationResult will be found.
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
public static final String EXTRA_RECOMMENDATION_RESULT =
|
||||
"android.net.extra.RECOMMENDATION_RESULT";
|
||||
/** The key into the callback Bundle where the sequence will be found. */
|
||||
/** The key into the callback Bundle where the sequence will be found.
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
public static final String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
|
||||
private final IBinder mService;
|
||||
|
||||
@@ -77,9 +81,9 @@ public abstract class NetworkRecommendationProvider {
|
||||
* @param callback a {@link ResultCallback} instance. When a {@link RecommendationResult} is
|
||||
* available it must be passed into
|
||||
* {@link ResultCallback#onResult(RecommendationResult)}.
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
public abstract void onRequestRecommendation(RecommendationRequest request,
|
||||
ResultCallback callback);
|
||||
public void onRequestRecommendation(RecommendationRequest request, ResultCallback callback) {}
|
||||
|
||||
/**
|
||||
* Invoked when network scores have been requested.
|
||||
@@ -101,6 +105,8 @@ public abstract class NetworkRecommendationProvider {
|
||||
/**
|
||||
* A callback implementing applications should invoke when a {@link RecommendationResult}
|
||||
* is available.
|
||||
*
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
public static class ResultCallback {
|
||||
private final IRemoteCallback mCallback;
|
||||
@@ -175,23 +181,6 @@ public abstract class NetworkRecommendationProvider {
|
||||
mHandler = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestRecommendation(final RecommendationRequest request,
|
||||
final IRemoteCallback callback, final int sequence) throws RemoteException {
|
||||
enforceCallingPermission();
|
||||
if (VERBOSE) Log.v(TAG, "requestRecommendation(seq=" + sequence + ")");
|
||||
execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, "requestRecommendation(seq=" + sequence + ") running...");
|
||||
}
|
||||
ResultCallback resultCallback = new ResultCallback(callback, sequence);
|
||||
onRequestRecommendation(request, resultCallback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestScores(final NetworkKey[] networks) throws RemoteException {
|
||||
enforceCallingPermission();
|
||||
|
||||
@@ -428,14 +428,11 @@ public class NetworkScoreManager {
|
||||
* @throws SecurityException if the caller does not hold the
|
||||
* {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
|
||||
* @hide
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
public RecommendationResult requestRecommendation(RecommendationRequest request)
|
||||
throws SecurityException {
|
||||
try {
|
||||
return mService.requestRecommendation(request);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,43 +449,4 @@ public class NetworkScoreManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a recommendation for which network to connect to.
|
||||
*
|
||||
* <p>The callback will be run on the thread associated with provided {@link Handler}.
|
||||
*
|
||||
* @param request a {@link RecommendationRequest} instance containing additional
|
||||
* request details
|
||||
* @param handler a {@link Handler} instance representing the thread to complete the future on.
|
||||
* If null the responding binder thread will be used.
|
||||
* @return a {@link CompletableFuture} instance that will eventually receive the
|
||||
* {@link RecommendationResult}.
|
||||
* @throws SecurityException
|
||||
* @hide
|
||||
*/
|
||||
public CompletableFuture<RecommendationResult> requestRecommendation(
|
||||
final @NonNull RecommendationRequest request,
|
||||
final @Nullable Handler handler) {
|
||||
Preconditions.checkNotNull(request, "RecommendationRequest cannot be null.");
|
||||
|
||||
final CompletableFuture<RecommendationResult> futureResult =
|
||||
new CompletableFuture<>();
|
||||
|
||||
RemoteCallback remoteCallback = new RemoteCallback(new RemoteCallback.OnResultListener() {
|
||||
@Override
|
||||
public void onResult(Bundle data) {
|
||||
RecommendationResult result = data.getParcelable(EXTRA_RECOMMENDATION_RESULT);
|
||||
futureResult.complete(result);
|
||||
}
|
||||
}, handler);
|
||||
|
||||
try {
|
||||
mService.requestRecommendationAsync(request, remoteCallback);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
return futureResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2016, 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;
|
||||
|
||||
parcelable RecommendationRequest;
|
||||
@@ -30,6 +30,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
*
|
||||
* @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}.
|
||||
* @hide
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
@SystemApi
|
||||
public final class RecommendationRequest implements Parcelable {
|
||||
@@ -43,6 +44,7 @@ public final class RecommendationRequest implements Parcelable {
|
||||
/**
|
||||
* Builder class for constructing {@link RecommendationRequest} instances.
|
||||
* @hide
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
@SystemApi
|
||||
public static final class Builder {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2016, 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;
|
||||
|
||||
parcelable RecommendationResult;
|
||||
@@ -31,6 +31,7 @@ import com.android.internal.util.Preconditions;
|
||||
*
|
||||
* @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}.
|
||||
* @hide
|
||||
* @deprecated to be removed.
|
||||
*/
|
||||
@SystemApi
|
||||
public final class RecommendationResult implements Parcelable {
|
||||
|
||||
@@ -8371,16 +8371,6 @@ public final class Settings {
|
||||
public static final String NETWORK_RECOMMENDATIONS_PACKAGE =
|
||||
"network_recommendations_package";
|
||||
|
||||
/**
|
||||
* Value to specify if the Wi-Fi Framework should defer to
|
||||
* {@link com.android.server.NetworkScoreService} for evaluating saved open networks.
|
||||
*
|
||||
* Type: int (0 for false, 1 for true)
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String CURATE_SAVED_OPEN_NETWORKS = "curate_saved_open_networks";
|
||||
|
||||
/**
|
||||
* The package name of the application that connect and secures high quality open wifi
|
||||
* networks automatically.
|
||||
@@ -8396,6 +8386,7 @@ public final class Settings {
|
||||
*
|
||||
* Type: long
|
||||
* @hide
|
||||
* @deprecated to be removed
|
||||
*/
|
||||
public static final String NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS =
|
||||
"network_recommendation_request_timeout_ms";
|
||||
@@ -9897,7 +9888,6 @@ public final class Settings {
|
||||
CHARGING_SOUNDS_ENABLED,
|
||||
USB_MASS_STORAGE_ENABLED,
|
||||
NETWORK_RECOMMENDATIONS_ENABLED,
|
||||
CURATE_SAVED_OPEN_NETWORKS,
|
||||
WIFI_WAKEUP_ENABLED,
|
||||
WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
|
||||
USE_OPEN_WIFI_PACKAGE,
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
package android.net;
|
||||
|
||||
import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
|
||||
import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertSame;
|
||||
import static junit.framework.Assert.fail;
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
|
||||
import android.Manifest.permission;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
@@ -35,11 +28,9 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NetworkRecommendationProviderTest {
|
||||
@Mock private IRemoteCallback mMockRemoteCallback;
|
||||
@Mock private Context mContext;
|
||||
private NetworkRecProvider mRecProvider;
|
||||
private INetworkRecommendationProvider mStub;
|
||||
private CountDownLatch mRecRequestLatch;
|
||||
private CountDownLatch mScoreRequestLatch;
|
||||
private NetworkKey[] mTestNetworkKeys;
|
||||
|
||||
@@ -48,79 +39,14 @@ public class NetworkRecommendationProviderTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
Executor executor = Executors.newSingleThreadExecutor();
|
||||
mRecRequestLatch = new CountDownLatch(1);
|
||||
mScoreRequestLatch = new CountDownLatch(1);
|
||||
mRecProvider = new NetworkRecProvider(mContext, executor, mRecRequestLatch,
|
||||
mScoreRequestLatch);
|
||||
mRecProvider = new NetworkRecProvider(mContext, executor, mScoreRequestLatch);
|
||||
mStub = INetworkRecommendationProvider.Stub.asInterface(mRecProvider.getBinder());
|
||||
mTestNetworkKeys = new NetworkKey[2];
|
||||
mTestNetworkKeys[0] = new NetworkKey(new WifiKey("\"ssid_01\"", "00:00:00:00:00:11"));
|
||||
mTestNetworkKeys[1] = new NetworkKey(new WifiKey("\"ssid_02\"", "00:00:00:00:00:22"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecommendationRequestReceived() throws Exception {
|
||||
final RecommendationRequest request = new RecommendationRequest.Builder().build();
|
||||
final int sequence = 100;
|
||||
mStub.requestRecommendation(request, mMockRemoteCallback, sequence);
|
||||
|
||||
// wait for onRequestRecommendation() to be called in our impl below.
|
||||
mRecRequestLatch.await(200, TimeUnit.MILLISECONDS);
|
||||
NetworkRecommendationProvider.ResultCallback expectedResultCallback =
|
||||
new NetworkRecommendationProvider.ResultCallback(mMockRemoteCallback, sequence);
|
||||
assertEquals(request, mRecProvider.mCapturedRequest);
|
||||
assertEquals(expectedResultCallback, mRecProvider.mCapturedCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecommendationRequest_permissionsEnforced() throws Exception {
|
||||
final RecommendationRequest request = new RecommendationRequest.Builder().build();
|
||||
final int sequence = 100;
|
||||
Mockito.doThrow(new SecurityException())
|
||||
.when(mContext)
|
||||
.enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES), anyString());
|
||||
|
||||
try {
|
||||
mStub.requestRecommendation(request, mMockRemoteCallback, sequence);
|
||||
fail("SecurityException expected.");
|
||||
} catch (SecurityException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultCallbackOnResult() throws Exception {
|
||||
final int sequence = 100;
|
||||
final NetworkRecommendationProvider.ResultCallback callback =
|
||||
new NetworkRecommendationProvider.ResultCallback(mMockRemoteCallback, sequence);
|
||||
|
||||
final RecommendationResult result = RecommendationResult.createDoNotConnectRecommendation();
|
||||
callback.onResult(result);
|
||||
|
||||
final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
Mockito.verify(mMockRemoteCallback).sendResult(bundleCaptor.capture());
|
||||
Bundle capturedBundle = bundleCaptor.getValue();
|
||||
assertEquals(sequence, capturedBundle.getInt(EXTRA_SEQUENCE));
|
||||
assertSame(result, capturedBundle.getParcelable(EXTRA_RECOMMENDATION_RESULT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultCallbackOnResult_runTwice_throwsException() throws Exception {
|
||||
final int sequence = 100;
|
||||
final NetworkRecommendationProvider.ResultCallback callback =
|
||||
new NetworkRecommendationProvider.ResultCallback(mMockRemoteCallback, sequence);
|
||||
|
||||
final RecommendationResult result = RecommendationResult.createDoNotConnectRecommendation();
|
||||
callback.onResult(result);
|
||||
|
||||
try {
|
||||
callback.onResult(result);
|
||||
fail("Callback ran more than once.");
|
||||
} catch (IllegalStateException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScoreRequestReceived() throws Exception {
|
||||
mStub.requestScores(mTestNetworkKeys);
|
||||
@@ -162,27 +88,14 @@ public class NetworkRecommendationProviderTest {
|
||||
}
|
||||
|
||||
private static class NetworkRecProvider extends NetworkRecommendationProvider {
|
||||
private final CountDownLatch mRecRequestLatch;
|
||||
private final CountDownLatch mScoreRequestLatch;
|
||||
RecommendationRequest mCapturedRequest;
|
||||
ResultCallback mCapturedCallback;
|
||||
NetworkKey[] mCapturedNetworks;
|
||||
|
||||
NetworkRecProvider(Context context, Executor executor, CountDownLatch recRequestLatch,
|
||||
CountDownLatch networkRequestLatch) {
|
||||
NetworkRecProvider(Context context, Executor executor, CountDownLatch networkRequestLatch) {
|
||||
super(context, executor);
|
||||
mRecRequestLatch = recRequestLatch;
|
||||
mScoreRequestLatch = networkRequestLatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestRecommendation(RecommendationRequest request,
|
||||
ResultCallback callback) {
|
||||
mCapturedRequest = request;
|
||||
mCapturedCallback = callback;
|
||||
mRecRequestLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestScores(NetworkKey[] networks) {
|
||||
mCapturedNetworks = networks;
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
package android.net;
|
||||
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.os.Parcel;
|
||||
import android.os.SystemClock;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
public class RecommendationRequestTest extends AndroidTestCase {
|
||||
private ScanResult[] mScanResults;
|
||||
private WifiConfiguration mDefaultConfig;
|
||||
private WifiConfiguration mConnectedConfig;
|
||||
private WifiConfiguration[] mConnectableConfigs;
|
||||
private int mLastSelectedNetworkId;
|
||||
private long mLastSelectedNetworkTimestamp;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
mScanResults = new ScanResult[2];
|
||||
mScanResults[0] = new ScanResult();
|
||||
mScanResults[1] = new ScanResult(
|
||||
"ssid",
|
||||
"bssid",
|
||||
0L /*hessid*/,
|
||||
1 /*anqpDominId*/,
|
||||
"caps",
|
||||
2 /*level*/,
|
||||
3 /*frequency*/,
|
||||
4L /*tsf*/,
|
||||
5 /*distCm*/,
|
||||
6 /*distSdCm*/,
|
||||
7 /*channelWidth*/,
|
||||
8 /*centerFreq0*/,
|
||||
9 /*centerFreq1*/,
|
||||
false /*is80211McRTTResponder*/);
|
||||
mDefaultConfig = new WifiConfiguration();
|
||||
mDefaultConfig.SSID = "default_config";
|
||||
mConnectedConfig = new WifiConfiguration();
|
||||
mConnectedConfig.SSID = "connected_config";
|
||||
mConnectableConfigs = new WifiConfiguration[] {mDefaultConfig, mConnectedConfig};
|
||||
mLastSelectedNetworkId = 5;
|
||||
mLastSelectedNetworkTimestamp = SystemClock.elapsedRealtime();
|
||||
}
|
||||
|
||||
public void testParceling() throws Exception {
|
||||
RecommendationRequest request = new RecommendationRequest.Builder()
|
||||
.setDefaultWifiConfig(mDefaultConfig)
|
||||
.setScanResults(mScanResults)
|
||||
.setConnectedWifiConfig(mConnectedConfig)
|
||||
.setConnectableConfigs(mConnectableConfigs)
|
||||
.setLastSelectedNetwork(mLastSelectedNetworkId, mLastSelectedNetworkTimestamp)
|
||||
.build();
|
||||
|
||||
RecommendationRequest parceled = passThroughParcel(request);
|
||||
assertEquals(request.getDefaultWifiConfig().SSID,
|
||||
parceled.getDefaultWifiConfig().SSID);
|
||||
assertEquals(request.getConnectedConfig().SSID,
|
||||
parceled.getConnectedConfig().SSID);
|
||||
ScanResult[] parceledScanResults = parceled.getScanResults();
|
||||
assertNotNull(parceledScanResults);
|
||||
assertEquals(mScanResults.length, parceledScanResults.length);
|
||||
for (int i = 0; i < mScanResults.length; i++) {
|
||||
assertEquals(mScanResults[i].SSID, parceledScanResults[i].SSID);
|
||||
}
|
||||
WifiConfiguration[] parceledConfigs = parceled.getConnectableConfigs();
|
||||
for (int i = 0; i < parceledConfigs.length; i++) {
|
||||
assertEquals(mConnectableConfigs[i].SSID, parceledConfigs[i].SSID);
|
||||
}
|
||||
assertEquals(mLastSelectedNetworkId, parceled.getLastSelectedNetworkId());
|
||||
assertEquals(mLastSelectedNetworkTimestamp, parceled.getLastSelectedNetworkTimestamp());
|
||||
}
|
||||
|
||||
public void testParceling_nullScanResults() throws Exception {
|
||||
RecommendationRequest request = new RecommendationRequest.Builder()
|
||||
.setDefaultWifiConfig(mDefaultConfig)
|
||||
.build();
|
||||
|
||||
RecommendationRequest parceled = passThroughParcel(request);
|
||||
ScanResult[] parceledScanResults = parceled.getScanResults();
|
||||
assertNull(parceledScanResults);
|
||||
}
|
||||
|
||||
public void testParceling_nullWifiConfigArray() throws Exception {
|
||||
RecommendationRequest request = new RecommendationRequest.Builder()
|
||||
.setDefaultWifiConfig(mDefaultConfig)
|
||||
.build();
|
||||
|
||||
RecommendationRequest parceled = passThroughParcel(request);
|
||||
WifiConfiguration[] parceledConfigs = parceled.getConnectableConfigs();
|
||||
assertNull(parceledConfigs);
|
||||
}
|
||||
|
||||
public void testParceling_unsetLastSelectedNetwork() throws Exception {
|
||||
RecommendationRequest request = new RecommendationRequest.Builder()
|
||||
.build();
|
||||
|
||||
RecommendationRequest parceled = passThroughParcel(request);
|
||||
|
||||
assertEquals(-1, parceled.getLastSelectedNetworkId());
|
||||
assertEquals(0, parceled.getLastSelectedNetworkTimestamp());
|
||||
}
|
||||
|
||||
private RecommendationRequest passThroughParcel(RecommendationRequest request) {
|
||||
Parcel p = Parcel.obtain();
|
||||
RecommendationRequest output = null;
|
||||
try {
|
||||
request.writeToParcel(p, 0);
|
||||
p.setDataPosition(0);
|
||||
output = RecommendationRequest.CREATOR.createFromParcel(p);
|
||||
} finally {
|
||||
p.recycle();
|
||||
}
|
||||
assertNotNull(output);
|
||||
return output;
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
|
||||
import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
|
||||
|
||||
import android.Manifest.permission;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -36,8 +33,6 @@ import android.net.INetworkScoreService;
|
||||
import android.net.NetworkKey;
|
||||
import android.net.NetworkScoreManager;
|
||||
import android.net.NetworkScorerAppData;
|
||||
import android.net.RecommendationRequest;
|
||||
import android.net.RecommendationResult;
|
||||
import android.net.ScoredNetwork;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.ScanResult;
|
||||
@@ -46,24 +41,18 @@ import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.WifiScanner;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteCallback;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.TimedRemoteCaller;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -80,9 +69,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
@@ -99,7 +85,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
|
||||
private final Context mContext;
|
||||
private final NetworkScorerAppManager mNetworkScorerAppManager;
|
||||
private final AtomicReference<RequestRecommendationCaller> mReqRecommendationCallerRef;
|
||||
@GuardedBy("mScoreCaches")
|
||||
private final Map<Integer, RemoteCallbackList<INetworkScoreCache>> mScoreCaches;
|
||||
/** Lock used to update mPackageMonitor when scorer package changes occur. */
|
||||
@@ -113,7 +98,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
private NetworkScorerPackageMonitor mPackageMonitor;
|
||||
@GuardedBy("mServiceConnectionLock")
|
||||
private ScoringServiceConnection mServiceConnection;
|
||||
private volatile long mRecommendationRequestTimeoutMs;
|
||||
|
||||
private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
@@ -256,9 +240,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
mContext.registerReceiverAsUser(
|
||||
mUserIntentReceiver, UserHandle.SYSTEM, filter, null /* broadcastPermission*/,
|
||||
null /* scheduler */);
|
||||
mReqRecommendationCallerRef = new AtomicReference<>(
|
||||
new RequestRecommendationCaller(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS));
|
||||
mRecommendationRequestTimeoutMs = TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS;
|
||||
mHandler = new ServiceHandler(looper);
|
||||
mContentObserver = new DispatchingContentObserver(context, mHandler);
|
||||
mServiceConnProducer = serviceConnProducer;
|
||||
@@ -295,10 +276,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
mContentObserver.observe(packageNameUri,
|
||||
ServiceHandler.MSG_RECOMMENDATIONS_PACKAGE_CHANGED);
|
||||
|
||||
final Uri timeoutUri = Global.getUriFor(Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS);
|
||||
mContentObserver.observe(timeoutUri,
|
||||
ServiceHandler.MSG_RECOMMENDATION_REQUEST_TIMEOUT_CHANGED);
|
||||
|
||||
final Uri settingUri = Global.getUriFor(Global.NETWORK_RECOMMENDATIONS_ENABLED);
|
||||
mContentObserver.observe(settingUri,
|
||||
ServiceHandler.MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED);
|
||||
@@ -826,87 +803,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecommendationResult requestRecommendation(RecommendationRequest request) {
|
||||
mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
|
||||
throwIfCalledOnMainThread();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final INetworkRecommendationProvider provider = getRecommendationProvider();
|
||||
if (provider != null) {
|
||||
try {
|
||||
final RequestRecommendationCaller caller = mReqRecommendationCallerRef.get();
|
||||
return caller.getRecommendationResult(provider, request);
|
||||
} catch (RemoteException | TimeoutException e) {
|
||||
Log.w(TAG, "Failed to request a recommendation.", e);
|
||||
// TODO: 12/15/16 - Keep track of failures.
|
||||
}
|
||||
}
|
||||
|
||||
if (DBG) {
|
||||
Log.d(TAG, "Returning the default network recommendation.");
|
||||
}
|
||||
|
||||
if (request != null && request.getDefaultWifiConfig() != null) {
|
||||
return RecommendationResult.createConnectRecommendation(
|
||||
request.getDefaultWifiConfig());
|
||||
}
|
||||
return RecommendationResult.createDoNotConnectRecommendation();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a recommendation for the best network to connect to
|
||||
* taking into account the inputs from the {@link RecommendationRequest}.
|
||||
*
|
||||
* @param request a {@link RecommendationRequest} instance containing the details of the request
|
||||
* @param remoteCallback a {@link IRemoteCallback} instance to invoke when the recommendation
|
||||
* is available.
|
||||
* @throws SecurityException if the caller is not the system
|
||||
*/
|
||||
@Override
|
||||
public void requestRecommendationAsync(RecommendationRequest request,
|
||||
RemoteCallback remoteCallback) {
|
||||
mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
|
||||
|
||||
final OneTimeCallback oneTimeCallback = new OneTimeCallback(remoteCallback);
|
||||
final Pair<RecommendationRequest, OneTimeCallback> pair =
|
||||
Pair.create(request, oneTimeCallback);
|
||||
final Message timeoutMsg = mHandler.obtainMessage(
|
||||
ServiceHandler.MSG_RECOMMENDATION_REQUEST_TIMEOUT, pair);
|
||||
final INetworkRecommendationProvider provider = getRecommendationProvider();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
if (provider != null) {
|
||||
try {
|
||||
mHandler.sendMessageDelayed(timeoutMsg, mRecommendationRequestTimeoutMs);
|
||||
provider.requestRecommendation(request, new IRemoteCallback.Stub() {
|
||||
@Override
|
||||
public void sendResult(Bundle data) throws RemoteException {
|
||||
// Remove the timeout message
|
||||
mHandler.removeMessages(timeoutMsg.what, pair);
|
||||
oneTimeCallback.sendResult(data);
|
||||
}
|
||||
}, 0 /*sequence*/);
|
||||
return;
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to request a recommendation.", e);
|
||||
// TODO: 12/15/16 - Keep track of failures.
|
||||
// Remove the timeout message
|
||||
mHandler.removeMessages(timeoutMsg.what, pair);
|
||||
// Will fall through and send back the default recommendation.
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
|
||||
// Else send back the default recommendation.
|
||||
sendDefaultRecommendationResponse(request, oneTimeCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestScores(NetworkKey[] networks) {
|
||||
mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
|
||||
@@ -941,7 +837,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
return;
|
||||
}
|
||||
writer.println("Current scorer: " + currentScorer);
|
||||
writer.println("RecommendationRequestTimeoutMs: " + mRecommendationRequestTimeoutMs);
|
||||
|
||||
sendCacheUpdateCallback(new BiConsumer<INetworkScoreCache, Object>() {
|
||||
@Override
|
||||
@@ -996,12 +891,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void throwIfCalledOnMainThread() {
|
||||
if (Thread.currentThread() == mContext.getMainLooper().getThread()) {
|
||||
throw new RuntimeException("Cannot invoke on the main thread");
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private INetworkRecommendationProvider getRecommendationProvider() {
|
||||
synchronized (mServiceConnectionLock) {
|
||||
@@ -1012,19 +901,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
return null;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void refreshRecommendationRequestTimeoutMs() {
|
||||
final ContentResolver cr = mContext.getContentResolver();
|
||||
long timeoutMs = Settings.Global.getLong(cr,
|
||||
Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, -1L /*default*/);
|
||||
if (timeoutMs < 0) {
|
||||
timeoutMs = TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS;
|
||||
}
|
||||
if (DBG) Log.d(TAG, "Updating the recommendation request timeout to " + timeoutMs + " ms");
|
||||
mRecommendationRequestTimeoutMs = timeoutMs;
|
||||
mReqRecommendationCallerRef.set(new RequestRecommendationCaller(timeoutMs));
|
||||
}
|
||||
|
||||
// The class and methods need to be public for Mockito to work.
|
||||
@VisibleForTesting
|
||||
public static class ScoringServiceConnection implements ServiceConnection {
|
||||
@@ -1114,93 +990,10 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the async requestRecommendation() call with a timeout.
|
||||
*/
|
||||
private static final class RequestRecommendationCaller
|
||||
extends TimedRemoteCaller<RecommendationResult> {
|
||||
private final IRemoteCallback mCallback;
|
||||
|
||||
RequestRecommendationCaller(long callTimeoutMillis) {
|
||||
super(callTimeoutMillis);
|
||||
mCallback = new IRemoteCallback.Stub() {
|
||||
@Override
|
||||
public void sendResult(Bundle data) throws RemoteException {
|
||||
final RecommendationResult result =
|
||||
data.getParcelable(EXTRA_RECOMMENDATION_RESULT);
|
||||
final int sequence = data.getInt(EXTRA_SEQUENCE, -1);
|
||||
if (VERBOSE) Log.v(TAG, "callback received for sequence " + sequence);
|
||||
onRemoteMethodResult(result, sequence);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the requestRecommendation() call on the given {@link INetworkRecommendationProvider}
|
||||
* instance.
|
||||
*
|
||||
* @param target the {@link INetworkRecommendationProvider} to request a recommendation
|
||||
* from
|
||||
* @param request the {@link RecommendationRequest} from the calling client
|
||||
* @return a {@link RecommendationResult} from the provider
|
||||
* @throws RemoteException if the call failed
|
||||
* @throws TimeoutException if the call took longer than the set timeout
|
||||
*/
|
||||
RecommendationResult getRecommendationResult(INetworkRecommendationProvider target,
|
||||
RecommendationRequest request) throws RemoteException, TimeoutException {
|
||||
final int sequence = onBeforeRemoteCall();
|
||||
if (VERBOSE) Log.v(TAG, "getRecommendationResult() seq=" + sequence);
|
||||
target.requestRecommendation(request, mCallback, sequence);
|
||||
return getResultTimed(sequence);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around {@link RemoteCallback} that guarantees
|
||||
* {@link RemoteCallback#sendResult(Bundle)} will be invoked at most once.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static final class OneTimeCallback {
|
||||
private final RemoteCallback mRemoteCallback;
|
||||
private final AtomicBoolean mCallbackRun;
|
||||
|
||||
public OneTimeCallback(RemoteCallback remoteCallback) {
|
||||
mRemoteCallback = remoteCallback;
|
||||
mCallbackRun = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
public void sendResult(Bundle data) {
|
||||
if (mCallbackRun.compareAndSet(false, true)) {
|
||||
mRemoteCallback.sendResult(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendDefaultRecommendationResponse(RecommendationRequest request,
|
||||
OneTimeCallback remoteCallback) {
|
||||
if (DBG) {
|
||||
Log.d(TAG, "Returning the default network recommendation.");
|
||||
}
|
||||
|
||||
final RecommendationResult result;
|
||||
if (request != null && request.getDefaultWifiConfig() != null) {
|
||||
result = RecommendationResult.createConnectRecommendation(
|
||||
request.getDefaultWifiConfig());
|
||||
} else {
|
||||
result = RecommendationResult.createDoNotConnectRecommendation();
|
||||
}
|
||||
|
||||
final Bundle data = new Bundle();
|
||||
data.putParcelable(EXTRA_RECOMMENDATION_RESULT, result);
|
||||
remoteCallback.sendResult(data);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public final class ServiceHandler extends Handler {
|
||||
public static final int MSG_RECOMMENDATION_REQUEST_TIMEOUT = 1;
|
||||
public static final int MSG_RECOMMENDATIONS_PACKAGE_CHANGED = 2;
|
||||
public static final int MSG_RECOMMENDATION_REQUEST_TIMEOUT_CHANGED = 3;
|
||||
public static final int MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED = 4;
|
||||
public static final int MSG_RECOMMENDATIONS_PACKAGE_CHANGED = 1;
|
||||
public static final int MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED = 2;
|
||||
|
||||
public ServiceHandler(Looper looper) {
|
||||
super(looper);
|
||||
@@ -1210,26 +1003,11 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
public void handleMessage(Message msg) {
|
||||
final int what = msg.what;
|
||||
switch (what) {
|
||||
case MSG_RECOMMENDATION_REQUEST_TIMEOUT:
|
||||
if (DBG) {
|
||||
Log.d(TAG, "Network recommendation request timed out.");
|
||||
}
|
||||
final Pair<RecommendationRequest, OneTimeCallback> pair =
|
||||
(Pair<RecommendationRequest, OneTimeCallback>) msg.obj;
|
||||
final RecommendationRequest request = pair.first;
|
||||
final OneTimeCallback remoteCallback = pair.second;
|
||||
sendDefaultRecommendationResponse(request, remoteCallback);
|
||||
break;
|
||||
|
||||
case MSG_RECOMMENDATIONS_PACKAGE_CHANGED:
|
||||
case MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED:
|
||||
refreshBinding();
|
||||
break;
|
||||
|
||||
case MSG_RECOMMENDATION_REQUEST_TIMEOUT_CHANGED:
|
||||
refreshRecommendationRequestTimeoutMs();
|
||||
break;
|
||||
|
||||
default:
|
||||
Log.w(TAG,"Unknown message: " + what);
|
||||
}
|
||||
|
||||
@@ -16,25 +16,18 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
|
||||
import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
|
||||
import static android.net.NetworkScoreManager.CACHE_FILTER_NONE;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertSame;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyListOf;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -55,8 +48,6 @@ import android.net.INetworkScoreCache;
|
||||
import android.net.NetworkKey;
|
||||
import android.net.NetworkScoreManager;
|
||||
import android.net.NetworkScorerAppData;
|
||||
import android.net.RecommendationRequest;
|
||||
import android.net.RecommendationResult;
|
||||
import android.net.ScoredNetwork;
|
||||
import android.net.Uri;
|
||||
import android.net.WifiKey;
|
||||
@@ -69,13 +60,11 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
@@ -145,9 +134,6 @@ public class NetworkScoreServiceTest {
|
||||
|
||||
private ContentResolver mContentResolver;
|
||||
private NetworkScoreService mNetworkScoreService;
|
||||
private RecommendationRequest mRecommendationRequest;
|
||||
private RemoteCallback mRemoteCallback;
|
||||
private OnResultListener mOnResultListener;
|
||||
private HandlerThread mHandlerThread;
|
||||
private List<ScanResult> mScanResults;
|
||||
|
||||
@@ -177,13 +163,6 @@ public class NetworkScoreServiceTest {
|
||||
WifiConfiguration configuration = new WifiConfiguration();
|
||||
configuration.SSID = "NetworkScoreServiceTest_SSID";
|
||||
configuration.BSSID = "NetworkScoreServiceTest_BSSID";
|
||||
mRecommendationRequest = new RecommendationRequest.Builder()
|
||||
.setDefaultWifiConfig(configuration).build();
|
||||
mOnResultListener = new OnResultListener();
|
||||
mRemoteCallback = new RemoteCallback(mOnResultListener);
|
||||
Settings.Global.putLong(mContentResolver,
|
||||
Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, -1L);
|
||||
mNetworkScoreService.refreshRecommendationRequestTimeoutMs();
|
||||
populateScanResults();
|
||||
}
|
||||
|
||||
@@ -215,7 +194,6 @@ public class NetworkScoreServiceTest {
|
||||
verify(mNetworkScorerAppManager).updateState();
|
||||
verify(mNetworkScorerAppManager).migrateNetworkScorerAppSettingIfNeeded();
|
||||
verify(mServiceConnection).bind(mContext);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -255,160 +233,6 @@ public class NetworkScoreServiceTest {
|
||||
verify(mRecommendationProvider).requestScores(networks);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendation_noPermission() throws Exception {
|
||||
doThrow(new SecurityException()).when(mContext)
|
||||
.enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
|
||||
anyString());
|
||||
try {
|
||||
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
|
||||
fail("REQUEST_NETWORK_SCORES not enforced.");
|
||||
} catch (SecurityException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendation_mainThread() throws Exception {
|
||||
when(mContext.getMainLooper()).thenReturn(Looper.myLooper());
|
||||
try {
|
||||
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
|
||||
fail("requestRecommendation run on main thread.");
|
||||
} catch (RuntimeException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendation_providerNotConnected() throws Exception {
|
||||
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
|
||||
|
||||
final RecommendationResult result =
|
||||
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
|
||||
assertNotNull(result);
|
||||
assertEquals(mRecommendationRequest.getDefaultWifiConfig(),
|
||||
result.getWifiConfiguration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendation_providerThrowsRemoteException() throws Exception {
|
||||
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
|
||||
doThrow(new RemoteException()).when(mRecommendationProvider)
|
||||
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
|
||||
anyInt());
|
||||
mNetworkScoreService.onUserUnlocked(0);
|
||||
|
||||
final RecommendationResult result =
|
||||
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
|
||||
assertNotNull(result);
|
||||
assertEquals(mRecommendationRequest.getDefaultWifiConfig(),
|
||||
result.getWifiConfiguration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendation_resultReturned() throws Exception {
|
||||
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
|
||||
final WifiConfiguration wifiConfiguration = new WifiConfiguration();
|
||||
wifiConfiguration.SSID = "testRequestRecommendation_resultReturned_SSID";
|
||||
wifiConfiguration.BSSID = "testRequestRecommendation_resultReturned_BSSID";
|
||||
final RecommendationResult providerResult = RecommendationResult
|
||||
.createConnectRecommendation(wifiConfiguration);
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(EXTRA_RECOMMENDATION_RESULT, providerResult);
|
||||
doAnswer(invocation -> {
|
||||
bundle.putInt(EXTRA_SEQUENCE, invocation.getArgument(2));
|
||||
invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
|
||||
return null;
|
||||
}).when(mRecommendationProvider)
|
||||
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
|
||||
anyInt());
|
||||
mNetworkScoreService.onUserUnlocked(0);
|
||||
|
||||
final RecommendationResult result =
|
||||
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
|
||||
assertNotNull(result);
|
||||
assertEquals(providerResult.getWifiConfiguration().SSID,
|
||||
result.getWifiConfiguration().SSID);
|
||||
assertEquals(providerResult.getWifiConfiguration().BSSID,
|
||||
result.getWifiConfiguration().BSSID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendationAsync_noPermission() throws Exception {
|
||||
doThrow(new SecurityException()).when(mContext)
|
||||
.enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
|
||||
anyString());
|
||||
try {
|
||||
mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
|
||||
mRemoteCallback);
|
||||
fail("REQUEST_NETWORK_SCORES not enforced.");
|
||||
} catch (SecurityException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendationAsync_providerNotConnected() throws Exception {
|
||||
mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
|
||||
mRemoteCallback);
|
||||
boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
|
||||
assertTrue(callbackRan);
|
||||
verifyZeroInteractions(mRecommendationProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendationAsync_requestTimesOut() throws Exception {
|
||||
mNetworkScoreService.onUserUnlocked(0);
|
||||
Settings.Global.putLong(mContentResolver,
|
||||
Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, 1L);
|
||||
mNetworkScoreService.refreshRecommendationRequestTimeoutMs();
|
||||
mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
|
||||
mRemoteCallback);
|
||||
boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
|
||||
assertTrue(callbackRan);
|
||||
verify(mRecommendationProvider).requestRecommendation(eq(mRecommendationRequest),
|
||||
isA(IRemoteCallback.Stub.class), anyInt());
|
||||
|
||||
assertTrue(mOnResultListener.receivedBundle.containsKey(EXTRA_RECOMMENDATION_RESULT));
|
||||
RecommendationResult result =
|
||||
mOnResultListener.receivedBundle.getParcelable(EXTRA_RECOMMENDATION_RESULT);
|
||||
assertTrue(result.hasRecommendation());
|
||||
assertEquals(mRecommendationRequest.getDefaultWifiConfig().SSID,
|
||||
result.getWifiConfiguration().SSID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendationAsync_requestSucceeds() throws Exception {
|
||||
mNetworkScoreService.onUserUnlocked(0);
|
||||
final Bundle bundle = new Bundle();
|
||||
doAnswer(invocation -> {
|
||||
invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
|
||||
return null;
|
||||
}).when(mRecommendationProvider)
|
||||
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
|
||||
anyInt());
|
||||
|
||||
mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
|
||||
mRemoteCallback);
|
||||
boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
|
||||
assertTrue(callbackRan);
|
||||
// If it's not the same instance then something else ran the callback.
|
||||
assertSame(bundle, mOnResultListener.receivedBundle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestRecommendationAsync_requestThrowsRemoteException() throws Exception {
|
||||
mNetworkScoreService.onUserUnlocked(0);
|
||||
doThrow(new RemoteException()).when(mRecommendationProvider)
|
||||
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
|
||||
anyInt());
|
||||
|
||||
mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
|
||||
mRemoteCallback);
|
||||
boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
|
||||
assertTrue(callbackRan);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchingContentObserver_nullUri() throws Exception {
|
||||
NetworkScoreService.DispatchingContentObserver observer =
|
||||
@@ -434,15 +258,6 @@ public class NetworkScoreServiceTest {
|
||||
assertEquals(expectedWhat, handler.receivedWhat);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneTimeCallback_multipleCallbacks() throws Exception {
|
||||
NetworkScoreService.OneTimeCallback callback =
|
||||
new NetworkScoreService.OneTimeCallback(mRemoteCallback);
|
||||
callback.sendResult(null);
|
||||
callback.sendResult(null);
|
||||
assertEquals(1, mOnResultListener.resultCount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateScores_notActiveScorer() {
|
||||
bindToScorer(false /*callerIsScorer*/);
|
||||
@@ -1088,19 +903,6 @@ public class NetworkScoreServiceTest {
|
||||
mNetworkScoreService.onUserUnlocked(0);
|
||||
}
|
||||
|
||||
private static class OnResultListener implements RemoteCallback.OnResultListener {
|
||||
private final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
private int resultCount;
|
||||
private Bundle receivedBundle;
|
||||
|
||||
@Override
|
||||
public void onResult(Bundle result) {
|
||||
countDownLatch.countDown();
|
||||
resultCount++;
|
||||
receivedBundle = result;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CountDownHandler extends Handler {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
int receivedWhat;
|
||||
|
||||
Reference in New Issue
Block a user