New internal interface method to get the active scorer metadata.
Returns the cached NetworkScorerAppData from the connected service. Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest Bug: 34773276 Change-Id: Ia8986e770c4ede0c0f7e2ad4f5bc0a0117a9ae2b
This commit is contained in:
@@ -18,6 +18,7 @@ package android.net;
|
||||
|
||||
import android.net.INetworkScoreCache;
|
||||
import android.net.NetworkKey;
|
||||
import android.net.NetworkScorerAppManager;
|
||||
import android.net.RecommendationRequest;
|
||||
import android.net.RecommendationResult;
|
||||
import android.net.ScoredNetwork;
|
||||
@@ -130,4 +131,6 @@ interface INetworkScoreService
|
||||
*/
|
||||
oneway void requestRecommendationAsync(in RecommendationRequest request,
|
||||
in RemoteCallback remoteCallback);
|
||||
|
||||
NetworkScorerAppManager.NetworkScorerAppData getActiveScorer();
|
||||
}
|
||||
|
||||
@@ -185,6 +185,20 @@ public class NetworkScoreManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns metadata about the active scorer or <code>null</code> if there is no active scorer.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Nullable
|
||||
public NetworkScorerAppData getActiveScorer() {
|
||||
try {
|
||||
return mService.getActiveScorer();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update network scores.
|
||||
*
|
||||
|
||||
19
core/java/android/net/NetworkScorerAppManager.aidl
Normal file
19
core/java/android/net/NetworkScorerAppManager.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2017, 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 NetworkScorerAppManager.NetworkScorerAppData;
|
||||
@@ -24,6 +24,8 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
@@ -54,7 +56,7 @@ public class NetworkScorerAppManager {
|
||||
/**
|
||||
* Holds metadata about a discovered network scorer/recommendation application.
|
||||
*/
|
||||
public static class NetworkScorerAppData {
|
||||
public static final class NetworkScorerAppData implements Parcelable {
|
||||
/** UID of the scorer app. */
|
||||
public final int packageUid;
|
||||
private final ComponentName mRecommendationService;
|
||||
@@ -64,6 +66,35 @@ public class NetworkScorerAppManager {
|
||||
this.mRecommendationService = recommendationServiceComp;
|
||||
}
|
||||
|
||||
protected NetworkScorerAppData(Parcel in) {
|
||||
packageUid = in.readInt();
|
||||
mRecommendationService = ComponentName.readFromParcel(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(packageUid);
|
||||
ComponentName.writeToParcel(mRecommendationService, dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<NetworkScorerAppData> CREATOR =
|
||||
new Creator<NetworkScorerAppData>() {
|
||||
@Override
|
||||
public NetworkScorerAppData createFromParcel(Parcel in) {
|
||||
return new NetworkScorerAppData(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkScorerAppData[] newArray(int size) {
|
||||
return new NetworkScorerAppData[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String getRecommendationServicePackageName() {
|
||||
return mRecommendationService.getPackageName();
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ 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;
|
||||
@@ -676,6 +677,10 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCallerSystemProcess(int callingUid) {
|
||||
return callingUid == Process.SYSTEM_UID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the package name of the current active network scorer.
|
||||
*
|
||||
@@ -692,6 +697,27 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns metadata about the active scorer or <code>null</code> if there is no active scorer.
|
||||
*/
|
||||
@Override
|
||||
public NetworkScorerAppData getActiveScorer() {
|
||||
// Only the system can access this data.
|
||||
if (isCallerSystemProcess(getCallingUid()) || callerCanRequestScores()) {
|
||||
synchronized (mServiceConnectionLock) {
|
||||
if (mServiceConnection != null) {
|
||||
return mServiceConnection.mAppData;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new SecurityException(
|
||||
"Caller is neither the system process nor a score requester.");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableScoring() {
|
||||
// Only the active scorer or the system should be allowed to disable scoring.
|
||||
|
||||
@@ -829,6 +829,50 @@ public class NetworkScoreServiceTest {
|
||||
assertEquals(expectedList, actualList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveScorer_notConnected_canRequestScores() throws Exception {
|
||||
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||
.thenReturn(PackageManager.PERMISSION_GRANTED);
|
||||
assertNull(mNetworkScoreService.getActiveScorer());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveScorer_notConnected_canNotRequestScores() throws Exception {
|
||||
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||
.thenReturn(PackageManager.PERMISSION_DENIED);
|
||||
try {
|
||||
mNetworkScoreService.getActiveScorer();
|
||||
fail("SecurityException expected.");
|
||||
} catch (SecurityException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveScorer_connected_canRequestScores()
|
||||
throws Exception {
|
||||
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||
.thenReturn(PackageManager.PERMISSION_GRANTED);
|
||||
NetworkScorerAppData expectedAppData =
|
||||
new NetworkScorerAppData(Binder.getCallingUid(), RECOMMENDATION_SERVICE_COMP);
|
||||
bindToScorer(expectedAppData);
|
||||
assertEquals(expectedAppData, mNetworkScoreService.getActiveScorer());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveScorer_connected_canNotRequestScores()
|
||||
throws Exception {
|
||||
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||
.thenReturn(PackageManager.PERMISSION_DENIED);
|
||||
bindToScorer(false);
|
||||
try {
|
||||
mNetworkScoreService.getActiveScorer();
|
||||
fail("SecurityException expected.");
|
||||
} catch (SecurityException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
// "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
|
||||
private void injectProvider() {
|
||||
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
|
||||
@@ -849,9 +893,13 @@ public class NetworkScoreServiceTest {
|
||||
}
|
||||
|
||||
private void bindToScorer(boolean callerIsScorer) {
|
||||
final int callingUid = callerIsScorer ? Binder.getCallingUid() : 0;
|
||||
final int callingUid = callerIsScorer ? Binder.getCallingUid() : Binder.getCallingUid() + 1;
|
||||
NetworkScorerAppData appData =
|
||||
new NetworkScorerAppData(callingUid, RECOMMENDATION_SERVICE_COMP);
|
||||
bindToScorer(appData);
|
||||
}
|
||||
|
||||
private void bindToScorer(NetworkScorerAppData appData) {
|
||||
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData);
|
||||
when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
|
||||
isA(UserHandle.class))).thenReturn(true);
|
||||
|
||||
Reference in New Issue
Block a user