OSDN Git Service

RESTRICT AUTOMERGE
[android-x86/frameworks-base.git] / services / companion / java / com / android / server / companion / CompanionDeviceManagerService.java
index f47b0d3..bf2b83b 100644 (file)
@@ -21,6 +21,7 @@ import static com.android.internal.util.CollectionUtils.size;
 import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
 
 import android.Manifest;
 import android.annotation.CheckResult;
@@ -57,6 +58,7 @@ import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.SettingsStringUtil.ComponentNameSet;
 import android.text.BidiFormatter;
+import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.ExceptionUtils;
 import android.util.Log;
@@ -68,6 +70,7 @@ import com.android.internal.content.PackageMonitor;
 import com.android.internal.notification.NotificationAccessConfirmationActivityContract;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
 import com.android.server.SystemService;
 
@@ -83,6 +86,7 @@ import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
@@ -247,9 +251,9 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
                 throws RemoteException {
             checkCallerIsSystemOr(callingPackage, userId);
             checkUsesFeature(callingPackage, getCallingUserId());
-            return CollectionUtils.map(
+            return new ArrayList<>(CollectionUtils.map(
                     readAllAssociations(userId, callingPackage),
-                    a -> a.deviceAddress);
+                    a -> a.deviceAddress));
         }
 
         //TODO also revoke notification access
@@ -438,32 +442,35 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
             return;
         }
 
-        Binder.withCleanCallingIdentity(() -> {
-            try {
-                if (containsEither(packageInfo.requestedPermissions,
-                        Manifest.permission.RUN_IN_BACKGROUND,
-                        Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)) {
-                    mIdleController.addPowerSaveWhitelistApp(packageInfo.packageName);
-                } else {
-                    mIdleController.removePowerSaveWhitelistApp(packageInfo.packageName);
-                }
-            } catch (RemoteException e) {
-                /* ignore - local call */
-            }
+        Binder.withCleanCallingIdentity(obtainRunnable(CompanionDeviceManagerService::
+                updateSpecialAccessPermissionAsSystem, this, packageInfo).recycleOnUse());
+    }
 
-            NetworkPolicyManager networkPolicyManager = NetworkPolicyManager.from(getContext());
+    private void updateSpecialAccessPermissionAsSystem(PackageInfo packageInfo) {
+        try {
             if (containsEither(packageInfo.requestedPermissions,
-                    Manifest.permission.USE_DATA_IN_BACKGROUND,
-                    Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND)) {
-                networkPolicyManager.addUidPolicy(
-                        packageInfo.applicationInfo.uid,
-                        NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+                    android.Manifest.permission.RUN_IN_BACKGROUND,
+                    android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)) {
+                mIdleController.addPowerSaveWhitelistApp(packageInfo.packageName);
             } else {
-                networkPolicyManager.removeUidPolicy(
-                        packageInfo.applicationInfo.uid,
-                        NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+                mIdleController.removePowerSaveWhitelistApp(packageInfo.packageName);
             }
-        });
+        } catch (RemoteException e) {
+            /* ignore - local call */
+        }
+
+        NetworkPolicyManager networkPolicyManager = NetworkPolicyManager.from(getContext());
+        if (containsEither(packageInfo.requestedPermissions,
+                android.Manifest.permission.USE_DATA_IN_BACKGROUND,
+                android.Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND)) {
+            networkPolicyManager.addUidPolicy(
+                    packageInfo.applicationInfo.uid,
+                    NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+        } else {
+            networkPolicyManager.removeUidPolicy(
+                    packageInfo.applicationInfo.uid,
+                    NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+        }
     }
 
     private static <T> boolean containsEither(T[] array, T a, T b) {
@@ -472,17 +479,17 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
 
     @Nullable
     private PackageInfo getPackageInfo(String packageName, int userId) {
-        return Binder.withCleanCallingIdentity(() -> {
+        return Binder.withCleanCallingIdentity(PooledLambda.obtainSupplier((context, pkg, id) -> {
             try {
-                return getContext().getPackageManager().getPackageInfoAsUser(
-                        packageName,
+                return context.getPackageManager().getPackageInfoAsUser(
+                        pkg,
                         PackageManager.GET_PERMISSIONS | PackageManager.GET_CONFIGURATIONS,
-                        userId);
+                        id);
             } catch (PackageManager.NameNotFoundException e) {
-                Slog.e(LOG_TAG, "Failed to get PackageInfo for package " + packageName, e);
+                Slog.e(LOG_TAG, "Failed to get PackageInfo for package " + pkg, e);
                 return null;
             }
-        });
+        }, getContext(), packageName, userId).recycleOnUse());
     }
 
     private void recordAssociation(String priviledgedPackage, String deviceAddress) {
@@ -495,20 +502,20 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
                 new Association(userId, deviceAddress, priviledgedPackage)));
     }
 
-    private void updateAssociations(Function<List<Association>, List<Association>> update) {
+    private void updateAssociations(Function<Set<Association>, Set<Association>> update) {
         updateAssociations(update, getCallingUserId());
     }
 
-    private void updateAssociations(Function<List<Association>, List<Association>> update,
+    private void updateAssociations(Function<Set<Association>, Set<Association>> update,
             int userId) {
         final AtomicFile file = getStorageFileForUser(userId);
         synchronized (file) {
-            List<Association> associations = readAllAssociations(userId);
-            final List<Association> old = CollectionUtils.copyOf(associations);
+            Set<Association> associations = readAllAssociations(userId);
+            final Set<Association> old = CollectionUtils.copyOf(associations);
             associations = update.apply(associations);
             if (size(old) == size(associations)) return;
 
-            List<Association> finalAssociations = associations;
+            Set<Association> finalAssociations = associations;
             file.write((out) -> {
                 XmlSerializer xml = Xml.newSerializer();
                 try {
@@ -517,13 +524,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
                     xml.startDocument(null, true);
                     xml.startTag(null, XML_TAG_ASSOCIATIONS);
 
-                    for (int i = 0; i < size(finalAssociations); i++) {
-                        Association association = finalAssociations.get(i);
+                    CollectionUtils.forEach(finalAssociations, association -> {
                         xml.startTag(null, XML_TAG_ASSOCIATION)
-                            .attribute(null, XML_ATTR_PACKAGE, association.companionAppPackage)
-                            .attribute(null, XML_ATTR_DEVICE, association.deviceAddress)
-                            .endTag(null, XML_TAG_ASSOCIATION);
-                    }
+                                .attribute(null, XML_ATTR_PACKAGE, association.companionAppPackage)
+                                .attribute(null, XML_ATTR_DEVICE, association.deviceAddress)
+                                .endTag(null, XML_TAG_ASSOCIATION);
+                    });
 
                     xml.endTag(null, XML_TAG_ASSOCIATIONS);
                     xml.endDocument();
@@ -545,17 +551,17 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
     }
 
     @Nullable
-    private ArrayList<Association> readAllAssociations(int userId) {
+    private Set<Association> readAllAssociations(int userId) {
         return readAllAssociations(userId, null);
     }
 
     @Nullable
-    private ArrayList<Association> readAllAssociations(int userId, @Nullable String packageFilter) {
+    private Set<Association> readAllAssociations(int userId, @Nullable String packageFilter) {
         final AtomicFile file = getStorageFileForUser(userId);
 
         if (!file.getBaseFile().exists()) return null;
 
-        ArrayList<Association> result = null;
+        ArraySet<Association> result = null;
         final XmlPullParser parser = Xml.newPullParser();
         synchronized (file) {
             try (FileInputStream in = file.openRead()) {
@@ -623,16 +629,19 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
                 + "associate USER_ID PACKAGE MAC_ADDRESS\n"
                 + "disassociate USER_ID PACKAGE MAC_ADDRESS";
 
+        ShellCmd() {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.MANAGE_COMPANION_DEVICES, "ShellCmd");
+        }
+
         @Override
         public int onCommand(String cmd) {
             switch (cmd) {
                 case "list": {
-                    ArrayList<Association> associations = readAllAssociations(getNextArgInt());
-                    for (int i = 0; i < size(associations); i++) {
-                        Association a = associations.get(i);
-                        getOutPrintWriter()
-                                .println(a.companionAppPackage + " " + a.deviceAddress);
-                    }
+                    CollectionUtils.forEach(
+                            readAllAssociations(getNextArgInt()),
+                            a -> getOutPrintWriter()
+                                    .println(a.companionAppPackage + " " + a.deviceAddress));
                 } break;
 
                 case "associate": {