Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8c866d6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Clear USB device defaults when user is removed"

parents e9c67f6b 880389e6
Loading
Loading
Loading
Loading
+113 −43
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
@@ -42,6 +43,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.Xml;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.Immutable;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.FastXmlSerializer;
@@ -60,7 +62,9 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import libcore.io.IoUtils;

@@ -87,13 +91,23 @@ class UsbProfileGroupSettingsManager {
    private final UserManager mUserManager;
    private final @NonNull UsbSettingsManager mSettingsManager;

    // Maps DeviceFilter to user preferred application package
    /** Maps DeviceFilter to user preferred application package */
    @GuardedBy("mLock")
    private final HashMap<DeviceFilter, UserPackage> mDevicePreferenceMap = new HashMap<>();
    // Maps AccessoryFilter to user preferred application package

    /** Maps AccessoryFilter to user preferred application package */
    @GuardedBy("mLock")
    private final HashMap<AccessoryFilter, UserPackage> mAccessoryPreferenceMap = new HashMap<>();

    private final Object mLock = new Object();

    /**
     * If a async task to persist the mDevicePreferenceMap and mAccessoryPreferenceMap is currently
     * scheduled.
     */
    @GuardedBy("mLock")
    private boolean mIsWriteSettingsScheduled;

    /**
     * A package of a user.
     */
@@ -591,6 +605,42 @@ class UsbProfileGroupSettingsManager {
                });
    }

    /**
     * Remove all defaults for a user.
     *
     * @param userToRemove The user the defaults belong to.
     */
    void removeAllDefaultsForUser(@NonNull UserHandle userToRemove) {
        synchronized (mLock) {
            boolean needToPersist = false;
            Iterator<Map.Entry<DeviceFilter, UserPackage>> devicePreferenceIt = mDevicePreferenceMap
                    .entrySet().iterator();
            while (devicePreferenceIt.hasNext()) {
                Map.Entry<DeviceFilter, UserPackage> entry = devicePreferenceIt.next();

                if (entry.getValue().user.equals(userToRemove)) {
                    devicePreferenceIt.remove();
                    needToPersist = true;
                }
            }

            Iterator<Map.Entry<AccessoryFilter, UserPackage>> accessoryPreferenceIt =
                    mAccessoryPreferenceMap.entrySet().iterator();
            while (accessoryPreferenceIt.hasNext()) {
                Map.Entry<AccessoryFilter, UserPackage> entry = accessoryPreferenceIt.next();

                if (entry.getValue().user.equals(userToRemove)) {
                    accessoryPreferenceIt.remove();
                    needToPersist = true;
                }
            }

            if (needToPersist) {
                scheduleWriteSettingsLocked();
            }
        }
    }

    private void readPreference(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        String packageName = null;
@@ -657,7 +707,7 @@ class UsbProfileGroupSettingsManager {
                IoUtils.closeQuietly(fis);
            }

            writeSettingsLocked();
            scheduleWriteSettingsLocked();

            // Success or failure, we delete single-user file
            sSingleUserSettingsFile.delete();
@@ -695,9 +745,23 @@ class UsbProfileGroupSettingsManager {
        }
    }

    private void writeSettingsLocked() {
        if (DEBUG) Slog.v(TAG, "writeSettingsLocked()");
    /**
     * Schedule a async task to persist {@link #mDevicePreferenceMap} and
     * {@link #mAccessoryPreferenceMap}. If a task is already scheduled but not completed, do
     * nothing as the currently scheduled one will do the work.
     * <p>Called with {@link #mLock} held.</p>
     * <p>In the uncommon case that the system crashes in between the scheduling and the write the
     * update is lost.</p>
     */
    private void scheduleWriteSettingsLocked() {
        if (mIsWriteSettingsScheduled) {
            return;
        } else {
            mIsWriteSettingsScheduled = true;
        }

        AsyncTask.execute(() -> {
            synchronized (mLock) {
                FileOutputStream fos = null;
                try {
                    fos = mSettingsFile.startWrite();
@@ -705,12 +769,14 @@ class UsbProfileGroupSettingsManager {
                    FastXmlSerializer serializer = new FastXmlSerializer();
                    serializer.setOutput(fos, StandardCharsets.UTF_8.name());
                    serializer.startDocument(null, true);
            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
                    serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
                                    true);
                    serializer.startTag(null, "settings");

                    for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
                        serializer.startTag(null, "preference");
                serializer.attribute(null, "package", mDevicePreferenceMap.get(filter).packageName);
                        serializer.attribute(null, "package",
                                mDevicePreferenceMap.get(filter).packageName);
                        serializer.attribute(null, "user",
                                String.valueOf(getSerial(mDevicePreferenceMap.get(filter).user)));
                        filter.write(serializer);
@@ -721,8 +787,8 @@ class UsbProfileGroupSettingsManager {
                        serializer.startTag(null, "preference");
                        serializer.attribute(null, "package",
                                mAccessoryPreferenceMap.get(filter).packageName);
                serializer.attribute(null, "user",
                        String.valueOf(getSerial(mAccessoryPreferenceMap.get(filter).user)));
                        serializer.attribute(null, "user", String.valueOf(
                                        getSerial(mAccessoryPreferenceMap.get(filter).user)));
                        filter.write(serializer);
                        serializer.endTag(null, "preference");
                    }
@@ -737,6 +803,10 @@ class UsbProfileGroupSettingsManager {
                        mSettingsFile.failWrite(fos);
                    }
                }

                mIsWriteSettingsScheduled = false;
            }
        });
    }

    // Checks to see if a package matches a device or accessory.
@@ -1141,7 +1211,7 @@ class UsbProfileGroupSettingsManager {
            }

            if (changed) {
                writeSettingsLocked();
                scheduleWriteSettingsLocked();
            }
        }
    }
@@ -1178,7 +1248,7 @@ class UsbProfileGroupSettingsManager {
                }
            }
            if (changed) {
                writeSettingsLocked();
                scheduleWriteSettingsLocked();
            }
        }
    }
@@ -1204,7 +1274,7 @@ class UsbProfileGroupSettingsManager {
                }
            }
            if (changed) {
                writeSettingsLocked();
                scheduleWriteSettingsLocked();
            }
        }
    }
@@ -1237,7 +1307,7 @@ class UsbProfileGroupSettingsManager {

        synchronized (mLock) {
            if (clearPackageDefaultsLocked(userPackage)) {
                writeSettingsLocked();
                scheduleWriteSettingsLocked();
            }
        }
    }
+5 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.usb;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
@@ -83,7 +84,7 @@ public class UsbService extends IUsbManager.Stub {

        @Override
        public void onStopUser(int userHandle) {
            mUsbService.onStopUser(userHandle);
            mUsbService.onStopUser(UserHandle.of(userHandle));
        }
    }

@@ -177,10 +178,10 @@ public class UsbService extends IUsbManager.Stub {
    /**
     * Execute operations when a user is stopped.
     *
     * @param stoppedUserId The id of the used that is stopped
     * @param stoppedUser The user that is stopped
     */
    private void onStopUser(@UserIdInt int stoppedUserId) {
        mSettingsManager.remove(stoppedUserId);
    private void onStopUser(@NonNull UserHandle stoppedUser) {
        mSettingsManager.remove(stoppedUser);
    }

    public void systemReady() {
+18 −3
Original line number Diff line number Diff line
@@ -108,11 +108,26 @@ class UsbSettingsManager {
    /**
     * Remove the settings for a user.
     *
     * @param userIdToRemove The user o remove
     * @param userToRemove The user to remove
     */
    void remove(@UserIdInt int userIdToRemove) {
    void remove(@NonNull UserHandle userToRemove) {
        synchronized (mSettingsByUser) {
            mSettingsByUser.remove(userIdToRemove);
            mSettingsByUser.remove(userToRemove.getIdentifier());
        }

        synchronized (mSettingsByProfileGroup) {
            if (mSettingsByProfileGroup.indexOfKey(userToRemove.getIdentifier()) >= 0) {
                // The user to remove is the parent user of the group. The parent is the last user
                // that gets removed. All state will be removed with the user
                mSettingsByProfileGroup.remove(userToRemove.getIdentifier());
            } else {
                // We cannot find the parent user of the user that is removed, hence try to remove
                // it from all profile groups.
                int numProfileGroups = mSettingsByProfileGroup.size();
                for (int i = 0; i < numProfileGroups; i++) {
                    mSettingsByProfileGroup.valueAt(i).removeAllDefaultsForUser(userToRemove);
                }
            }
        }
    }