252252import org .xmlpull .v1 .XmlPullParserException ;
253253import org .xmlpull .v1 .XmlSerializer ;
254254
255+ import java .io .ByteArrayInputStream ;
256+ import java .io .ByteArrayOutputStream ;
255257import java .io .File ;
256258import java .io .FileDescriptor ;
257259import java .io .FileInputStream ;
@@ -377,6 +379,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
377379 private static final String ATTR_OWNER_PACKAGE = "ownerPackage" ;
378380 private static final String ATTR_NETWORK_TYPES = "networkTypes" ;
379381 private static final String ATTR_XML_UTILS_NAME = "name" ;
382+ private static final String ATTR_USER_ID = "userId" ;
380383
381384 private static final String ACTION_ALLOW_BACKGROUND =
382385 "com.android.server.net.action.ALLOW_BACKGROUND" ;
@@ -2233,7 +2236,7 @@ private void readPolicyAL() {
22332236 FileInputStream fis = null ;
22342237 try {
22352238 fis = mPolicyFile .openRead ();
2236- readPolicyXml (fis );
2239+ readPolicyXml (fis , false );
22372240 } catch (FileNotFoundException e ) {
22382241 // missing policy is okay, probably first boot
22392242 upgradeDefaultBackgroundDataUL ();
@@ -2244,7 +2247,7 @@ private void readPolicyAL() {
22442247 }
22452248 }
22462249
2247- private void readPolicyXml (InputStream inputStream ) {
2250+ private void readPolicyXml (InputStream inputStream , boolean forRestore ) throws IOException , XmlPullParserException {
22482251 final XmlPullParser in = Xml .newPullParser ();
22492252 in .setInput (inputStream , StandardCharsets .UTF_8 .name ());
22502253
@@ -2384,7 +2387,12 @@ private void readPolicyXml(InputStream inputStream) {
23842387 SubscriptionPlan .class , mSubscriptionPlans .get (subId ), plan ));
23852388 mSubscriptionPlansOwner .put (subId , ownerPackage );
23862389 } else if (TAG_UID_POLICY .equals (tag )) {
2387- final int uid = readIntAttribute (in , ATTR_UID );
2390+ int uid ;
2391+ if (!forRestore ) {
2392+ uid = readIntAttribute (in , ATTR_UID );
2393+ } else {
2394+ uid = getUidForPackage (readStringAttribute (in , ATTR_XML_UTILS_NAME ), readIntAttribute (in , ATTR_USER_ID ));
2395+ }
23882396 final int policy = readIntAttribute (in , ATTR_POLICY );
23892397
23902398 if (UserHandle .isApp (uid )) {
@@ -2407,10 +2415,20 @@ private void readPolicyXml(InputStream inputStream) {
24072415 } else if (TAG_WHITELIST .equals (tag )) {
24082416 insideWhitelist = true ;
24092417 } else if (TAG_RESTRICT_BACKGROUND .equals (tag ) && insideWhitelist ) {
2410- final int uid = readIntAttribute (in , ATTR_UID );
2418+ int uid ;
2419+ if (!forRestore ) {
2420+ uid = readIntAttribute (in , ATTR_UID );
2421+ } else {
2422+ uid = getUidForPackage (readStringAttribute (in , ATTR_XML_UTILS_NAME ), readIntAttribute (in , ATTR_USER_ID ));
2423+ }
24112424 whitelistedRestrictBackground .append (uid , true );
24122425 } else if (TAG_REVOKED_RESTRICT_BACKGROUND .equals (tag ) && insideWhitelist ) {
2413- final int uid = readIntAttribute (in , ATTR_UID );
2426+ int uid ;
2427+ if (!forRestore ) {
2428+ uid = readIntAttribute (in , ATTR_UID );
2429+ } else {
2430+ uid = getUidForPackage (readStringAttribute (in , ATTR_XML_UTILS_NAME ), readIntAttribute (in , ATTR_USER_ID ));
2431+ }
24142432 mRestrictBackgroundWhitelistRevokedUids .put (uid , true );
24152433 }
24162434 } else if (type == END_TAG ) {
@@ -2506,7 +2524,7 @@ void writePolicyAL() {
25062524 try {
25072525 fos = mPolicyFile .startWrite ();
25082526
2509- writePolicyXml (fos );
2527+ writePolicyXml (fos , false );
25102528
25112529 mPolicyFile .finishWrite (fos );
25122530 } catch (IOException e ) {
@@ -2516,7 +2534,7 @@ void writePolicyAL() {
25162534 }
25172535 }
25182536
2519- private void writePolicyXml (OutputStream outputStream ) {
2537+ private void writePolicyXml (OutputStream outputStream , boolean forBackup ) throws IOException {
25202538 XmlSerializer out = new FastXmlSerializer ();
25212539 out .setOutput (outputStream , StandardCharsets .UTF_8 .name ());
25222540 out .startDocument (null , true );
@@ -2596,7 +2614,13 @@ private void writePolicyXml(OutputStream outputStream) {
25962614 if (policy == POLICY_NONE ) continue ;
25972615
25982616 out .startTag (null , TAG_UID_POLICY );
2599- writeIntAttribute (out , ATTR_UID , uid );
2617+
2618+ if (!forBackup ) {
2619+ writeIntAttribute (out , ATTR_UID , uid );
2620+ } else {
2621+ writeStringAttribute (out , ATTR_XML_UTILS_NAME , getPackageForUid (uid ));
2622+ writeIntAttribute (out , ATTR_USER_ID , UserHandle .getUserId (uid ));
2623+ }
26002624 writeIntAttribute (out , ATTR_POLICY , policy );
26012625 out .endTag (null , TAG_UID_POLICY );
26022626 }
@@ -2611,7 +2635,12 @@ private void writePolicyXml(OutputStream outputStream) {
26112635 for (int i = 0 ; i < size ; i ++) {
26122636 final int uid = mRestrictBackgroundWhitelistRevokedUids .keyAt (i );
26132637 out .startTag (null , TAG_REVOKED_RESTRICT_BACKGROUND );
2614- writeIntAttribute (out , ATTR_UID , uid );
2638+ if (!forBackup ) {
2639+ writeIntAttribute (out , ATTR_UID , uid );
2640+ } else {
2641+ writeStringAttribute (out , ATTR_XML_UTILS_NAME , getPackageForUid (uid ));
2642+ writeIntAttribute (out , ATTR_USER_ID , UserHandle .getUserId (uid ));
2643+ }
26152644 out .endTag (null , TAG_REVOKED_RESTRICT_BACKGROUND );
26162645 }
26172646
@@ -2620,6 +2649,44 @@ private void writePolicyXml(OutputStream outputStream) {
26202649 out .endDocument ();
26212650 }
26222651
2652+ @ Override
2653+ public byte [] getBackupPayload () {
2654+ enforceSystemCaller ();
2655+ if (LOGD ) Slog .d (TAG , "getBackupPayload" );
2656+ final ByteArrayOutputStream baos = new ByteArrayOutputStream ();
2657+ try {
2658+ writePolicyXml (baos , true );
2659+ return baos .toByteArray ();
2660+ } catch (IOException e ) {
2661+ Slog .w (TAG , "getBackupPayload: error writing payload" , e );
2662+ }
2663+ return null ;
2664+ }
2665+
2666+ @ Override
2667+ public void applyRestore (byte [] payload ) {
2668+ enforceSystemCaller ();
2669+ if (LOGD ) Slog .d (TAG , "applyRestore payload="
2670+ + (payload != null ? new String (payload , StandardCharsets .UTF_8 ) : null ));
2671+ if (payload == null ) {
2672+ Slog .w (TAG , "applyRestore: no payload to restore" );
2673+ return ;
2674+ }
2675+
2676+ // clear any existing policy and read from disk
2677+ mNetworkPolicy .clear ();
2678+ mSubscriptionPlans .clear ();
2679+ mSubscriptionPlansOwner .clear ();
2680+ mUidPolicy .clear ();
2681+
2682+ final ByteArrayInputStream bais = new ByteArrayInputStream (payload );
2683+ try {
2684+ readPolicyXml (bais , true );
2685+ } catch (IOException | XmlPullParserException e ) {
2686+ Slog .w (TAG , "applyRestore: error reading payload" , e );
2687+ }
2688+ }
2689+
26232690 @ Override
26242691 public void setUidPolicy (int uid , int policy ) {
26252692 mContext .enforceCallingOrSelfPermission (MANAGE_NETWORK_POLICY , TAG );
@@ -2828,6 +2895,12 @@ private void enforceAnyPermissionOf(String... permissions) {
28282895 }
28292896 }
28302897
2898+ private void enforceSystemCaller () {
2899+ if (Binder .getCallingUid () != android .os .Process .SYSTEM_UID ) {
2900+ throw new SecurityException ("Caller must be system" );
2901+ }
2902+ }
2903+
28312904 @ Override
28322905 public void registerListener (INetworkPolicyListener listener ) {
28332906 // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
@@ -5522,6 +5595,10 @@ private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int
55225595 }
55235596 }
55245597
5598+ private String getPackageForUid (int uid ) {
5599+ return mContext .getPackageManager ().getPackagesForUid (uid )[0 ];
5600+ }
5601+
55255602 private int getUidForPackage (String packageName , int userId ) {
55265603 try {
55275604 return mContext .getPackageManager ().getPackageUidAsUser (packageName ,
0 commit comments