Merge "Dump activities that handle when USB devices get plugged in"
This commit is contained in:
committed by
Android (Google) Code Review
commit
054e16e477
@@ -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;
|
||||
}
|
||||
|
||||
@@ -445,38 +445,38 @@ 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;
|
||||
}
|
||||
}
|
||||
else if (accessory != null && "usb-accessory".equals(tagName)) {
|
||||
AccessoryFilter filter = AccessoryFilter.read(parser);
|
||||
if (filter.matches(accessory)) {
|
||||
return true;
|
||||
if ("usb-device".equals(tagName)) {
|
||||
if (filters == null) {
|
||||
filters = new ArrayList<>(1);
|
||||
}
|
||||
filters.add(DeviceFilter.read(parser));
|
||||
}
|
||||
XmlUtils.nextElement(parser);
|
||||
}
|
||||
@@ -485,6 +485,84 @@ class UsbProfileGroupSettingsManager {
|
||||
} 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);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Slog.w(TAG, "Unable to load component info " + info.toString(), e);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user