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

Commit 733d322c authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

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
parent 776a2402
Loading
Loading
Loading
Loading
+58 −6
Original line number Diff line number Diff line
@@ -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<ResolveInfo> preferHighPriority(
            @NonNull ArrayList<ResolveInfo> matches) {
        SparseArray<ArrayList<ResolveInfo>> 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<ResolveInfo> 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<ResolveInfo> combinedMatches = new ArrayList<>();
        int numMatchArrays = highestPriorityMatchesByUserId.size();
        for (int matchArrayNum = 0; matchArrayNum < numMatchArrays; matchArrayNum++) {
            combinedMatches.addAll(highestPriorityMatchesByUserId.valueAt(matchArrayNum));
        }

        return combinedMatches;
    }

    private final ArrayList<ResolveInfo> getDeviceMatchesLocked(UsbDevice device, Intent intent) {
        ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
        List<ResolveInfo> resolveInfos = queryIntentActivitiesForAllProfiles(intent);
@@ -883,7 +935,7 @@ class UsbProfileGroupSettingsManager {
                matches.add(resolveInfo);
            }
        }
        return matches;
        return preferHighPriority(matches);
    }

    private final ArrayList<ResolveInfo> getAccessoryMatchesLocked(
@@ -897,7 +949,7 @@ class UsbProfileGroupSettingsManager {
                matches.add(resolveInfo);
            }
        }
        return matches;
        return preferHighPriority(matches);
    }

    public void deviceAttached(UsbDevice device) {