Merge "Make default USB handling apps per profile group."

This commit is contained in:
Philip P. Moltmann
2016-09-16 17:22:22 +00:00
committed by Android (Google) Code Review
7 changed files with 1464 additions and 1068 deletions

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}
}
}
}
/**