Loading core/java/android/net/INetworkPolicyManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -78,4 +78,7 @@ interface INetworkPolicyManager { void factoryReset(String subscriber); boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork); byte[] getBackupPayload(); void applyRestore(in byte[] payload); } core/java/com/android/server/backup/NetworkPolicyBackupHelper.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Calyx Institute * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.backup; import android.app.backup.BlobBackupHelper; import android.content.Context; import android.net.INetworkPolicyManager; import android.os.ServiceManager; import android.util.Log; import android.util.Slog; public class NetworkPolicyBackupHelper extends BlobBackupHelper { private static final String TAG = "NetworkPolicyBackupHelper"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // Current version of the blob schema static final int BLOB_VERSION = 1; // Key under which the payload blob is stored static final String KEY_NETWORK_POLICY = "network_policy"; public NetworkPolicyBackupHelper() { super(BLOB_VERSION, KEY_NETWORK_POLICY); } @Override protected byte[] getBackupPayload(String key) { byte[] newPayload = null; if (KEY_NETWORK_POLICY.equals(key)) { try { INetworkPolicyManager npm = INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); newPayload = npm.getBackupPayload(); } catch (Exception e) { // Treat as no data Slog.e(TAG, "Couldn't communicate with network policy manager"); newPayload = null; } } return newPayload; } @Override protected void applyRestoredPayload(String key, byte[] payload) { if (DEBUG) { Slog.v(TAG, "Got restore of " + key); } if (KEY_NETWORK_POLICY.equals(key)) { try { INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)) .applyRestore(payload); } catch (Exception e) { Slog.e(TAG, "Couldn't communicate with network policy manager"); } } } } services/core/java/com/android/server/backup/SystemBackupAgent.java +2 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ public class SystemBackupAgent extends BackupAgentHelper { private static final String ACCOUNT_MANAGER_HELPER = "account_manager"; private static final String SLICES_HELPER = "slices"; private static final String PEOPLE_HELPER = "people"; private static final String NETWORK_POLICY_HELPER = "network_policy"; // These paths must match what the WallpaperManagerService uses. The leaf *_FILENAME // are also used in the full-backup file format, so must not change unless steps are Loading Loading @@ -101,6 +102,7 @@ public class SystemBackupAgent extends BackupAgentHelper { addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper()); addHelper(SLICES_HELPER, new SliceBackupHelper(this)); addHelper(PEOPLE_HELPER, new PeopleBackupHelper(mUserId)); addHelper(NETWORK_POLICY_HELPER, new NetworkPolicyBackupHelper()); } @Override Loading services/core/java/com/android/server/net/NetworkPolicyManagerService.java +347 −269 Original line number Diff line number Diff line Loading @@ -252,12 +252,16 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -375,6 +379,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final String ATTR_OWNER_PACKAGE = "ownerPackage"; private static final String ATTR_NETWORK_TYPES = "networkTypes"; private static final String ATTR_XML_UTILS_NAME = "name"; private static final String ATTR_USER_ID = "userId"; private static final String ACTION_ALLOW_BACKGROUND = "com.android.server.net.action.ALLOW_BACKGROUND"; Loading Loading @@ -2213,8 +2218,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { FileInputStream fis = null; try { fis = mPolicyFile.openRead(); readPolicyXml(fis, false); } catch (FileNotFoundException e) { // missing policy is okay, probably first boot upgradeDefaultBackgroundDataUL(); } catch (Exception e) { Log.wtf(TAG, "problem reading network policy", e); } finally { IoUtils.closeQuietly(fis); } } private void readPolicyXml(InputStream inputStream, boolean forRestore) throws IOException, XmlPullParserException { final XmlPullParser in = Xml.newPullParser(); in.setInput(fis, StandardCharsets.UTF_8.name()); in.setInput(inputStream, StandardCharsets.UTF_8.name()); // Must save the <restrict-background> tags and convert them to <uid-policy> later, // to skip UIDs that were explicitly blacklisted. Loading Loading @@ -2352,7 +2370,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan)); mSubscriptionPlansOwner.put(subId, ownerPackage); } else if (TAG_UID_POLICY.equals(tag)) { final int uid = readIntAttribute(in, ATTR_UID); int uid = readUidAttribute(in, forRestore); final int policy = readIntAttribute(in, ATTR_POLICY); if (UserHandle.isApp(uid)) { Loading @@ -2375,10 +2393,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } else if (TAG_WHITELIST.equals(tag)) { insideWhitelist = true; } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { final int uid = readIntAttribute(in, ATTR_UID); int uid = readUidAttribute(in, forRestore); whitelistedRestrictBackground.append(uid, true); } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { final int uid = readIntAttribute(in, ATTR_UID); int uid = readUidAttribute(in, forRestore); mRestrictBackgroundWhitelistRevokedUids.put(uid, true); } } else if (type == END_TAG) { Loading Loading @@ -2407,15 +2425,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Slog.w(TAG, "unable to update policy on UID " + uid); } } } catch (FileNotFoundException e) { // missing policy is okay, probably first boot upgradeDefaultBackgroundDataUL(); } catch (Exception e) { Log.wtf(TAG, "problem reading network policy", e); } finally { IoUtils.closeQuietly(fis); } } /** Loading Loading @@ -2482,9 +2491,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { FileOutputStream fos = null; try { fos = mPolicyFile.startWrite(); writePolicyXml(fos, false); mPolicyFile.finishWrite(fos); } catch (IOException e) { if (fos != null) { mPolicyFile.failWrite(fos); } } } private void writePolicyXml(OutputStream outputStream, boolean forBackup) throws IOException { XmlSerializer out = new FastXmlSerializer(); out.setOutput(fos, StandardCharsets.UTF_8.name()); out.setOutput(outputStream, StandardCharsets.UTF_8.name()); out.startDocument(null, true); out.startTag(null, TAG_POLICY_LIST); Loading Loading @@ -2562,7 +2580,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (policy == POLICY_NONE) continue; out.startTag(null, TAG_UID_POLICY); if (!forBackup) { writeIntAttribute(out, ATTR_UID, uid); } else { writeStringAttribute(out, ATTR_XML_UTILS_NAME, getPackageForUid(uid)); writeIntAttribute(out, ATTR_USER_ID, UserHandle.getUserId(uid)); } writeIntAttribute(out, ATTR_POLICY, policy); out.endTag(null, TAG_UID_POLICY); } Loading @@ -2577,19 +2600,55 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int i = 0; i < size; i++) { final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); if (!forBackup) { writeIntAttribute(out, ATTR_UID, uid); } else { writeStringAttribute(out, ATTR_XML_UTILS_NAME, getPackageForUid(uid)); writeIntAttribute(out, ATTR_USER_ID, UserHandle.getUserId(uid)); } out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); } out.endTag(null, TAG_WHITELIST); out.endDocument(); } mPolicyFile.finishWrite(fos); @Override public byte[] getBackupPayload() { enforceSystemCaller(); if (LOGD) Slog.d(TAG, "getBackupPayload"); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { writePolicyXml(baos, true); return baos.toByteArray(); } catch (IOException e) { if (fos != null) { mPolicyFile.failWrite(fos); Slog.w(TAG, "getBackupPayload: error writing payload", e); } return null; } @Override public void applyRestore(byte[] payload) { enforceSystemCaller(); if (LOGD) Slog.d(TAG, "applyRestore payload=" + (payload != null ? new String(payload, StandardCharsets.UTF_8) : null)); if (payload == null) { Slog.w(TAG, "applyRestore: no payload to restore"); return; } // clear any existing policy and read from disk mNetworkPolicy.clear(); mSubscriptionPlans.clear(); mSubscriptionPlansOwner.clear(); mUidPolicy.clear(); final ByteArrayInputStream bais = new ByteArrayInputStream(payload); try { readPolicyXml(bais, true); } catch (IOException | XmlPullParserException e) { Slog.w(TAG, "applyRestore: error reading payload", e); } } Loading Loading @@ -2801,6 +2860,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } private void enforceSystemCaller() { if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) { throw new SecurityException("Caller must be system"); } } @Override public void registerListener(INetworkPolicyListener listener) { // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps Loading Loading @@ -5493,6 +5558,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } private int readUidAttribute(XmlPullParser in, boolean forRestore) throws IOException { if (!forRestore) { return readIntAttribute(in, ATTR_UID); } else { return getUidForPackage(readStringAttribute(in, ATTR_XML_UTILS_NAME), readIntAttribute(in, ATTR_USER_ID)); } } private String getPackageForUid(int uid) { return mContext.getPackageManager().getPackagesForUid(uid)[0]; } private int getUidForPackage(String packageName, int userId) { try { return mContext.getPackageManager().getPackageUidAsUser(packageName, Loading Loading
core/java/android/net/INetworkPolicyManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -78,4 +78,7 @@ interface INetworkPolicyManager { void factoryReset(String subscriber); boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork); byte[] getBackupPayload(); void applyRestore(in byte[] payload); }
core/java/com/android/server/backup/NetworkPolicyBackupHelper.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Calyx Institute * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.backup; import android.app.backup.BlobBackupHelper; import android.content.Context; import android.net.INetworkPolicyManager; import android.os.ServiceManager; import android.util.Log; import android.util.Slog; public class NetworkPolicyBackupHelper extends BlobBackupHelper { private static final String TAG = "NetworkPolicyBackupHelper"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // Current version of the blob schema static final int BLOB_VERSION = 1; // Key under which the payload blob is stored static final String KEY_NETWORK_POLICY = "network_policy"; public NetworkPolicyBackupHelper() { super(BLOB_VERSION, KEY_NETWORK_POLICY); } @Override protected byte[] getBackupPayload(String key) { byte[] newPayload = null; if (KEY_NETWORK_POLICY.equals(key)) { try { INetworkPolicyManager npm = INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); newPayload = npm.getBackupPayload(); } catch (Exception e) { // Treat as no data Slog.e(TAG, "Couldn't communicate with network policy manager"); newPayload = null; } } return newPayload; } @Override protected void applyRestoredPayload(String key, byte[] payload) { if (DEBUG) { Slog.v(TAG, "Got restore of " + key); } if (KEY_NETWORK_POLICY.equals(key)) { try { INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)) .applyRestore(payload); } catch (Exception e) { Slog.e(TAG, "Couldn't communicate with network policy manager"); } } } }
services/core/java/com/android/server/backup/SystemBackupAgent.java +2 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ public class SystemBackupAgent extends BackupAgentHelper { private static final String ACCOUNT_MANAGER_HELPER = "account_manager"; private static final String SLICES_HELPER = "slices"; private static final String PEOPLE_HELPER = "people"; private static final String NETWORK_POLICY_HELPER = "network_policy"; // These paths must match what the WallpaperManagerService uses. The leaf *_FILENAME // are also used in the full-backup file format, so must not change unless steps are Loading Loading @@ -101,6 +102,7 @@ public class SystemBackupAgent extends BackupAgentHelper { addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper()); addHelper(SLICES_HELPER, new SliceBackupHelper(this)); addHelper(PEOPLE_HELPER, new PeopleBackupHelper(mUserId)); addHelper(NETWORK_POLICY_HELPER, new NetworkPolicyBackupHelper()); } @Override Loading
services/core/java/com/android/server/net/NetworkPolicyManagerService.java +347 −269 Original line number Diff line number Diff line Loading @@ -252,12 +252,16 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -375,6 +379,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final String ATTR_OWNER_PACKAGE = "ownerPackage"; private static final String ATTR_NETWORK_TYPES = "networkTypes"; private static final String ATTR_XML_UTILS_NAME = "name"; private static final String ATTR_USER_ID = "userId"; private static final String ACTION_ALLOW_BACKGROUND = "com.android.server.net.action.ALLOW_BACKGROUND"; Loading Loading @@ -2213,8 +2218,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { FileInputStream fis = null; try { fis = mPolicyFile.openRead(); readPolicyXml(fis, false); } catch (FileNotFoundException e) { // missing policy is okay, probably first boot upgradeDefaultBackgroundDataUL(); } catch (Exception e) { Log.wtf(TAG, "problem reading network policy", e); } finally { IoUtils.closeQuietly(fis); } } private void readPolicyXml(InputStream inputStream, boolean forRestore) throws IOException, XmlPullParserException { final XmlPullParser in = Xml.newPullParser(); in.setInput(fis, StandardCharsets.UTF_8.name()); in.setInput(inputStream, StandardCharsets.UTF_8.name()); // Must save the <restrict-background> tags and convert them to <uid-policy> later, // to skip UIDs that were explicitly blacklisted. Loading Loading @@ -2352,7 +2370,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan)); mSubscriptionPlansOwner.put(subId, ownerPackage); } else if (TAG_UID_POLICY.equals(tag)) { final int uid = readIntAttribute(in, ATTR_UID); int uid = readUidAttribute(in, forRestore); final int policy = readIntAttribute(in, ATTR_POLICY); if (UserHandle.isApp(uid)) { Loading @@ -2375,10 +2393,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } else if (TAG_WHITELIST.equals(tag)) { insideWhitelist = true; } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { final int uid = readIntAttribute(in, ATTR_UID); int uid = readUidAttribute(in, forRestore); whitelistedRestrictBackground.append(uid, true); } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { final int uid = readIntAttribute(in, ATTR_UID); int uid = readUidAttribute(in, forRestore); mRestrictBackgroundWhitelistRevokedUids.put(uid, true); } } else if (type == END_TAG) { Loading Loading @@ -2407,15 +2425,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Slog.w(TAG, "unable to update policy on UID " + uid); } } } catch (FileNotFoundException e) { // missing policy is okay, probably first boot upgradeDefaultBackgroundDataUL(); } catch (Exception e) { Log.wtf(TAG, "problem reading network policy", e); } finally { IoUtils.closeQuietly(fis); } } /** Loading Loading @@ -2482,9 +2491,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { FileOutputStream fos = null; try { fos = mPolicyFile.startWrite(); writePolicyXml(fos, false); mPolicyFile.finishWrite(fos); } catch (IOException e) { if (fos != null) { mPolicyFile.failWrite(fos); } } } private void writePolicyXml(OutputStream outputStream, boolean forBackup) throws IOException { XmlSerializer out = new FastXmlSerializer(); out.setOutput(fos, StandardCharsets.UTF_8.name()); out.setOutput(outputStream, StandardCharsets.UTF_8.name()); out.startDocument(null, true); out.startTag(null, TAG_POLICY_LIST); Loading Loading @@ -2562,7 +2580,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (policy == POLICY_NONE) continue; out.startTag(null, TAG_UID_POLICY); if (!forBackup) { writeIntAttribute(out, ATTR_UID, uid); } else { writeStringAttribute(out, ATTR_XML_UTILS_NAME, getPackageForUid(uid)); writeIntAttribute(out, ATTR_USER_ID, UserHandle.getUserId(uid)); } writeIntAttribute(out, ATTR_POLICY, policy); out.endTag(null, TAG_UID_POLICY); } Loading @@ -2577,19 +2600,55 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int i = 0; i < size; i++) { final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); if (!forBackup) { writeIntAttribute(out, ATTR_UID, uid); } else { writeStringAttribute(out, ATTR_XML_UTILS_NAME, getPackageForUid(uid)); writeIntAttribute(out, ATTR_USER_ID, UserHandle.getUserId(uid)); } out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); } out.endTag(null, TAG_WHITELIST); out.endDocument(); } mPolicyFile.finishWrite(fos); @Override public byte[] getBackupPayload() { enforceSystemCaller(); if (LOGD) Slog.d(TAG, "getBackupPayload"); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { writePolicyXml(baos, true); return baos.toByteArray(); } catch (IOException e) { if (fos != null) { mPolicyFile.failWrite(fos); Slog.w(TAG, "getBackupPayload: error writing payload", e); } return null; } @Override public void applyRestore(byte[] payload) { enforceSystemCaller(); if (LOGD) Slog.d(TAG, "applyRestore payload=" + (payload != null ? new String(payload, StandardCharsets.UTF_8) : null)); if (payload == null) { Slog.w(TAG, "applyRestore: no payload to restore"); return; } // clear any existing policy and read from disk mNetworkPolicy.clear(); mSubscriptionPlans.clear(); mSubscriptionPlansOwner.clear(); mUidPolicy.clear(); final ByteArrayInputStream bais = new ByteArrayInputStream(payload); try { readPolicyXml(bais, true); } catch (IOException | XmlPullParserException e) { Slog.w(TAG, "applyRestore: error reading payload", e); } } Loading Loading @@ -2801,6 +2860,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } private void enforceSystemCaller() { if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) { throw new SecurityException("Caller must be system"); } } @Override public void registerListener(INetworkPolicyListener listener) { // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps Loading Loading @@ -5493,6 +5558,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } private int readUidAttribute(XmlPullParser in, boolean forRestore) throws IOException { if (!forRestore) { return readIntAttribute(in, ATTR_UID); } else { return getUidForPackage(readStringAttribute(in, ATTR_XML_UTILS_NAME), readIntAttribute(in, ATTR_USER_ID)); } } private String getPackageForUid(int uid) { return mContext.getPackageManager().getPackagesForUid(uid)[0]; } private int getUidForPackage(String packageName, int userId) { try { return mContext.getPackageManager().getPackageUidAsUser(packageName, Loading