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

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

Merge "Dump activities that handle when USB devices get plugged in"

parents 93e87cf1 66c5a8d2
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -278,6 +278,8 @@ message UsbUserSettingsManagerProto {
    optional int32 user_id = 1;
    repeated UsbSettingsDevicePermissionProto device_permissions = 2;
    repeated UsbSettingsAccessoryPermissionProto accessory_permissions = 3;
    repeated UsbDeviceAttachedActivities device_attached_activities = 4;
    repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
}

message UsbSettingsDevicePermissionProto {
@@ -343,3 +345,17 @@ message UsbAccessoryFilterProto {
    optional string model = 2;
    optional string version = 3;
}

message UsbDeviceAttachedActivities {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional android.content.ComponentNameProto activity = 1;
    repeated UsbDeviceFilterProto filters = 2;
}

message UsbAccessoryAttachedActivities {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional android.content.ComponentNameProto activity = 1;
    repeated UsbAccessoryFilterProto filters = 2;
}
+100 −22
Original line number Diff line number Diff line
@@ -445,38 +445,80 @@ class UsbProfileGroupSettingsManager {
        });
    }

    // Checks to see if a package matches a device or accessory.
    // Only one of device and accessory should be non-null.
    private boolean packageMatchesLocked(ResolveInfo info, String metaDataName,
            UsbDevice device, UsbAccessory accessory) {
        if (isForwardMatch(info)) {
            return true;
        }

    /**
     * Get {@link DeviceFilter} for all devices an activity should be launched for.
     *
     * @param pm The package manager used to get the device filter files
     * @param info The {@link ResolveInfo} for the activity that can handle usb device attached
     *             events
     *
     * @return The list of {@link DeviceFilter} the activity should be called for or {@code null} if
     *         none
     */
    @Nullable
    static ArrayList<DeviceFilter> getDeviceFilters(@NonNull PackageManager pm,
            @NonNull ResolveInfo info) {
        ArrayList<DeviceFilter> filters = null;
        ActivityInfo ai = info.activityInfo;

        XmlResourceParser parser = null;
        try {
            parser = ai.loadXmlMetaData(mPackageManager, metaDataName);
            parser = ai.loadXmlMetaData(pm, UsbManager.ACTION_USB_DEVICE_ATTACHED);
            if (parser == null) {
                Slog.w(TAG, "no meta-data for " + info);
                return false;
                return null;
            }

            XmlUtils.nextElement(parser);
            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                String tagName = parser.getName();
                if (device != null && "usb-device".equals(tagName)) {
                    DeviceFilter filter = DeviceFilter.read(parser);
                    if (filter.matches(device)) {
                        return true;
                if ("usb-device".equals(tagName)) {
                    if (filters == null) {
                        filters = new ArrayList<>(1);
                    }
                    filters.add(DeviceFilter.read(parser));
                }
                else if (accessory != null && "usb-accessory".equals(tagName)) {
                    AccessoryFilter filter = AccessoryFilter.read(parser);
                    if (filter.matches(accessory)) {
                        return true;
                XmlUtils.nextElement(parser);
            }
        } catch (Exception e) {
            Slog.w(TAG, "Unable to load component info " + info.toString(), e);
        } finally {
            if (parser != null) parser.close();
        }
        return filters;
    }

    /**
     * Get {@link AccessoryFilter} for all accessories an activity should be launched for.
     *
     * @param pm The package manager used to get the accessory filter files
     * @param info The {@link ResolveInfo} for the activity that can handle usb accessory attached
     *             events
     *
     * @return The list of {@link AccessoryFilter} the activity should be called for or {@code null}
     *         if none
     */
    static @Nullable ArrayList<AccessoryFilter> getAccessoryFilters(@NonNull PackageManager pm,
            @NonNull ResolveInfo info) {
        ArrayList<AccessoryFilter> filters = null;
        ActivityInfo ai = info.activityInfo;

        XmlResourceParser parser = null;
        try {
            parser = ai.loadXmlMetaData(pm, UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
            if (parser == null) {
                Slog.w(TAG, "no meta-data for " + info);
                return null;
            }

            XmlUtils.nextElement(parser);
            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                String tagName = parser.getName();
                if ("usb-accessory".equals(tagName)) {
                    if (filters == null) {
                        filters = new ArrayList<>(1);
                    }
                    filters.add(AccessoryFilter.read(parser));
                }
                XmlUtils.nextElement(parser);
            }
@@ -485,6 +527,42 @@ class UsbProfileGroupSettingsManager {
        } finally {
            if (parser != null) parser.close();
        }
        return filters;
    }

    // Checks to see if a package matches a device or accessory.
    // Only one of device and accessory should be non-null.
    private boolean packageMatchesLocked(ResolveInfo info, UsbDevice device,
            UsbAccessory accessory) {
        if (isForwardMatch(info)) {
            return true;
        }

        if (device != null) {
            ArrayList<DeviceFilter> deviceFilters = getDeviceFilters(mPackageManager, info);
            if (deviceFilters != null) {
                int numDeviceFilters = deviceFilters.size();
                for (int i = 0; i < numDeviceFilters; i++) {
                    if (deviceFilters.get(i).matches(device)) {
                        return true;
                    }
                }
            }
        }

        if (accessory != null) {
            ArrayList<AccessoryFilter> accessoryFilters = getAccessoryFilters(mPackageManager,
                    info);
            if (accessoryFilters != null) {
                int numAccessoryFilters = accessoryFilters.size();
                for (int i = 0; i < numAccessoryFilters; i++) {
                    if (accessoryFilters.get(i).matches(accessory)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

@@ -502,8 +580,8 @@ class UsbProfileGroupSettingsManager {
        ArrayList<ResolveInfo> resolveInfos = new ArrayList<>();
        int numProfiles = profiles.size();
        for (int i = 0; i < numProfiles; i++) {
            resolveInfos.addAll(mPackageManager.queryIntentActivitiesAsUser(intent,
                    PackageManager.GET_META_DATA, profiles.get(i).id));
            resolveInfos.addAll(mSettingsManager.getSettingsForUser(profiles.get(i).id)
                    .queryIntentActivities(intent));
        }

        return resolveInfos;
@@ -629,7 +707,7 @@ class UsbProfileGroupSettingsManager {
        int count = resolveInfos.size();
        for (int i = 0; i < count; i++) {
            ResolveInfo resolveInfo = resolveInfos.get(i);
            if (packageMatchesLocked(resolveInfo, intent.getAction(), device, null)) {
            if (packageMatchesLocked(resolveInfo, device, null)) {
                matches.add(resolveInfo);
            }
        }
@@ -644,7 +722,7 @@ class UsbProfileGroupSettingsManager {
        int count = resolveInfos.size();
        for (int i = 0; i < count; i++) {
            ResolveInfo resolveInfo = resolveInfos.get(i);
            if (packageMatchesLocked(resolveInfo, intent.getAction(), null, accessory)) {
            if (packageMatchesLocked(resolveInfo, null, accessory)) {
                matches.add(resolveInfo);
            }
        }
+5 −2
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.dump.DualDumpOutputStream;

import java.util.List;

/**
 * Maintains all {@link UsbUserSettingsManager} for all users.
 */
@@ -140,9 +142,10 @@ class UsbSettingsManager {
        long token = dump.start(idName, id);

        synchronized (mSettingsByUser) {
            int numUsers = mSettingsByUser.size();
            List<UserInfo> users = mUserManager.getUsers();
            int numUsers = users.size();
            for (int i = 0; i < numUsers; i++) {
                mSettingsByUser.valueAt(i).dump(dump, "user_settings",
                getSettingsForUser(users.get(i).id).dump(dump, "user_settings",
                        UsbSettingsManagerProto.USER_SETTINGS);
            }
        }
+77 −0
Original line number Diff line number Diff line
@@ -16,14 +16,22 @@

package com.android.server.usb;

import static com.android.internal.util.dump.DumpUtils.writeComponentName;
import static com.android.server.usb.UsbProfileGroupSettingsManager.getAccessoryFilters;
import static com.android.server.usb.UsbProfileGroupSettingsManager.getDeviceFilters;

import android.annotation.NonNull;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.hardware.usb.AccessoryFilter;
import android.hardware.usb.DeviceFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
@@ -32,6 +40,8 @@ import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.Process;
import android.os.UserHandle;
import android.service.usb.UsbAccessoryAttachedActivities;
import android.service.usb.UsbDeviceAttachedActivities;
import android.service.usb.UsbSettingsAccessoryPermissionProto;
import android.service.usb.UsbSettingsDevicePermissionProto;
import android.service.usb.UsbUserSettingsManagerProto;
@@ -40,7 +50,9 @@ import android.util.SparseBooleanArray;

import com.android.internal.util.dump.DualDumpOutputStream;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

class UsbUserSettingsManager {
    private static final String TAG = "UsbUserSettingsManager";
@@ -305,6 +317,18 @@ class UsbUserSettingsManager {
        }
    }

    /**
     * Get all activities that can handle the device/accessory attached intent.
     *
     * @param intent The intent to handle
     *
     * @return The resolve infos of the activities that can handle the intent
     */
    List<ResolveInfo> queryIntentActivities(@NonNull Intent intent) {
        return mPackageManager.queryIntentActivitiesAsUser(intent, PackageManager.GET_META_DATA,
                mUser.getIdentifier());
    }

    public void dump(@NonNull DualDumpOutputStream dump, @NonNull String idName, long id) {
        long token = dump.start(idName, id);

@@ -341,6 +365,59 @@ class UsbUserSettingsManager {

                dump.end(accessoryPermissionToken);
            }

            List<ResolveInfo> deviceAttachedActivities = queryIntentActivities(
                    new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED));
            int numDeviceAttachedActivities = deviceAttachedActivities.size();
            for (int activityNum = 0; activityNum < numDeviceAttachedActivities; activityNum++) {
                ResolveInfo deviceAttachedActivity = deviceAttachedActivities.get(activityNum);

                long deviceAttachedActivityToken = dump.start("device_attached_activities",
                        UsbUserSettingsManagerProto.DEVICE_ATTACHED_ACTIVITIES);

                writeComponentName(dump, "activity", UsbDeviceAttachedActivities.ACTIVITY,
                        new ComponentName(deviceAttachedActivity.activityInfo.packageName,
                                deviceAttachedActivity.activityInfo.name));

                ArrayList<DeviceFilter> deviceFilters = getDeviceFilters(mPackageManager,
                        deviceAttachedActivity);
                if (deviceFilters != null) {
                    int numDeviceFilters = deviceFilters.size();
                    for (int filterNum = 0; filterNum < numDeviceFilters; filterNum++) {
                        deviceFilters.get(filterNum).dump(dump, "filters",
                                UsbDeviceAttachedActivities.FILTERS);
                    }
                }

                dump.end(deviceAttachedActivityToken);
            }

            List<ResolveInfo> accessoryAttachedActivities =
                    queryIntentActivities(new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED));
            int numAccessoryAttachedActivities = accessoryAttachedActivities.size();
            for (int activityNum = 0; activityNum < numAccessoryAttachedActivities; activityNum++) {
                ResolveInfo accessoryAttachedActivity =
                        accessoryAttachedActivities.get(activityNum);

                long accessoryAttachedActivityToken = dump.start("accessory_attached_activities",
                        UsbUserSettingsManagerProto.ACCESSORY_ATTACHED_ACTIVITIES);

                writeComponentName(dump, "activity", UsbAccessoryAttachedActivities.ACTIVITY,
                        new ComponentName(accessoryAttachedActivity.activityInfo.packageName,
                                accessoryAttachedActivity.activityInfo.name));

                ArrayList<AccessoryFilter> accessoryFilters = getAccessoryFilters(mPackageManager,
                        accessoryAttachedActivity);
                if (accessoryFilters != null) {
                    int numAccessoryFilters = accessoryFilters.size();
                    for (int filterNum = 0; filterNum < numAccessoryFilters; filterNum++) {
                        accessoryFilters.get(filterNum).dump(dump, "filters",
                                UsbAccessoryAttachedActivities.FILTERS);
                    }
                }

                dump.end(accessoryAttachedActivityToken);
            }
        }

        dump.end(token);