NetworkPolicyManagerService.java revision 9599cc5f21152860af9d18015b1398b50743da76
1d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey/* 2d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project 3d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * 4d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * you may not use this file except in compliance with the License. 6d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * You may obtain a copy of the License at 7d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * 8d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * 10d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * See the License for the specific language governing permissions and 14d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * limitations under the License. 15d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 16d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 17d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeypackage com.android.server.net; 18d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 191b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.Manifest.permission.DUMP; 20d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport static android.Manifest.permission.MANAGE_APP_TOKENS; 21d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport static android.Manifest.permission.UPDATE_DEVICE_STATS; 22d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_NONE; 23c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND; 24c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 25c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_REJECT_PAID; 261b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpPolicy; 271b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpRules; 28d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 29a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IActivityManager; 30a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IProcessObserver; 31a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.BroadcastReceiver; 32d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.content.Context; 33a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.Intent; 34a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.IntentFilter; 35c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.ConnectivityManager; 36c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyListener; 37d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.net.INetworkPolicyManager; 38a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.IPowerManager; 39c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.os.RemoteCallbackList; 40a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.RemoteException; 41d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.Log; 42a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.util.Slog; 43d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseArray; 44d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseBooleanArray; 45d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseIntArray; 46d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 471b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.FileDescriptor; 481b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.PrintWriter; 491b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 50d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey/** 51d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Service that maintains low-level network policy rules and collects usage 52d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * statistics to drive those rules. 53c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * <p> 54c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * Derives active rules by combining a given policy with other system status, 55c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * and delivers to listeners, such as {@link ConnectivityManager}, for 56c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * enforcement. 57d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 58d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeypublic class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 59d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private static final String TAG = "NetworkPolicy"; 60d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private static final boolean LOGD = true; 61d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 62d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private Context mContext; 63a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private IActivityManager mActivityManager; 64a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private IPowerManager mPowerManager; 65a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 66a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private Object mRulesLock = new Object(); 67a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 68c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private boolean mScreenOn; 69d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 70d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** Current network policy for each UID. */ 71a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseIntArray mUidPolicy = new SparseIntArray(); 72c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey /** Current derived network rules for each UID. */ 73c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private SparseIntArray mUidRules = new SparseIntArray(); 74d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 75d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** Foreground at both UID and PID granularity. */ 76a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseBooleanArray mUidForeground = new SparseBooleanArray(); 77a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseArray<SparseBooleanArray> mUidPidForeground = new SparseArray< 78a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey SparseBooleanArray>(); 79d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 80c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private final RemoteCallbackList<INetworkPolicyListener> mListeners = new RemoteCallbackList< 81c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey INetworkPolicyListener>(); 82c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 83d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // TODO: periodically poll network stats and write to disk 84d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // TODO: save/restore policy information from disk 85d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 86c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: keep whitelist of system-critical services that should never have 87c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // rules enforced, such as system, phone, and radio UIDs. 88c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 89a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public NetworkPolicyManagerService( 90a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey Context context, IActivityManager activityManager, IPowerManager powerManager) { 91a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext = checkNotNull(context, "missing context"); 92a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager = checkNotNull(activityManager, "missing activityManager"); 93a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mPowerManager = checkNotNull(powerManager, "missing powerManager"); 94a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 95d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 96a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void systemReady() { 97a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // TODO: read current policy+stats from disk and generate NMS rules 98d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 99a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateScreenOn(); 100d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 101a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 102a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager.registerProcessObserver(mProcessObserver); 103a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 104a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // ouch, no foregroundActivities updates means some processes may 105a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // never get network access. 106a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey Slog.e(TAG, "unable to register IProcessObserver", e); 107a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 108d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 109a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // TODO: traverse existing processes to know foreground state, or have 110a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // activitymanager dispatch current state when new observer attached. 111d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 112a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final IntentFilter screenFilter = new IntentFilter(); 113a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_ON); 114a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 115a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext.registerReceiver(mScreenReceiver, screenFilter); 116d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 117a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final IntentFilter shutdownFilter = new IntentFilter(); 118a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey shutdownFilter.addAction(Intent.ACTION_SHUTDOWN); 119a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext.registerReceiver(mShutdownReceiver, shutdownFilter); 120d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 121a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 122d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 123a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 124a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 125a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 126a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only someone like AMS should only be calling us 127a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext.enforceCallingOrSelfPermission( 128a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey MANAGE_APP_TOKENS, "requires MANAGE_APP_TOKENS permission"); 129a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 130a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 131a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // because a uid can have multiple pids running inside, we need to 132a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // remember all pid states and summarize foreground at uid level. 133a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 134a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // record foreground for this specific pid 135a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 136a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (pidForeground == null) { 137a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground = new SparseBooleanArray(2); 138a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mUidPidForeground.put(uid, pidForeground); 139a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 140a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground.put(pid, foregroundActivities); 141a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey computeUidForegroundL(uid); 142a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 143d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 144d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 145a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 146a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onProcessDied(int pid, int uid) { 147a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only someone like AMS should only be calling us 148a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext.enforceCallingOrSelfPermission( 149a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey MANAGE_APP_TOKENS, "requires MANAGE_APP_TOKENS permission"); 150a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 151a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 152a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // clear records and recompute, when they exist 153a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 154a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (pidForeground != null) { 155a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground.delete(pid); 156a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey computeUidForegroundL(uid); 157a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 158a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 159a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 160a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 161a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 162a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 163a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 164a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onReceive(Context context, Intent intent) { 165a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 166a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // screen-related broadcasts are protected by system, no need 167a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // for permissions check. 168a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateScreenOn(); 169a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 170a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 171a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 172d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 173a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() { 174a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 175a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onReceive(Context context, Intent intent) { 176a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // TODO: persist any pending stats during clean shutdown 177a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey Log.d(TAG, "persisting stats"); 178d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 179a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 180d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 181d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 182d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey public void setUidPolicy(int uid, int policy) { 183c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: create permission for modifying data policy 184d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey mContext.enforceCallingOrSelfPermission( 185d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey UPDATE_DEVICE_STATS, "requires UPDATE_DEVICE_STATS permission"); 186a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 187c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int oldPolicy; 188a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 189c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey oldPolicy = getUidPolicy(uid); 190a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mUidPolicy.put(uid, policy); 1919599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey updateRulesForUidL(uid); 192a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 193c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 194c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: consider dispatching BACKGROUND_DATA_SETTING broadcast 195d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 196d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 197d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 198d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey public int getUidPolicy(int uid) { 199a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 200a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey return mUidPolicy.get(uid, POLICY_NONE); 201a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 202d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 203d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 204c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 205c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void registerListener(INetworkPolicyListener listener) { 206c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.register(listener); 207c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 208c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey synchronized (mRulesLock) { 209c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch any existing rules to new listeners 210c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int size = mUidRules.size(); 211c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey for (int i = 0; i < size; i++) { 212c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int uid = mUidRules.keyAt(i); 213c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int uidRules = mUidRules.valueAt(i); 214c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (uidRules != RULE_ALLOW_ALL) { 215c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey try { 216c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey listener.onRulesChanged(uid, uidRules); 217c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } catch (RemoteException e) { 218c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 219c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 220c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 221c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 222c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 223c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 224c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 225c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void unregisterListener(INetworkPolicyListener listener) { 226c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.unregister(listener); 227c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 228c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 2291b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey @Override 2301b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 2311b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey mContext.enforceCallingOrSelfPermission(DUMP, "requires DUMP permission"); 2321b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2331b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey synchronized (mRulesLock) { 2341b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println("Policy status for known UIDs:"); 2351b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2361b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final SparseBooleanArray knownUids = new SparseBooleanArray(); 2371b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidPolicy, knownUids); 2381b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidForeground, knownUids); 2391b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidRules, knownUids); 2401b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2411b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = knownUids.size(); 2421b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 2431b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int uid = knownUids.keyAt(i); 2441b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" UID="); 2451b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(uid); 2461b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2471b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" policy="); 2481b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int policyIndex = mUidPolicy.indexOfKey(uid); 2491b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (policyIndex < 0) { 2501b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 2511b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 2521b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpPolicy(fout, mUidPolicy.valueAt(policyIndex)); 2531b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2541b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2551b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" foreground="); 2561b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int foregroundIndex = mUidPidForeground.indexOfKey(uid); 2571b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (foregroundIndex < 0) { 2581b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 2591b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 2601b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpSparseBooleanArray(fout, mUidPidForeground.valueAt(foregroundIndex)); 2611b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2621b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2631b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" rules="); 2641b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int rulesIndex = mUidRules.indexOfKey(uid); 2651b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (rulesIndex < 0) { 2661b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 2671b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 2681b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpRules(fout, mUidRules.valueAt(rulesIndex)); 2691b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2701b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2711b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println(); 2721b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2759599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey 2769599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey @Override 2779599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey public boolean isUidForeground(int uid) { 2789599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey synchronized (mRulesLock) { 2799599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey // only really in foreground when screen is also on 2809599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey return mUidForeground.get(uid, false) && mScreenOn; 2819599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey } 282c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 283c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 284d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** 285d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Foreground for PID changed; recompute foreground at UID level. If 286a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey * changed, will trigger {@link #updateRulesForUidL(int)}. 287d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 288a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void computeUidForegroundL(int uid) { 289d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 290d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 291d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // current pid is dropping foreground; examine other pids 292d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey boolean uidForeground = false; 293d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int size = pidForeground.size(); 294d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey for (int i = 0; i < size; i++) { 295d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (pidForeground.valueAt(i)) { 296d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey uidForeground = true; 297d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey break; 298d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 299d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 300d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 301d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final boolean oldUidForeground = mUidForeground.get(uid, false); 302d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (oldUidForeground != uidForeground) { 303d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // foreground changed, push updated rules 304d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey mUidForeground.put(uid, uidForeground); 305a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateRulesForUidL(uid); 306a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 307a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 308a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 309a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateScreenOn() { 310a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 311a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 312a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mScreenOn = mPowerManager.isScreenOn(); 313a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 314a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 315a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateRulesForScreenL(); 316d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 317d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 318d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 319a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey /** 320a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey * Update rules that might be changed by {@link #mScreenOn} value. 321a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey */ 322a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateRulesForScreenL() { 323a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only update rules for anyone with foreground activities 324a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int size = mUidForeground.size(); 325a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey for (int i = 0; i < size; i++) { 326a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (mUidForeground.valueAt(i)) { 327a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int uid = mUidForeground.keyAt(i); 328a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateRulesForUidL(uid); 329a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 330a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 331a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 332a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 333a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateRulesForUidL(int uid) { 334d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int uidPolicy = getUidPolicy(uid); 3359599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey final boolean uidForeground = isUidForeground(uid); 336d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 337c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // derive active rules based on policy and active state 338c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey int uidRules = RULE_ALLOW_ALL; 339c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (!uidForeground && (uidPolicy & POLICY_REJECT_PAID_BACKGROUND) != 0) { 340c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // uid in background, and policy says to block paid data 341c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey uidRules = RULE_REJECT_PAID; 342d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 343d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 344c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: only dispatch when rules actually change 345c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 346c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // record rule locally to dispatch to new listeners 347c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mUidRules.put(uid, uidRules); 348c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 349c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch changed rule to existing listeners 350c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int length = mListeners.beginBroadcast(); 351c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey for (int i = 0; i < length; i++) { 352c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 353c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (listener != null) { 354c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey try { 355c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey listener.onRulesChanged(uid, uidRules); 356c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } catch (RemoteException e) { 357c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 358c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 359d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 360c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.finishBroadcast(); 361d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 362d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 363a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private static <T> T checkNotNull(T value, String message) { 364a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (value == null) { 365a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey throw new NullPointerException(message); 366a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 367a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey return value; 368a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 3691b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 3701b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 3711b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 3721b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 3731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 3741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3751b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3761b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 3771b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseBooleanArray source, SparseBooleanArray target) { 3781b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 3791b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 3801b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 3811b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3821b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3831b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 3841b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void dumpSparseBooleanArray(PrintWriter fout, SparseBooleanArray value) { 3851b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("["); 3861b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = value.size(); 3871b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 3881b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(value.keyAt(i) + "=" + value.valueAt(i)); 3891b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (i < size - 1) fout.print(","); 3901b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3911b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("]"); 3921b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 393d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey} 394