diff options
| author | 2018-06-03 05:32:33 +0000 | |
|---|---|---|
| committer | 2018-06-03 05:32:33 +0000 | |
| commit | 054e16e47759139079f00dfcfe347a64e318e716 (patch) | |
| tree | 9672a781a148893fec60c629b880e45754de3241 | |
| parent | 93e87cf197e8bdda2020ebb2ec1ecfa831429b65 (diff) | |
| parent | 66c5a8d2073d2076fc0e06237659143e8de52539 (diff) | |
Merge "Dump activities that handle when USB devices get plugged in"
4 files changed, 198 insertions, 24 deletions
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto index c36371004c35..9f58611397f9 100644 --- a/core/proto/android/service/usb.proto +++ b/core/proto/android/service/usb.proto @@ -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; +} diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java index 43f189b26dfa..7a906d0b7aaf 100644 --- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java @@ -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); } } diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java index caf05a3538ec..9221825b2d87 100644 --- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java @@ -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); } } diff --git a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java index 840950679903..24a2d72415ed 100644 --- a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java @@ -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); |