Make default USB handling apps per profile group.
If a USB device is plugged in a default app might be started. As the user does not indicate which profile he is interested in by pluggin in a USB device, all handling of this operation has to be per default group. To do this Split UsbUserSettingsManager into UsbUserSettingsManager and UsbProfileGroupSettingsManager and modify UsbProfileGroupSettingsManager. Bug: 29233186 Change-Id: I8e56b621eeb802966504360d372a8a0140106114
This commit is contained in:
@@ -36,16 +36,26 @@ import com.android.internal.app.ResolverActivity;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
|
||||
|
||||
/* Activity for choosing an application for a USB device or accessory */
|
||||
public class UsbResolverActivity extends ResolverActivity {
|
||||
public static final String TAG = "UsbResolverActivity";
|
||||
public static final String EXTRA_RESOLVE_INFOS = "rlist";
|
||||
public static final String EXTRA_RESOLVE_INFO = "rinfo";
|
||||
|
||||
private UsbDevice mDevice;
|
||||
private UsbAccessory mAccessory;
|
||||
private UsbDisconnectedReceiver mDisconnectedReceiver;
|
||||
|
||||
/** Resolve info that switches user profiles */
|
||||
private ResolveInfo mForwardResolveInfo;
|
||||
|
||||
/** The intent that should be started when the profile is switched */
|
||||
private Intent mOtherProfileIntent;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Intent intent = getIntent();
|
||||
@@ -56,17 +66,22 @@ public class UsbResolverActivity extends ResolverActivity {
|
||||
return;
|
||||
}
|
||||
Intent target = (Intent)targetParcelable;
|
||||
ArrayList<ResolveInfo> rList = intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS);
|
||||
CharSequence title = getResources().getText(com.android.internal.R.string.chooseUsbActivity);
|
||||
super.onCreate(savedInstanceState, target, title, null, rList,
|
||||
true /* Set alwaysUseOption to true to enable "always use this app" checkbox. */ );
|
||||
ArrayList<ResolveInfo> rList = new ArrayList<>(
|
||||
intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS));
|
||||
|
||||
CheckBox alwaysUse = (CheckBox)findViewById(com.android.internal.R.id.alwaysUse);
|
||||
if (alwaysUse != null) {
|
||||
if (mDevice == null) {
|
||||
alwaysUse.setText(R.string.always_use_accessory);
|
||||
} else {
|
||||
alwaysUse.setText(R.string.always_use_device);
|
||||
// The rList contains the apps for all profiles of this users. Separate those. We currently
|
||||
// only support two profiles, i.e. one forward resolve info.
|
||||
ArrayList<ResolveInfo> rListOtherProfile = new ArrayList<>();
|
||||
mForwardResolveInfo = null;
|
||||
for (Iterator<ResolveInfo> iterator = rList.iterator(); iterator.hasNext();) {
|
||||
ResolveInfo ri = iterator.next();
|
||||
|
||||
if (ri.getComponentInfo().name.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
|
||||
mForwardResolveInfo = ri;
|
||||
} else if (UserHandle.getUserId(ri.activityInfo.applicationInfo.uid)
|
||||
!= UserHandle.myUserId()) {
|
||||
iterator.remove();
|
||||
rListOtherProfile.add(ri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +97,40 @@ public class UsbResolverActivity extends ResolverActivity {
|
||||
}
|
||||
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
|
||||
}
|
||||
|
||||
// Create intent that will be used when switching to other profile. Emulate the behavior of
|
||||
// UsbProfileGroupSettingsManager#resolveActivity
|
||||
if (mForwardResolveInfo != null) {
|
||||
if (rListOtherProfile.size() > 1) {
|
||||
mOtherProfileIntent = new Intent(intent);
|
||||
mOtherProfileIntent.putParcelableArrayListExtra(EXTRA_RESOLVE_INFOS,
|
||||
rListOtherProfile);
|
||||
} else {
|
||||
mOtherProfileIntent = new Intent(this, UsbConfirmActivity.class);
|
||||
mOtherProfileIntent.putExtra(EXTRA_RESOLVE_INFO, rListOtherProfile.get(0));
|
||||
|
||||
if (mDevice != null) {
|
||||
mOtherProfileIntent.putExtra(UsbManager.EXTRA_DEVICE, mDevice);
|
||||
}
|
||||
|
||||
if (mAccessory != null) {
|
||||
mOtherProfileIntent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CharSequence title = getResources().getText(com.android.internal.R.string.chooseUsbActivity);
|
||||
super.onCreate(savedInstanceState, target, title, null, rList,
|
||||
true /* Set alwaysUseOption to true to enable "always use this app" checkbox. */ );
|
||||
|
||||
CheckBox alwaysUse = (CheckBox)findViewById(com.android.internal.R.id.alwaysUse);
|
||||
if (alwaysUse != null) {
|
||||
if (mDevice == null) {
|
||||
alwaysUse.setText(R.string.always_use_accessory);
|
||||
} else {
|
||||
alwaysUse.setText(R.string.always_use_device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,6 +144,12 @@ public class UsbResolverActivity extends ResolverActivity {
|
||||
@Override
|
||||
protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
|
||||
final ResolveInfo ri = target.getResolveInfo();
|
||||
if (ri == mForwardResolveInfo) {
|
||||
startActivityAsUser(mOtherProfileIntent, null,
|
||||
UserHandle.of(mForwardResolveInfo.targetUserId));
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
IBinder b = ServiceManager.getService(USB_SERVICE);
|
||||
IUsbManager service = IUsbManager.Stub.asInterface(b);
|
||||
@@ -122,7 +177,7 @@ public class UsbResolverActivity extends ResolverActivity {
|
||||
}
|
||||
|
||||
try {
|
||||
target.startAsUser(this, null, new UserHandle(userId));
|
||||
target.startAsUser(this, null, UserHandle.of(userId));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.e(TAG, "startActivity failed", e);
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ public class UsbDeviceManager {
|
||||
private final Context mContext;
|
||||
private final ContentResolver mContentResolver;
|
||||
@GuardedBy("mLock")
|
||||
private UsbUserSettingsManager mCurrentUserSettings;
|
||||
private UsbProfileGroupSettingsManager mCurrentSettings;
|
||||
private NotificationManager mNotificationManager;
|
||||
private final boolean mHasUsbAccessory;
|
||||
private boolean mUseUsbNotification;
|
||||
@@ -221,9 +221,9 @@ public class UsbDeviceManager {
|
||||
new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
|
||||
}
|
||||
|
||||
private UsbUserSettingsManager getCurrentUserSettings() {
|
||||
private UsbProfileGroupSettingsManager getCurrentSettings() {
|
||||
synchronized (mLock) {
|
||||
return mCurrentUserSettings;
|
||||
return mCurrentSettings;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,9 +258,9 @@ public class UsbDeviceManager {
|
||||
mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
|
||||
}
|
||||
|
||||
public void setCurrentUser(int newCurrentUserId, UsbUserSettingsManager settings) {
|
||||
public void setCurrentUser(int newCurrentUserId, UsbProfileGroupSettingsManager settings) {
|
||||
synchronized (mLock) {
|
||||
mCurrentUserSettings = settings;
|
||||
mCurrentSettings = settings;
|
||||
mHandler.obtainMessage(MSG_USER_SWITCHED, newCurrentUserId, 0).sendToTarget();
|
||||
}
|
||||
}
|
||||
@@ -574,7 +574,7 @@ public class UsbDeviceManager {
|
||||
Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
|
||||
// defer accessoryAttached if system is not ready
|
||||
if (mBootCompleted) {
|
||||
getCurrentUserSettings().accessoryAttached(mCurrentAccessory);
|
||||
getCurrentSettings().accessoryAttached(mCurrentAccessory);
|
||||
} // else handle in boot completed
|
||||
} else {
|
||||
Slog.e(TAG, "nativeGetAccessoryStrings failed");
|
||||
@@ -767,7 +767,7 @@ public class UsbDeviceManager {
|
||||
case MSG_BOOT_COMPLETED:
|
||||
mBootCompleted = true;
|
||||
if (mCurrentAccessory != null) {
|
||||
getCurrentUserSettings().accessoryAttached(mCurrentAccessory);
|
||||
getCurrentSettings().accessoryAttached(mCurrentAccessory);
|
||||
}
|
||||
if (mDebuggingManager != null) {
|
||||
mDebuggingManager.setAdbEnabled(mAdbEnabled);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class UsbHostManager {
|
||||
private final UsbSettingsManager mSettingsManager;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private UsbUserSettingsManager mCurrentUserSettings;
|
||||
private UsbProfileGroupSettingsManager mCurrentSettings;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private ComponentName mUsbDeviceConnectionHandler;
|
||||
@@ -83,15 +83,15 @@ public class UsbHostManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentUserSettings(UsbUserSettingsManager settings) {
|
||||
public void setCurrentUserSettings(UsbProfileGroupSettingsManager settings) {
|
||||
synchronized (mLock) {
|
||||
mCurrentUserSettings = settings;
|
||||
mCurrentSettings = settings;
|
||||
}
|
||||
}
|
||||
|
||||
private UsbUserSettingsManager getCurrentUserSettings() {
|
||||
private UsbProfileGroupSettingsManager getCurrentUserSettings() {
|
||||
synchronized (mLock) {
|
||||
return mCurrentUserSettings;
|
||||
return mCurrentSettings;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -115,7 +115,7 @@ public class UsbService extends IUsbManager.Stub {
|
||||
public UsbService(Context context) {
|
||||
mContext = context;
|
||||
|
||||
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
mUserManager = context.getSystemService(UserManager.class);
|
||||
mSettingsManager = new UsbSettingsManager(context);
|
||||
mAlsaManager = new UsbAlsaManager(context);
|
||||
|
||||
@@ -160,15 +160,16 @@ public class UsbService extends IUsbManager.Stub {
|
||||
synchronized (mLock) {
|
||||
mCurrentUserId = newUserId;
|
||||
|
||||
// The following two modules need to know about the current user. If they need to
|
||||
// distinguish by profile of the user, the id has to be passed in the call to the
|
||||
// The following two modules need to know about the current profile group. If they need
|
||||
// to distinguish by profile of the user, the id has to be passed in the call to the
|
||||
// module.
|
||||
UsbUserSettingsManager userSettings = getSettingsForUser(newUserId);
|
||||
UsbProfileGroupSettingsManager settings =
|
||||
mSettingsManager.getSettingsForProfileGroup(UserHandle.of(newUserId));
|
||||
if (mHostManager != null) {
|
||||
mHostManager.setCurrentUserSettings(userSettings);
|
||||
mHostManager.setCurrentUserSettings(settings);
|
||||
}
|
||||
if (mDeviceManager != null) {
|
||||
mDeviceManager.setCurrentUser(newUserId, userSettings);
|
||||
mDeviceManager.setCurrentUser(newUserId, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,14 +285,24 @@ public class UsbService extends IUsbManager.Stub {
|
||||
|
||||
@Override
|
||||
public void setDevicePackage(UsbDevice device, String packageName, int userId) {
|
||||
device = Preconditions.checkNotNull(device);
|
||||
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||
getSettingsForUser(userId).setDevicePackage(device, packageName);
|
||||
|
||||
UserHandle user = UserHandle.of(userId);
|
||||
mSettingsManager.getSettingsForProfileGroup(user).setDevicePackage(device, packageName,
|
||||
user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessoryPackage(UsbAccessory accessory, String packageName, int userId) {
|
||||
accessory = Preconditions.checkNotNull(accessory);
|
||||
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||
getSettingsForUser(userId).setAccessoryPackage(accessory, packageName);
|
||||
|
||||
UserHandle user = UserHandle.of(userId);
|
||||
mSettingsManager.getSettingsForProfileGroup(user).setAccessoryPackage(accessory,
|
||||
packageName, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -335,14 +346,22 @@ public class UsbService extends IUsbManager.Stub {
|
||||
|
||||
@Override
|
||||
public boolean hasDefaults(String packageName, int userId) {
|
||||
packageName = Preconditions.checkStringNotEmpty(packageName);
|
||||
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||
return getSettingsForUser(userId).hasDefaults(packageName);
|
||||
|
||||
UserHandle user = UserHandle.of(userId);
|
||||
return mSettingsManager.getSettingsForProfileGroup(user).hasDefaults(packageName, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearDefaults(String packageName, int userId) {
|
||||
packageName = Preconditions.checkStringNotEmpty(packageName);
|
||||
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||
getSettingsForUser(userId).clearDefaults(packageName);
|
||||
|
||||
UserHandle user = UserHandle.of(userId);
|
||||
mSettingsManager.getSettingsForProfileGroup(user).clearDefaults(packageName, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,10 +20,12 @@ import android.annotation.NonNull;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.hardware.usb.UsbAccessory;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -43,8 +45,18 @@ class UsbSettingsManager {
|
||||
@GuardedBy("mSettingsByUser")
|
||||
private final SparseArray<UsbUserSettingsManager> mSettingsByUser = new SparseArray<>();
|
||||
|
||||
/**
|
||||
* Map from the parent profile's user id to {@link UsbProfileGroupSettingsManager} for the
|
||||
* group.
|
||||
*/
|
||||
@GuardedBy("mSettingsByProfileGroup")
|
||||
private final SparseArray<UsbProfileGroupSettingsManager> mSettingsByProfileGroup
|
||||
= new SparseArray<>();
|
||||
private UserManager mUserManager;
|
||||
|
||||
public UsbSettingsManager(@NonNull Context context) {
|
||||
mContext = context;
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,6 +77,34 @@ class UsbSettingsManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link UsbProfileGroupSettingsManager} for a user.
|
||||
*
|
||||
* @param user Any user of the profile group
|
||||
*
|
||||
* @return The settings for the profile group
|
||||
*/
|
||||
@NonNull UsbProfileGroupSettingsManager getSettingsForProfileGroup(@NonNull UserHandle user) {
|
||||
UserHandle parentUser;
|
||||
|
||||
UserInfo parentUserInfo = mUserManager.getProfileParent(user.getIdentifier());
|
||||
if (parentUserInfo != null) {
|
||||
parentUser = parentUserInfo.getUserHandle();
|
||||
} else {
|
||||
parentUser = user;
|
||||
}
|
||||
|
||||
synchronized (mSettingsByProfileGroup) {
|
||||
UsbProfileGroupSettingsManager settings = mSettingsByProfileGroup.get(
|
||||
parentUser.getIdentifier());
|
||||
if (settings == null) {
|
||||
settings = new UsbProfileGroupSettingsManager(mContext, parentUser, this);
|
||||
mSettingsByProfileGroup.put(parentUser.getIdentifier(), settings);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the settings for a user.
|
||||
*
|
||||
@@ -83,7 +123,8 @@ class UsbSettingsManager {
|
||||
*/
|
||||
void dump(@NonNull IndentingPrintWriter pw) {
|
||||
synchronized (mSettingsByUser) {
|
||||
for (int i = 0; i < mSettingsByUser.size(); i++) {
|
||||
int numUsers = mSettingsByUser.size();
|
||||
for (int i = 0; i < numUsers; i++) {
|
||||
final int userId = mSettingsByUser.keyAt(i);
|
||||
final UsbUserSettingsManager settings = mSettingsByUser.valueAt(i);
|
||||
pw.println("Settings for user " + userId + ":");
|
||||
@@ -95,6 +136,21 @@ class UsbSettingsManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mSettingsByProfileGroup) {
|
||||
int numProfileGroups = mSettingsByProfileGroup.size();
|
||||
for (int i = 0; i < numProfileGroups; i++) {
|
||||
final int parentUserId = mSettingsByProfileGroup.keyAt(i);
|
||||
final UsbProfileGroupSettingsManager settings = mSettingsByProfileGroup.valueAt(i);
|
||||
pw.println("Settings for profile group " + parentUserId + ":");
|
||||
pw.increaseIndent();
|
||||
try {
|
||||
settings.dump(pw);
|
||||
} finally {
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user