NetworkPolicyManagerService.java revision 1b861278a2051f53ce7955fb7992fa536dc975d9
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); 191a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 192c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 193c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: consider dispatching BACKGROUND_DATA_SETTING broadcast 194d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 195d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 196d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 197d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey public int getUidPolicy(int uid) { 198a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 199a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey return mUidPolicy.get(uid, POLICY_NONE); 200a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 201d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 202d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 203c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 204c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void registerListener(INetworkPolicyListener listener) { 205c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.register(listener); 206c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 207c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey synchronized (mRulesLock) { 208c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch any existing rules to new listeners 209c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int size = mUidRules.size(); 210c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey for (int i = 0; i < size; i++) { 211c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int uid = mUidRules.keyAt(i); 212c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int uidRules = mUidRules.valueAt(i); 213c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (uidRules != RULE_ALLOW_ALL) { 214c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey try { 215c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey listener.onRulesChanged(uid, uidRules); 216c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } catch (RemoteException e) { 217c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 218c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 219c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 220c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 221c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 222c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 223c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 224c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void unregisterListener(INetworkPolicyListener listener) { 225c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.unregister(listener); 226c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 227c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 2281b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey @Override 2291b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 2301b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey mContext.enforceCallingOrSelfPermission(DUMP, "requires DUMP permission"); 2311b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2321b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey synchronized (mRulesLock) { 2331b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println("Policy status for known UIDs:"); 2341b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2351b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final SparseBooleanArray knownUids = new SparseBooleanArray(); 2361b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidPolicy, knownUids); 2371b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidForeground, knownUids); 2381b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidRules, knownUids); 2391b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2401b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = knownUids.size(); 2411b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 2421b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int uid = knownUids.keyAt(i); 2431b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" UID="); 2441b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(uid); 2451b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2461b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" policy="); 2471b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int policyIndex = mUidPolicy.indexOfKey(uid); 2481b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (policyIndex < 0) { 2491b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 2501b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 2511b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpPolicy(fout, mUidPolicy.valueAt(policyIndex)); 2521b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2531b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2541b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" foreground="); 2551b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int foregroundIndex = mUidPidForeground.indexOfKey(uid); 2561b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (foregroundIndex < 0) { 2571b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 2581b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 2591b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpSparseBooleanArray(fout, mUidPidForeground.valueAt(foregroundIndex)); 2601b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2611b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2621b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" rules="); 2631b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int rulesIndex = mUidRules.indexOfKey(uid); 2641b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (rulesIndex < 0) { 2651b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 2661b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 2671b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpRules(fout, mUidRules.valueAt(rulesIndex)); 2681b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2691b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 2701b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println(); 2711b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2721b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 2741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 275c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private boolean isUidForegroundL(int uid) { 276c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // only really in foreground when screen is also on 277c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey return mUidForeground.get(uid, false) && mScreenOn; 278c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 279c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 280d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** 281d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Foreground for PID changed; recompute foreground at UID level. If 282a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey * changed, will trigger {@link #updateRulesForUidL(int)}. 283d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 284a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void computeUidForegroundL(int uid) { 285d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 286d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 287d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // current pid is dropping foreground; examine other pids 288d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey boolean uidForeground = false; 289d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int size = pidForeground.size(); 290d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey for (int i = 0; i < size; i++) { 291d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (pidForeground.valueAt(i)) { 292d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey uidForeground = true; 293d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey break; 294d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 295d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 296d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 297d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final boolean oldUidForeground = mUidForeground.get(uid, false); 298d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (oldUidForeground != uidForeground) { 299d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // foreground changed, push updated rules 300d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey mUidForeground.put(uid, uidForeground); 301a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateRulesForUidL(uid); 302a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 303a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 304a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 305a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateScreenOn() { 306a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 307a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 308a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mScreenOn = mPowerManager.isScreenOn(); 309a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 310a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 311a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateRulesForScreenL(); 312d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 313d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 314d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 315a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey /** 316a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey * Update rules that might be changed by {@link #mScreenOn} value. 317a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey */ 318a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateRulesForScreenL() { 319a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only update rules for anyone with foreground activities 320a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int size = mUidForeground.size(); 321a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey for (int i = 0; i < size; i++) { 322a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (mUidForeground.valueAt(i)) { 323a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int uid = mUidForeground.keyAt(i); 324a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateRulesForUidL(uid); 325a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 326a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 327a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 328a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 329a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateRulesForUidL(int uid) { 330d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int uidPolicy = getUidPolicy(uid); 331c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final boolean uidForeground = isUidForegroundL(uid); 332d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 333c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // derive active rules based on policy and active state 334c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey int uidRules = RULE_ALLOW_ALL; 335c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (!uidForeground && (uidPolicy & POLICY_REJECT_PAID_BACKGROUND) != 0) { 336c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // uid in background, and policy says to block paid data 337c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey uidRules = RULE_REJECT_PAID; 338d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 339d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 340c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: only dispatch when rules actually change 341c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 342c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // record rule locally to dispatch to new listeners 343c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mUidRules.put(uid, uidRules); 344c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 345c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch changed rule to existing listeners 346c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int length = mListeners.beginBroadcast(); 347c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey for (int i = 0; i < length; i++) { 348c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 349c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (listener != null) { 350c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey try { 351c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey listener.onRulesChanged(uid, uidRules); 352c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } catch (RemoteException e) { 353c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 354c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 355d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 356c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.finishBroadcast(); 357d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 358d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 359a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private static <T> T checkNotNull(T value, String message) { 360a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (value == null) { 361a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey throw new NullPointerException(message); 362a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 363a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey return value; 364a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 3651b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 3661b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 3671b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 3681b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 3691b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 3701b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3711b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3721b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 3731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseBooleanArray source, SparseBooleanArray target) { 3741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 3751b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 3761b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 3771b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3781b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3791b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 3801b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void dumpSparseBooleanArray(PrintWriter fout, SparseBooleanArray value) { 3811b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("["); 3821b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = value.size(); 3831b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 3841b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(value.keyAt(i) + "=" + value.valueAt(i)); 3851b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (i < size - 1) fout.print(","); 3861b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 3871b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("]"); 3881b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 389d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey} 390