Clear and restore the calling ID.
Clear and restore the calling identity in IPC methods after asserting
the caller has the required permissions.
Fixed 2 tests in NetworkScoreServiceTest that were failing due to a
recent refactor.
Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
BUG: 33781319
Change-Id: Icd79751d12dcfe4af8026980aaa1f7bd463468dc
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 0c21733..c64aa8e 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -40,7 +40,7 @@
import android.net.RecommendationResult;
import android.net.ScoredNetwork;
import android.net.Uri;
-import android.net.wifi.WifiConfiguration;
+import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
@@ -319,47 +319,54 @@
" is not the active scorer.");
}
- // Separate networks by type.
- Map<Integer, List<ScoredNetwork>> networksByType = new ArrayMap<>();
- for (ScoredNetwork network : networks) {
- List<ScoredNetwork> networkList = networksByType.get(network.networkKey.type);
- if (networkList == null) {
- networkList = new ArrayList<>();
- networksByType.put(network.networkKey.type, networkList);
- }
- networkList.add(network);
- }
-
- // Pass the scores of each type down to the appropriate network scorer.
- for (final Map.Entry<Integer, List<ScoredNetwork>> entry : networksByType.entrySet()) {
- final RemoteCallbackList<INetworkScoreCache> callbackList;
- final boolean isEmpty;
- synchronized (mScoreCaches) {
- callbackList = mScoreCaches.get(entry.getKey());
- isEmpty = callbackList == null || callbackList.getRegisteredCallbackCount() == 0;
- }
- if (isEmpty) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "No scorer registered for type " + entry.getKey() + ", discarding");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ // Separate networks by type.
+ Map<Integer, List<ScoredNetwork>> networksByType = new ArrayMap<>();
+ for (ScoredNetwork network : networks) {
+ List<ScoredNetwork> networkList = networksByType.get(network.networkKey.type);
+ if (networkList == null) {
+ networkList = new ArrayList<>();
+ networksByType.put(network.networkKey.type, networkList);
}
- continue;
+ networkList.add(network);
}
- sendCallback(new Consumer<INetworkScoreCache>() {
- @Override
- public void accept(INetworkScoreCache networkScoreCache) {
- try {
- networkScoreCache.updateScores(entry.getValue());
- } catch (RemoteException e) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Unable to update scores of type " + entry.getKey(), e);
+ // Pass the scores of each type down to the appropriate network scorer.
+ for (final Map.Entry<Integer, List<ScoredNetwork>> entry : networksByType.entrySet()) {
+ final RemoteCallbackList<INetworkScoreCache> callbackList;
+ final boolean isEmpty;
+ synchronized (mScoreCaches) {
+ callbackList = mScoreCaches.get(entry.getKey());
+ isEmpty = callbackList == null
+ || callbackList.getRegisteredCallbackCount() == 0;
+ }
+ if (isEmpty) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "No scorer registered for type " + entry.getKey()
+ + ", discarding");
+ }
+ continue;
+ }
+
+ sendCallback(new Consumer<INetworkScoreCache>() {
+ @Override
+ public void accept(INetworkScoreCache networkScoreCache) {
+ try {
+ networkScoreCache.updateScores(entry.getValue());
+ } catch (RemoteException e) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Unable to update scores of type " + entry.getKey(), e);
+ }
}
}
- }
- }, Collections.singleton(callbackList));
- }
+ }, Collections.singleton(callbackList));
+ }
- return true;
+ return true;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
@@ -369,8 +376,13 @@
if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) ||
mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
PackageManager.PERMISSION_GRANTED) {
- clearInternal();
- return true;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ clearInternal();
+ return true;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
} else {
throw new SecurityException(
"Caller is neither the active scorer nor the scorer manager.");
@@ -428,35 +440,46 @@
INetworkScoreCache scoreCache,
int filterType) {
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
- synchronized (mScoreCaches) {
- RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
- if (callbackList == null) {
- callbackList = new RemoteCallbackList<>();
- mScoreCaches.put(networkType, callbackList);
- }
- if (!callbackList.register(scoreCache, filterType)) {
- if (callbackList.getRegisteredCallbackCount() == 0) {
- mScoreCaches.remove(networkType);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mScoreCaches) {
+ RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
+ if (callbackList == null) {
+ callbackList = new RemoteCallbackList<>();
+ mScoreCaches.put(networkType, callbackList);
}
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Unable to register NetworkScoreCache for type " + networkType);
+ if (!callbackList.register(scoreCache, filterType)) {
+ if (callbackList.getRegisteredCallbackCount() == 0) {
+ mScoreCaches.remove(networkType);
+ }
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Unable to register NetworkScoreCache for type " + networkType);
+ }
}
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@Override
public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
- synchronized (mScoreCaches) {
- RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
- if (callbackList == null || !callbackList.unregister(scoreCache)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Unable to unregister NetworkScoreCache for type " + networkType);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mScoreCaches) {
+ RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
+ if (callbackList == null || !callbackList.unregister(scoreCache)) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Unable to unregister NetworkScoreCache for type "
+ + networkType);
+ }
+ } else if (callbackList.getRegisteredCallbackCount() == 0) {
+ mScoreCaches.remove(networkType);
}
- } else if (callbackList.getRegisteredCallbackCount() == 0) {
- mScoreCaches.remove(networkType);
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -464,43 +487,53 @@
public RecommendationResult requestRecommendation(RecommendationRequest request) {
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
throwIfCalledOnMainThread();
- final INetworkRecommendationProvider provider = getRecommendationProvider();
- if (provider != null) {
- try {
- return mRequestRecommendationCaller.getRecommendationResult(provider, request);
- } catch (RemoteException | TimeoutException e) {
- Log.w(TAG, "Failed to request a recommendation.", e);
- // TODO(jjoslin): 12/15/16 - Keep track of failures.
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final INetworkRecommendationProvider provider = getRecommendationProvider();
+ if (provider != null) {
+ try {
+ return mRequestRecommendationCaller.getRecommendationResult(provider, request);
+ } catch (RemoteException | TimeoutException e) {
+ Log.w(TAG, "Failed to request a recommendation.", e);
+ // TODO(jjoslin): 12/15/16 - Keep track of failures.
+ }
}
- }
- if (DBG) {
- Log.d(TAG, "Returning the default network recommendation.");
- }
+ if (DBG) {
+ Log.d(TAG, "Returning the default network recommendation.");
+ }
- if (request != null && request.getCurrentSelectedConfig() != null) {
- return RecommendationResult.createConnectRecommendation(
- request.getCurrentSelectedConfig());
+ if (request != null && request.getCurrentSelectedConfig() != null) {
+ return RecommendationResult.createConnectRecommendation(
+ request.getCurrentSelectedConfig());
+ }
+ return RecommendationResult.createDoNotConnectRecommendation();
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
- return RecommendationResult.createDoNotConnectRecommendation();
}
@Override
public boolean requestScores(NetworkKey[] networks) {
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
- final INetworkRecommendationProvider provider = getRecommendationProvider();
- if (provider != null) {
- try {
- provider.requestScores(networks);
- // TODO(jjoslin): 12/15/16 - Consider pushing null scores into the cache to prevent
- // repeated requests for the same scores.
- return true;
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to request scores.", e);
- // TODO(jjoslin): 12/15/16 - Keep track of failures.
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final INetworkRecommendationProvider provider = getRecommendationProvider();
+ if (provider != null) {
+ try {
+ provider.requestScores(networks);
+ // TODO(jjoslin): 12/15/16 - Consider pushing null scores into the cache to
+ // prevent repeated requests for the same scores.
+ return true;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to request scores.", e);
+ // TODO(jjoslin): 12/15/16 - Keep track of failures.
+ }
}
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
- return false;
}
@Override