Loading api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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"; } core/java/android/net/INetworkRecommendationProvider.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.net; import android.net.NetworkKey; import android.net.RecommendationRequest; import android.os.IRemoteCallback; Loading @@ -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 core/java/android/net/INetworkScoreService.aidl +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } core/java/android/net/NetworkRecommendationProvider.java +22 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,15 @@ public abstract class NetworkRecommendationProvider { public abstract void onRequestRecommendation(RecommendationRequest request, ResultCallback callback); /** * Invoked when network scores have been requested. * <p> * 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 <code>onBind()</code> method. Loading Loading @@ -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*/); Loading @@ -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); } Loading @@ -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(); } } } } core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java +51 −9 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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); Loading Loading @@ -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 Loading @@ -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(); } } } Loading
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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"; }
core/java/android/net/INetworkRecommendationProvider.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.net; import android.net.NetworkKey; import android.net.RecommendationRequest; import android.os.IRemoteCallback; Loading @@ -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
core/java/android/net/INetworkScoreService.aidl +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); }
core/java/android/net/NetworkRecommendationProvider.java +22 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,15 @@ public abstract class NetworkRecommendationProvider { public abstract void onRequestRecommendation(RecommendationRequest request, ResultCallback callback); /** * Invoked when network scores have been requested. * <p> * 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 <code>onBind()</code> method. Loading Loading @@ -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*/); Loading @@ -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); } Loading @@ -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(); } } } }
core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java +51 −9 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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); Loading Loading @@ -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 Loading @@ -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(); } } }