4141import static android .net .NetworkPolicyManager .computeLastCycleBoundary ;
4242import static android .net .NetworkPolicyManager .dumpPolicy ;
4343import static android .net .NetworkPolicyManager .dumpRules ;
44- import static android .net .NetworkPolicyManager .isUidValidForPolicy ;
4544import static android .net .NetworkTemplate .MATCH_ETHERNET ;
4645import static android .net .NetworkTemplate .MATCH_MOBILE_3G_LOWER ;
4746import static android .net .NetworkTemplate .MATCH_MOBILE_4G ;
7473import android .content .IntentFilter ;
7574import android .content .pm .ApplicationInfo ;
7675import android .content .pm .PackageManager ;
76+ import android .content .pm .UserInfo ;
7777import android .content .res .Resources ;
7878import android .net .ConnectivityManager ;
7979import android .net .IConnectivityManager ;
9696import android .os .MessageQueue .IdleHandler ;
9797import android .os .RemoteCallbackList ;
9898import android .os .RemoteException ;
99+ import android .os .UserId ;
99100import android .provider .Settings ;
100101import android .telephony .TelephonyManager ;
101102import android .text .format .Formatter ;
@@ -158,6 +159,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
158159 private static final int VERSION_SPLIT_SNOOZE = 5 ;
159160 private static final int VERSION_ADDED_TIMEZONE = 6 ;
160161 private static final int VERSION_ADDED_INFERRED = 7 ;
162+ private static final int VERSION_SWITCH_APP_ID = 8 ;
161163
162164 // @VisibleForTesting
163165 public static final int TYPE_WARNING = 0x1 ;
@@ -167,6 +169,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
167169 private static final String TAG_POLICY_LIST = "policy-list" ;
168170 private static final String TAG_NETWORK_POLICY = "network-policy" ;
169171 private static final String TAG_UID_POLICY = "uid-policy" ;
172+ private static final String TAG_APP_POLICY = "app-policy" ;
170173
171174 private static final String ATTR_VERSION = "version" ;
172175 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground" ;
@@ -182,6 +185,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
182185 private static final String ATTR_METERED = "metered" ;
183186 private static final String ATTR_INFERRED = "inferred" ;
184187 private static final String ATTR_UID = "uid" ;
188+ private static final String ATTR_APP_ID = "appId" ;
185189 private static final String ATTR_POLICY = "policy" ;
186190
187191 private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground" ;
@@ -223,8 +227,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
223227 /** Currently active network rules for ifaces. */
224228 private HashMap <NetworkPolicy , String []> mNetworkRules = Maps .newHashMap ();
225229
226- /** Defined UID policies. */
227- private SparseIntArray mUidPolicy = new SparseIntArray ();
230+ /** Defined app policies. */
231+ private SparseIntArray mAppPolicy = new SparseIntArray ();
228232 /** Currently derived rules for each UID. */
229233 private SparseIntArray mUidRules = new SparseIntArray ();
230234
@@ -379,18 +383,26 @@ public void onReceive(Context context, Intent intent) {
379383
380384 final String action = intent .getAction ();
381385 final int uid = intent .getIntExtra (EXTRA_UID , 0 );
386+ final int appId = UserId .getAppId (uid );
382387 synchronized (mRulesLock ) {
383388 if (ACTION_PACKAGE_ADDED .equals (action )) {
389+ // NOTE: PACKAGE_ADDED is currently only sent once, and is
390+ // not broadcast when users are added.
391+
384392 // update rules for UID, since it might be subject to
385393 // global background data policy.
386394 if (LOGV ) Slog .v (TAG , "ACTION_PACKAGE_ADDED for uid=" + uid );
387- updateRulesForUidLocked ( uid );
395+ updateRulesForAppLocked ( appId );
388396
389397 } else if (ACTION_UID_REMOVED .equals (action )) {
398+ // NOTE: UID_REMOVED is currently only sent once, and is not
399+ // broadcast when users are removed.
400+
390401 // remove any policy and update rules to clean up.
391402 if (LOGV ) Slog .v (TAG , "ACTION_UID_REMOVED for uid=" + uid );
392- mUidPolicy .delete (uid );
393- updateRulesForUidLocked (uid );
403+
404+ mAppPolicy .delete (appId );
405+ updateRulesForAppLocked (appId );
394406 writePolicyLocked ();
395407 }
396408 }
@@ -949,7 +961,7 @@ private void readPolicyLocked() {
949961
950962 // clear any existing policy and read from disk
951963 mNetworkPolicy .clear ();
952- mUidPolicy .clear ();
964+ mAppPolicy .clear ();
953965
954966 FileInputStream fis = null ;
955967 try {
@@ -1028,11 +1040,21 @@ private void readPolicyLocked() {
10281040 final int uid = readIntAttribute (in , ATTR_UID );
10291041 final int policy = readIntAttribute (in , ATTR_POLICY );
10301042
1031- if (isUidValidForPolicy (mContext , uid )) {
1032- setUidPolicyUnchecked (uid , policy , false );
1043+ final int appId = UserId .getAppId (uid );
1044+ if (UserId .isApp (appId )) {
1045+ setAppPolicyUnchecked (appId , policy , false );
10331046 } else {
10341047 Slog .w (TAG , "unable to apply policy to UID " + uid + "; ignoring" );
10351048 }
1049+ } else if (TAG_APP_POLICY .equals (tag )) {
1050+ final int appId = readIntAttribute (in , ATTR_APP_ID );
1051+ final int policy = readIntAttribute (in , ATTR_POLICY );
1052+
1053+ if (UserId .isApp (appId )) {
1054+ setAppPolicyUnchecked (appId , policy , false );
1055+ } else {
1056+ Slog .w (TAG , "unable to apply policy to appId " + appId + "; ignoring" );
1057+ }
10361058 }
10371059 }
10381060 }
@@ -1077,7 +1099,7 @@ private void writePolicyLocked() {
10771099 out .startDocument (null , true );
10781100
10791101 out .startTag (null , TAG_POLICY_LIST );
1080- writeIntAttribute (out , ATTR_VERSION , VERSION_ADDED_INFERRED );
1102+ writeIntAttribute (out , ATTR_VERSION , VERSION_SWITCH_APP_ID );
10811103 writeBooleanAttribute (out , ATTR_RESTRICT_BACKGROUND , mRestrictBackground );
10821104
10831105 // write all known network policies
@@ -1102,17 +1124,17 @@ private void writePolicyLocked() {
11021124 }
11031125
11041126 // write all known uid policies
1105- for (int i = 0 ; i < mUidPolicy .size (); i ++) {
1106- final int uid = mUidPolicy .keyAt (i );
1107- final int policy = mUidPolicy .valueAt (i );
1127+ for (int i = 0 ; i < mAppPolicy .size (); i ++) {
1128+ final int appId = mAppPolicy .keyAt (i );
1129+ final int policy = mAppPolicy .valueAt (i );
11081130
11091131 // skip writing empty policies
11101132 if (policy == POLICY_NONE ) continue ;
11111133
1112- out .startTag (null , TAG_UID_POLICY );
1113- writeIntAttribute (out , ATTR_UID , uid );
1134+ out .startTag (null , TAG_APP_POLICY );
1135+ writeIntAttribute (out , ATTR_APP_ID , appId );
11141136 writeIntAttribute (out , ATTR_POLICY , policy );
1115- out .endTag (null , TAG_UID_POLICY );
1137+ out .endTag (null , TAG_APP_POLICY );
11161138 }
11171139
11181140 out .endTag (null , TAG_POLICY_LIST );
@@ -1127,36 +1149,36 @@ private void writePolicyLocked() {
11271149 }
11281150
11291151 @ Override
1130- public void setUidPolicy (int uid , int policy ) {
1152+ public void setAppPolicy (int appId , int policy ) {
11311153 mContext .enforceCallingOrSelfPermission (MANAGE_NETWORK_POLICY , TAG );
11321154
1133- if (!isUidValidForPolicy ( mContext , uid )) {
1134- throw new IllegalArgumentException ("cannot apply policy to UID " + uid );
1155+ if (!UserId . isApp ( appId )) {
1156+ throw new IllegalArgumentException ("cannot apply policy to appId " + appId );
11351157 }
11361158
1137- setUidPolicyUnchecked ( uid , policy , true );
1159+ setAppPolicyUnchecked ( appId , policy , true );
11381160 }
11391161
1140- private void setUidPolicyUnchecked (int uid , int policy , boolean persist ) {
1162+ private void setAppPolicyUnchecked (int appId , int policy , boolean persist ) {
11411163 final int oldPolicy ;
11421164 synchronized (mRulesLock ) {
1143- oldPolicy = getUidPolicy ( uid );
1144- mUidPolicy .put (uid , policy );
1165+ oldPolicy = getAppPolicy ( appId );
1166+ mAppPolicy .put (appId , policy );
11451167
11461168 // uid policy changed, recompute rules and persist policy.
1147- updateRulesForUidLocked ( uid );
1169+ updateRulesForAppLocked ( appId );
11481170 if (persist ) {
11491171 writePolicyLocked ();
11501172 }
11511173 }
11521174 }
11531175
11541176 @ Override
1155- public int getUidPolicy (int uid ) {
1177+ public int getAppPolicy (int appId ) {
11561178 mContext .enforceCallingOrSelfPermission (MANAGE_NETWORK_POLICY , TAG );
11571179
11581180 synchronized (mRulesLock ) {
1159- return mUidPolicy .get (uid , POLICY_NONE );
1181+ return mAppPolicy .get (appId , POLICY_NONE );
11601182 }
11611183 }
11621184
@@ -1347,27 +1369,29 @@ protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
13471369 fout .print (" " ); fout .println (policy .toString ());
13481370 }
13491371
1350- fout .println ("Policy status for known UIDs:" );
1372+ fout .println ("Policy for apps:" );
1373+ int size = mAppPolicy .size ();
1374+ for (int i = 0 ; i < size ; i ++) {
1375+ final int appId = mAppPolicy .keyAt (i );
1376+ final int policy = mAppPolicy .valueAt (i );
1377+ fout .print (" appId=" );
1378+ fout .print (appId );
1379+ fout .print (" policy=" );
1380+ dumpPolicy (fout , policy );
1381+ fout .println ();
1382+ }
13511383
13521384 final SparseBooleanArray knownUids = new SparseBooleanArray ();
1353- collectKeys (mUidPolicy , knownUids );
13541385 collectKeys (mUidForeground , knownUids );
13551386 collectKeys (mUidRules , knownUids );
13561387
1357- final int size = knownUids .size ();
1388+ fout .println ("Status for known UIDs:" );
1389+ size = knownUids .size ();
13581390 for (int i = 0 ; i < size ; i ++) {
13591391 final int uid = knownUids .keyAt (i );
13601392 fout .print (" UID=" );
13611393 fout .print (uid );
13621394
1363- fout .print (" policy=" );
1364- final int policyIndex = mUidPolicy .indexOfKey (uid );
1365- if (policyIndex < 0 ) {
1366- fout .print ("UNKNOWN" );
1367- } else {
1368- dumpPolicy (fout , mUidPolicy .valueAt (policyIndex ));
1369- }
1370-
13711395 fout .print (" foreground=" );
13721396 final int foregroundIndex = mUidPidForeground .indexOfKey (uid );
13731397 if (foregroundIndex < 0 ) {
@@ -1457,7 +1481,8 @@ private void updateRulesForRestrictBackgroundLocked() {
14571481 final PackageManager pm = mContext .getPackageManager ();
14581482 final List <ApplicationInfo > apps = pm .getInstalledApplications (0 );
14591483 for (ApplicationInfo app : apps ) {
1460- updateRulesForUidLocked (app .uid );
1484+ final int appId = UserId .getAppId (app .uid );
1485+ updateRulesForAppLocked (appId );
14611486 }
14621487
14631488 // and catch system UIDs
@@ -1476,13 +1501,21 @@ private void updateRulesForRestrictBackgroundLocked() {
14761501 }
14771502 }
14781503
1504+ private void updateRulesForAppLocked (int appId ) {
1505+ for (UserInfo user : mContext .getPackageManager ().getUsers ()) {
1506+ final int uid = UserId .getUid (user .id , appId );
1507+ updateRulesForUidLocked (uid );
1508+ }
1509+ }
1510+
14791511 private void updateRulesForUidLocked (int uid ) {
1480- final int uidPolicy = getUidPolicy (uid );
1512+ final int appId = UserId .getAppId (uid );
1513+ final int appPolicy = getAppPolicy (appId );
14811514 final boolean uidForeground = isUidForeground (uid );
14821515
14831516 // derive active rules based on policy and active state
14841517 int uidRules = RULE_ALLOW_ALL ;
1485- if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND ) != 0 ) {
1518+ if (!uidForeground && (appPolicy & POLICY_REJECT_METERED_BACKGROUND ) != 0 ) {
14861519 // uid in background, and policy says to block metered data
14871520 uidRules = RULE_REJECT_METERED ;
14881521 }
0 commit comments