Loading services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +113 −43 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -657,7 +707,7 @@ class UsbProfileGroupSettingsManager { IoUtils.closeQuietly(fis); } writeSettingsLocked(); scheduleWriteSettingsLocked(); // Success or failure, we delete single-user file sSingleUserSettingsFile.delete(); Loading Loading @@ -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(); Loading @@ -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); Loading @@ -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"); } Loading @@ -737,6 +803,10 @@ class UsbProfileGroupSettingsManager { mSettingsFile.failWrite(fos); } } mIsWriteSettingsScheduled = false; } }); } // Checks to see if a package matches a device or accessory. Loading Loading @@ -1141,7 +1211,7 @@ class UsbProfileGroupSettingsManager { } if (changed) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading Loading @@ -1178,7 +1248,7 @@ class UsbProfileGroupSettingsManager { } } if (changed) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading @@ -1204,7 +1274,7 @@ class UsbProfileGroupSettingsManager { } } if (changed) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading Loading @@ -1237,7 +1307,7 @@ class UsbProfileGroupSettingsManager { synchronized (mLock) { if (clearPackageDefaultsLocked(userPackage)) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading services/usb/java/com/android/server/usb/UsbService.java +5 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -83,7 +84,7 @@ public class UsbService extends IUsbManager.Stub { @Override public void onStopUser(int userHandle) { mUsbService.onStopUser(userHandle); mUsbService.onStopUser(UserHandle.of(userHandle)); } } Loading Loading @@ -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() { Loading services/usb/java/com/android/server/usb/UsbSettingsManager.java +18 −3 Original line number Diff line number Diff line Loading @@ -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); } } } } Loading Loading
services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +113 −43 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -657,7 +707,7 @@ class UsbProfileGroupSettingsManager { IoUtils.closeQuietly(fis); } writeSettingsLocked(); scheduleWriteSettingsLocked(); // Success or failure, we delete single-user file sSingleUserSettingsFile.delete(); Loading Loading @@ -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(); Loading @@ -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); Loading @@ -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"); } Loading @@ -737,6 +803,10 @@ class UsbProfileGroupSettingsManager { mSettingsFile.failWrite(fos); } } mIsWriteSettingsScheduled = false; } }); } // Checks to see if a package matches a device or accessory. Loading Loading @@ -1141,7 +1211,7 @@ class UsbProfileGroupSettingsManager { } if (changed) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading Loading @@ -1178,7 +1248,7 @@ class UsbProfileGroupSettingsManager { } } if (changed) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading @@ -1204,7 +1274,7 @@ class UsbProfileGroupSettingsManager { } } if (changed) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading Loading @@ -1237,7 +1307,7 @@ class UsbProfileGroupSettingsManager { synchronized (mLock) { if (clearPackageDefaultsLocked(userPackage)) { writeSettingsLocked(); scheduleWriteSettingsLocked(); } } } Loading
services/usb/java/com/android/server/usb/UsbService.java +5 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -83,7 +84,7 @@ public class UsbService extends IUsbManager.Stub { @Override public void onStopUser(int userHandle) { mUsbService.onStopUser(userHandle); mUsbService.onStopUser(UserHandle.of(userHandle)); } } Loading Loading @@ -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() { Loading
services/usb/java/com/android/server/usb/UsbSettingsManager.java +18 −3 Original line number Diff line number Diff line Loading @@ -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); } } } } Loading