From 733d322cf594bb29a57e5e44c5c8100c4cf3ffcc Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 28 Nov 2016 16:37:47 -0800 Subject: [PATCH] Consider priority when launching a USB app If there are differnet priorities only consider the acitities with the highest priorities. Esp, if there is only one app with the highest priority launch it directly. This enables an interesting use case: If a priviledged app wants to always be launched for a device it can just set the priority to >0. As it is also on system/ the user _will_not_ get a confirmation dialog and the app will always be directly launched. Test: Added app with higher priority to device and saw it to get auto-selected. Fixes: 28595282 Change-Id: Ia2c9afa00b5a6e8a00b30a01442da62dd0e33961 --- .../usb/UsbProfileGroupSettingsManager.java | 64 +++++++++++++++++-- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java index e03a14f41ce24..d44005268683f 100644 --- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java @@ -16,6 +16,8 @@ package com.android.server.usb; +import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; + import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ActivityNotFoundException; @@ -41,6 +43,8 @@ import android.os.UserManager; import android.util.AtomicFile; import android.util.Log; import android.util.Slog; +import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.Xml; import com.android.internal.annotations.GuardedBy; @@ -50,6 +54,8 @@ import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.XmlUtils; +import libcore.io.IoUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -66,10 +72,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import libcore.io.IoUtils; - -import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; - class UsbProfileGroupSettingsManager { private static final String TAG = UsbProfileGroupSettingsManager.class.getSimpleName(); private static final boolean DEBUG = false; @@ -873,6 +875,56 @@ class UsbProfileGroupSettingsManager { return resolveInfos; } + /** + * Only return those matches with the highest priority. + * + * @param matches All matches, some might have lower priority + * + * @return The matches with the highest priority + */ + @NonNull + private ArrayList preferHighPriority( + @NonNull ArrayList matches) { + SparseArray> highestPriorityMatchesByUserId = new SparseArray<>(); + SparseIntArray highestPriorityByUserId = new SparseIntArray(); + + // Create list of highest priority matches per user in highestPriorityMatchesByUserId + int numMatches = matches.size(); + for (int matchNum = 0; matchNum < numMatches; matchNum++) { + ResolveInfo match = matches.get(matchNum); + + // If this a previously unknown user? + if (highestPriorityByUserId.indexOfKey(match.targetUserId) < 0) { + highestPriorityByUserId.put(match.targetUserId, Integer.MIN_VALUE); + highestPriorityMatchesByUserId.put(match.targetUserId, new ArrayList<>()); + } + + // Find current highest priority matches for the current user + int highestPriority = highestPriorityByUserId.get(match.targetUserId); + ArrayList highestPriorityMatches = highestPriorityMatchesByUserId.get( + match.targetUserId); + + if (match.priority == highestPriority) { + highestPriorityMatches.add(match); + } else if (match.priority > highestPriority) { + highestPriorityByUserId.put(match.targetUserId, match.priority); + + highestPriorityMatches.clear(); + highestPriorityMatches.add(match); + } + } + + // Combine all users back together. This means that all matches have the same priority for a + // user. Matches for different users might have different priority. + ArrayList combinedMatches = new ArrayList<>(); + int numMatchArrays = highestPriorityMatchesByUserId.size(); + for (int matchArrayNum = 0; matchArrayNum < numMatchArrays; matchArrayNum++) { + combinedMatches.addAll(highestPriorityMatchesByUserId.valueAt(matchArrayNum)); + } + + return combinedMatches; + } + private final ArrayList getDeviceMatchesLocked(UsbDevice device, Intent intent) { ArrayList matches = new ArrayList(); List resolveInfos = queryIntentActivitiesForAllProfiles(intent); @@ -883,7 +935,7 @@ class UsbProfileGroupSettingsManager { matches.add(resolveInfo); } } - return matches; + return preferHighPriority(matches); } private final ArrayList getAccessoryMatchesLocked( @@ -897,7 +949,7 @@ class UsbProfileGroupSettingsManager { matches.add(resolveInfo); } } - return matches; + return preferHighPriority(matches); } public void deviceAttached(UsbDevice device) {