diff --git a/api/system-current.txt b/api/system-current.txt index 4ddc901f2eb88..f7075176773fb 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -25606,6 +25606,7 @@ package android.net { ctor public NetworkRecommendationProvider(android.os.Handler); method public final android.os.IBinder getBinder(); method public abstract 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"; } diff --git a/core/java/android/net/INetworkRecommendationProvider.aidl b/core/java/android/net/INetworkRecommendationProvider.aidl index 5e455d3e33fe1..052c92c0309f8 100644 --- a/core/java/android/net/INetworkRecommendationProvider.aidl +++ b/core/java/android/net/INetworkRecommendationProvider.aidl @@ -16,6 +16,7 @@ package android.net; +import android.net.NetworkKey; import android.net.RecommendationRequest; import android.os.IRemoteCallback; @@ -38,4 +39,15 @@ oneway interface INetworkRecommendationProvider { void requestRecommendation(in RecommendationRequest request, in IRemoteCallback callback, int sequence); + + /** + * Request scoring for networks. + * + * Implementations should use {@link NetworkScoreManager#updateScores(ScoredNetwork[])} to + * respond to score requests. + * + * @param networks an array of {@link NetworkKey}s to score + * @hide + */ + void requestScores(in NetworkKey[] networks); } \ No newline at end of file diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl index 24f4504207517..932f03116f154 100644 --- a/core/java/android/net/INetworkScoreService.aidl +++ b/core/java/android/net/INetworkScoreService.aidl @@ -17,6 +17,7 @@ package android.net; import android.net.INetworkScoreCache; +import android.net.NetworkKey; import android.net.RecommendationRequest; import android.net.RecommendationResult; import android.net.ScoredNetwork; @@ -87,4 +88,16 @@ interface INetworkScoreService */ RecommendationResult requestRecommendation(in RecommendationRequest request); + /** + * Request scoring for networks. + * + * Implementations should delegate to the registered network recommendation provider or + * fulfill the request locally if possible. + * + * @param networks an array of {@link NetworkKey}s to score + * @return true if the request was delegated or fulfilled locally, false otherwise + * @throws SecurityException if the caller is not the system + * @hide + */ + boolean requestScores(in NetworkKey[] networks); } diff --git a/core/java/android/net/NetworkRecommendationProvider.java b/core/java/android/net/NetworkRecommendationProvider.java index fc3213f486cd3..af5a052c6bf71 100644 --- a/core/java/android/net/NetworkRecommendationProvider.java +++ b/core/java/android/net/NetworkRecommendationProvider.java @@ -54,6 +54,15 @@ public abstract class NetworkRecommendationProvider { public abstract void onRequestRecommendation(RecommendationRequest request, ResultCallback callback); + /** + * Invoked when network scores have been requested. + *
+ * Use {@link NetworkScoreManager#updateScores(ScoredNetwork[])} to respond to score requests.
+ *
+ * @param networks a non-empty array of {@link NetworkKey}s to score.
+ */
+ public abstract void onRequestScores(NetworkKey[] networks);
+
/**
* Services that can handle {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} should
* return this Binder from their onBind() method.
@@ -118,6 +127,7 @@ public abstract class NetworkRecommendationProvider {
private final class ServiceHandler extends Handler {
static final int MSG_GET_RECOMMENDATION = 1;
+ static final int MSG_REQUEST_SCORES = 2;
ServiceHandler(Looper looper) {
super(looper, null /*callback*/, true /*async*/);
@@ -136,6 +146,11 @@ public abstract class NetworkRecommendationProvider {
onRequestRecommendation(request, resultCallback);
break;
+ case MSG_REQUEST_SCORES:
+ final NetworkKey[] networks = (NetworkKey[]) msg.obj;
+ onRequestScores(networks);
+ break;
+
default:
throw new IllegalArgumentException("Unknown message: " + what);
}
@@ -162,5 +177,12 @@ public abstract class NetworkRecommendationProvider {
msg.setData(data);
msg.sendToTarget();
}
+
+ @Override
+ public void requestScores(NetworkKey[] networks) throws RemoteException {
+ if (networks != null && networks.length > 0) {
+ mHandler.obtainMessage(ServiceHandler.MSG_REQUEST_SCORES, networks).sendToTarget();
+ }
+ }
}
}
diff --git a/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java b/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java
index 5ac8f56dae951..9a81401e535e4 100644
--- a/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java
+++ b/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java
@@ -28,7 +28,9 @@ public class NetworkRecommendationProviderTest extends InstrumentationTestCase {
private NetworkRecProvider mRecProvider;
private Handler mHandler;
private INetworkRecommendationProvider mStub;
- private CountDownLatch mCountDownLatch;
+ private CountDownLatch mRecRequestLatch;
+ private CountDownLatch mScoreRequestLatch;
+ private NetworkKey[] mTestNetworkKeys;
@Override
public void setUp() throws Exception {
@@ -45,20 +47,24 @@ public class NetworkRecommendationProviderTest extends InstrumentationTestCase {
HandlerThread thread = new HandlerThread("NetworkRecommendationProviderTest");
thread.start();
- mCountDownLatch = new CountDownLatch(1);
+ mRecRequestLatch = new CountDownLatch(1);
+ mScoreRequestLatch = new CountDownLatch(1);
mHandler = new Handler(thread.getLooper());
- mRecProvider = new NetworkRecProvider(mHandler, mCountDownLatch);
+ mRecProvider = new NetworkRecProvider(mHandler, mRecRequestLatch, 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"));
}
@MediumTest
- public void testRequestReceived() throws Exception {
+ 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.
- mCountDownLatch.await(200, TimeUnit.MILLISECONDS);
+ mRecRequestLatch.await(200, TimeUnit.MILLISECONDS);
NetworkRecommendationProvider.ResultCallback expectedResultCallback =
new NetworkRecommendationProvider.ResultCallback(mMockRemoteCallback, sequence);
assertEquals(request, mRecProvider.mCapturedRequest);
@@ -98,14 +104,44 @@ public class NetworkRecommendationProviderTest extends InstrumentationTestCase {
}
}
+ @MediumTest
+ public void testScoreRequestReceived() throws Exception {
+ mStub.requestScores(mTestNetworkKeys);
+
+ // wait for onRequestScores() to be called in our impl below.
+ mScoreRequestLatch.await(200, TimeUnit.MILLISECONDS);
+
+ assertSame(mTestNetworkKeys, mRecProvider.mCapturedNetworks);
+ }
+
+ @MediumTest
+ public void testScoreRequest_nullInput() throws Exception {
+ mStub.requestScores(null);
+
+ // onRequestScores() should never be called
+ assertFalse(mScoreRequestLatch.await(200, TimeUnit.MILLISECONDS));
+ }
+
+ @MediumTest
+ public void testScoreRequest_emptyInput() throws Exception {
+ mStub.requestScores(new NetworkKey[0]);
+
+ // onRequestScores() should never be called
+ assertFalse(mScoreRequestLatch.await(200, TimeUnit.MILLISECONDS));
+ }
+
private static class NetworkRecProvider extends NetworkRecommendationProvider {
- private final CountDownLatch mCountDownLatch;
+ private final CountDownLatch mRecRequestLatch;
+ private final CountDownLatch mScoreRequestLatch;
RecommendationRequest mCapturedRequest;
ResultCallback mCapturedCallback;
+ NetworkKey[] mCapturedNetworks;
- NetworkRecProvider(Handler handler, CountDownLatch countDownLatch) {
+ NetworkRecProvider(Handler handler, CountDownLatch recRequestLatch,
+ CountDownLatch networkRequestLatch) {
super(handler);
- mCountDownLatch = countDownLatch;
+ mRecRequestLatch = recRequestLatch;
+ mScoreRequestLatch = networkRequestLatch;
}
@Override
@@ -113,7 +149,13 @@ public class NetworkRecommendationProviderTest extends InstrumentationTestCase {
ResultCallback callback) {
mCapturedRequest = request;
mCapturedCallback = callback;
- mCountDownLatch.countDown();
+ mRecRequestLatch.countDown();
+ }
+
+ @Override
+ public void onRequestScores(NetworkKey[] networks) {
+ mCapturedNetworks = networks;
+ mScoreRequestLatch.countDown();
}
}
}
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 27e4aa48c0470..a1c3564abf8c8 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -27,6 +27,7 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.net.INetworkScoreCache;
import android.net.INetworkScoreService;
+import android.net.NetworkKey;
import android.net.NetworkScoreManager;
import android.net.NetworkScorerAppManager;
import android.net.NetworkScorerAppManager.NetworkScorerAppData;
@@ -471,6 +472,12 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
return new RecommendationResult(selectedConfig);
}
+ @Override
+ public boolean requestScores(NetworkKey[] networks) {
+ // TODO(jjoslin): 12/13/16 - Implement
+ return false;
+ }
+
@Override
protected void dump(final FileDescriptor fd, final PrintWriter writer, final String[] args) {
mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);