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

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

Merge "Allow connection from secondary profiles"

parents 6abee0ef 031cee90
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ public class UsbDeviceManager {
    private final Context mContext;
    private final ContentResolver mContentResolver;
    @GuardedBy("mLock")
    private UsbSettingsManager mCurrentSettings;
    private UsbUserSettingsManager mCurrentUserSettings;
    private NotificationManager mNotificationManager;
    private final boolean mHasUsbAccessory;
    private boolean mUseUsbNotification;
@@ -150,6 +150,7 @@ public class UsbDeviceManager {
    private String[] mAccessoryStrings;
    private UsbDebuggingManager mDebuggingManager;
    private final UsbAlsaManager mUsbAlsaManager;
    private final UsbSettingsManager mSettingsManager;
    private Intent mBroadcastedIntent;

    private class AdbSettingsObserver extends ContentObserver {
@@ -192,9 +193,11 @@ public class UsbDeviceManager {
        }
    };

    public UsbDeviceManager(Context context, UsbAlsaManager alsaManager) {
    public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
            UsbSettingsManager settingsManager) {
        mContext = context;
        mUsbAlsaManager = alsaManager;
        mSettingsManager = settingsManager;
        mContentResolver = context.getContentResolver();
        PackageManager pm = mContext.getPackageManager();
        mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
@@ -218,9 +221,9 @@ public class UsbDeviceManager {
                new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
    }

    private UsbSettingsManager getCurrentSettings() {
    private UsbUserSettingsManager getCurrentUserSettings() {
        synchronized (mLock) {
            return mCurrentSettings;
            return mCurrentUserSettings;
        }
    }

@@ -255,10 +258,10 @@ public class UsbDeviceManager {
        mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
    }

    public void setCurrentUser(int userId, UsbSettingsManager settings) {
    public void setCurrentUser(int newCurrentUserId, UsbUserSettingsManager settings) {
        synchronized (mLock) {
            mCurrentSettings = settings;
            mHandler.obtainMessage(MSG_USER_SWITCHED, userId, 0).sendToTarget();
            mCurrentUserSettings = settings;
            mHandler.obtainMessage(MSG_USER_SWITCHED, newCurrentUserId, 0).sendToTarget();
        }
    }

@@ -571,7 +574,7 @@ public class UsbDeviceManager {
                    Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
                    // defer accessoryAttached if system is not ready
                    if (mBootCompleted) {
                        getCurrentSettings().accessoryAttached(mCurrentAccessory);
                        getCurrentUserSettings().accessoryAttached(mCurrentAccessory);
                    } // else handle in boot completed
                } else {
                    Slog.e(TAG, "nativeGetAccessoryStrings failed");
@@ -584,7 +587,7 @@ public class UsbDeviceManager {

                if (mCurrentAccessory != null) {
                    if (mBootCompleted) {
                        getCurrentSettings().accessoryDetached(mCurrentAccessory);
                        mSettingsManager.usbAccessoryRemoved(mCurrentAccessory);
                    }
                    mCurrentAccessory = null;
                    mAccessoryStrings = null;
@@ -764,7 +767,7 @@ public class UsbDeviceManager {
                case MSG_BOOT_COMPLETED:
                    mBootCompleted = true;
                    if (mCurrentAccessory != null) {
                        getCurrentSettings().accessoryAttached(mCurrentAccessory);
                        getCurrentUserSettings().accessoryAttached(mCurrentAccessory);
                    }
                    if (mDebuggingManager != null) {
                        mDebuggingManager.setAdbEnabled(mAdbEnabled);
@@ -947,7 +950,7 @@ public class UsbDeviceManager {
    }

    /* opens the currently attached USB accessory */
    public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
    public ParcelFileDescriptor openAccessory(UsbAccessory accessory, UsbUserSettingsManager settings) {
        UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
        if (currentAccessory == null) {
            throw new IllegalArgumentException("no accessory attached");
@@ -958,7 +961,7 @@ public class UsbDeviceManager {
                    + currentAccessory;
            throw new IllegalArgumentException(error);
        }
        getCurrentSettings().checkPermission(accessory);
        settings.checkPermission(accessory);
        return nativeOpenAccessory();
    }

+18 −13
Original line number Diff line number Diff line
@@ -32,8 +32,6 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;

@@ -62,18 +60,21 @@ public class UsbHostManager {
    private ArrayList<UsbEndpoint> mNewEndpoints;

    private final UsbAlsaManager mUsbAlsaManager;
    private final UsbSettingsManager mSettingsManager;

    @GuardedBy("mLock")
    private UsbSettingsManager mCurrentSettings;
    private UsbUserSettingsManager mCurrentUserSettings;

    @GuardedBy("mLock")
    private ComponentName mUsbDeviceConnectionHandler;

    public UsbHostManager(Context context, UsbAlsaManager alsaManager) {
    public UsbHostManager(Context context, UsbAlsaManager alsaManager,
            UsbSettingsManager settingsManager) {
        mContext = context;
        mHostBlacklist = context.getResources().getStringArray(
                com.android.internal.R.array.config_usbHostBlacklist);
        mUsbAlsaManager = alsaManager;
        mSettingsManager = settingsManager;
        String deviceConnectionHandler = context.getResources().getString(
                com.android.internal.R.string.config_UsbDeviceConnectionHandling_component);
        if (!TextUtils.isEmpty(deviceConnectionHandler)) {
@@ -82,15 +83,15 @@ public class UsbHostManager {
        }
    }

    public void setCurrentSettings(UsbSettingsManager settings) {
    public void setCurrentUserSettings(UsbUserSettingsManager settings) {
        synchronized (mLock) {
            mCurrentSettings = settings;
            mCurrentUserSettings = settings;
        }
    }

    private UsbSettingsManager getCurrentSettings() {
    private UsbUserSettingsManager getCurrentUserSettings() {
        synchronized (mLock) {
            return mCurrentSettings;
            return mCurrentUserSettings;
        }
    }

@@ -247,11 +248,14 @@ public class UsbHostManager {
                                new UsbConfiguration[mNewConfigurations.size()]));
                mDevices.put(mNewDevice.getDeviceName(), mNewDevice);
                Slog.d(TAG, "Added device " + mNewDevice);

                // It is fine to call this only for the current user as all broadcasts are sent to
                // all profiles of the user and the dialogs should only show once.
                ComponentName usbDeviceConnectionHandler = getUsbDeviceConnectionHandler();
                if (usbDeviceConnectionHandler == null) {
                    getCurrentSettings().deviceAttached(mNewDevice);
                    getCurrentUserSettings().deviceAttached(mNewDevice);
                } else {
                    getCurrentSettings().deviceAttachedForFixedHandler(mNewDevice,
                    getCurrentUserSettings().deviceAttachedForFixedHandler(mNewDevice,
                            usbDeviceConnectionHandler);
                }
                mUsbAlsaManager.usbDeviceAdded(mNewDevice);
@@ -273,7 +277,8 @@ public class UsbHostManager {
            UsbDevice device = mDevices.remove(deviceName);
            if (device != null) {
                mUsbAlsaManager.usbDeviceRemoved(device);
                getCurrentSettings().deviceDetached(device);
                mSettingsManager.usbDeviceRemoved(device);
                getCurrentUserSettings().usbDeviceRemoved(device);
            }
        }
    }
@@ -301,7 +306,7 @@ public class UsbHostManager {
    }

    /* Opens the specified USB device */
    public ParcelFileDescriptor openDevice(String deviceName) {
    public ParcelFileDescriptor openDevice(String deviceName, UsbUserSettingsManager settings) {
        synchronized (mLock) {
            if (isBlackListed(deviceName)) {
                throw new SecurityException("USB device is on a restricted bus");
@@ -312,7 +317,7 @@ public class UsbHostManager {
                throw new IllegalArgumentException(
                        "device " + deviceName + " does not exist or is restricted");
            }
            getCurrentSettings().checkPermission(device);
            settings.checkPermission(device);
            return nativeOpenDevice(deviceName);
        }
    }
+114 −52
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.usb;

import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
@@ -36,7 +37,6 @@ import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;
@@ -75,57 +75,65 @@ public class UsbService extends IUsbManager.Stub {
                mUsbService.bootCompleted();
            }
        }

        @Override
        public void onSwitchUser(int newUserId) {
            mUsbService.onSwitchUser(newUserId);
        }

        @Override
        public void onStopUser(int userHandle) {
            mUsbService.onStopUser(userHandle);
        }
    }

    private static final String TAG = "UsbService";

    private final Context mContext;
    private final UserManager mUserManager;

    private UsbDeviceManager mDeviceManager;
    private UsbHostManager mHostManager;
    private UsbPortManager mPortManager;
    private final UsbAlsaManager mAlsaManager;

    private final Object mLock = new Object();
    private final UsbSettingsManager mSettingsManager;

    /** Map from {@link UserHandle} to {@link UsbSettingsManager} */
    /**
     * The user id of the current user. There might be several profiles (with separate user ids)
     * per user.
     */
    @GuardedBy("mLock")
    private final SparseArray<UsbSettingsManager>
            mSettingsByUser = new SparseArray<UsbSettingsManager>();
    private @UserIdInt int mCurrentUserId;

    private UsbSettingsManager getSettingsForUser(int userId) {
        synchronized (mLock) {
            UsbSettingsManager settings = mSettingsByUser.get(userId);
            if (settings == null) {
                settings = new UsbSettingsManager(mContext, new UserHandle(userId));
                mSettingsByUser.put(userId, settings);
            }
            return settings;
        }
    private final Object mLock = new Object();

    private UsbUserSettingsManager getSettingsForUser(@UserIdInt int userIdInt) {
        return mSettingsManager.getSettingsForUser(userIdInt);
    }

    public UsbService(Context context) {
        mContext = context;

        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mSettingsManager = new UsbSettingsManager(context);
        mAlsaManager = new UsbAlsaManager(context);

        final PackageManager pm = mContext.getPackageManager();
        if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
            mHostManager = new UsbHostManager(context, mAlsaManager);
            mHostManager = new UsbHostManager(context, mAlsaManager, mSettingsManager);
        }
        if (new File("/sys/class/android_usb").exists()) {
            mDeviceManager = new UsbDeviceManager(context, mAlsaManager);
            mDeviceManager = new UsbDeviceManager(context, mAlsaManager, mSettingsManager);
        }
        if (mHostManager != null || mDeviceManager != null) {
            mPortManager = new UsbPortManager(context);
        }

        setCurrentUser(UserHandle.USER_SYSTEM);
        onSwitchUser(UserHandle.USER_SYSTEM);

        final IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        filter.addAction(Intent.ACTION_USER_STOPPED);
        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
        mContext.registerReceiver(mReceiver, filter, null, null);
    }
@@ -133,15 +141,8 @@ public class UsbService extends IUsbManager.Stub {
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
            final String action = intent.getAction();
            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                setCurrentUser(userId);
            } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
                synchronized (mLock) {
                    mSettingsByUser.remove(userId);
                }
            } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
                    .equals(action)) {
                if (mDeviceManager != null) {
                    mDeviceManager.updateUserRestrictions();
@@ -150,16 +151,37 @@ public class UsbService extends IUsbManager.Stub {
        }
    };

    private void setCurrentUser(int userId) {
        final UsbSettingsManager userSettings = getSettingsForUser(userId);
    /**
     * Set new {@link #mCurrentUserId} and propagate it to other modules.
     *
     * @param newUserId The user id of the new current user.
     */
    private void onSwitchUser(@UserIdInt int newUserId) {
        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
            // module.
            UsbUserSettingsManager userSettings = getSettingsForUser(newUserId);
            if (mHostManager != null) {
            mHostManager.setCurrentSettings(userSettings);
                mHostManager.setCurrentUserSettings(userSettings);
            }
            if (mDeviceManager != null) {
            mDeviceManager.setCurrentUser(userId, userSettings);
                mDeviceManager.setCurrentUser(newUserId, userSettings);
            }
        }
    }

    /**
     * Execute operations when a user is stopped.
     *
     * @param stoppedUserId The id of the used that is stopped
     */
    private void onStopUser(@UserIdInt int stoppedUserId) {
        mSettingsManager.remove(stoppedUserId);
    }

    public void systemReady() {
        mAlsaManager.systemReady();

@@ -188,16 +210,47 @@ public class UsbService extends IUsbManager.Stub {
        }
    }

    /**
     * Check if the calling user is in the same profile group as the {@link #mCurrentUserId
     * current user}.
     *
     * @return Iff the caller is in the current user's profile group
     */
    private boolean isCallerInCurrentUserProfileGroupLocked() {
        int userIdInt = UserHandle.getCallingUserId();

        long ident = clearCallingIdentity();
        try {
            return mUserManager.isSameProfileGroup(userIdInt, mCurrentUserId);
        } finally {
            restoreCallingIdentity(ident);
        }
    }

    /* Opens the specified USB device (host mode) */
    @Override
    public ParcelFileDescriptor openDevice(String deviceName) {
        ParcelFileDescriptor fd = null;

        if (mHostManager != null) {
            return mHostManager.openDevice(deviceName);
            synchronized (mLock) {
                if (deviceName != null) {
                    int userIdInt = UserHandle.getCallingUserId();
                    boolean isCurrentUser = isCallerInCurrentUserProfileGroupLocked();

                    if (isCurrentUser) {
                        fd = mHostManager.openDevice(deviceName, getSettingsForUser(userIdInt));
                    } else {
            return null;
                        Slog.w(TAG, "Cannot open " + deviceName + " for user " + userIdInt +
                               " as user is not active.");
                    }
                }
            }
        }

        return fd;
    }

    /* returns the currently attached USB accessory (device mode) */
    @Override
    public UsbAccessory getCurrentAccessory() {
@@ -212,12 +265,23 @@ public class UsbService extends IUsbManager.Stub {
    @Override
    public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
        if (mDeviceManager != null) {
            return mDeviceManager.openAccessory(accessory);
            int userIdInt = UserHandle.getCallingUserId();

            synchronized (mLock) {
                boolean isCurrentUser = isCallerInCurrentUserProfileGroupLocked();

                if (isCurrentUser) {
                    return mDeviceManager.openAccessory(accessory, getSettingsForUser(userIdInt));
                } else {
            return null;
                    Slog.w(TAG, "Cannot open " + accessory + " for user " + userIdInt +
                            " as user is not active.");
                }
            }
        }

        return null;
    }

    @Override
    public void setDevicePackage(UsbDevice device, String packageName, int userId) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
@@ -388,9 +452,16 @@ public class UsbService extends IUsbManager.Stub {
    @Override
    public void setUsbDeviceConnectionHandler(ComponentName usbDeviceConnectionHandler) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
        synchronized (mLock) {
            if (mCurrentUserId == UserHandle.getCallingUserId()) {
                if (mHostManager != null) {
                    mHostManager.setUsbDeviceConnectionHandler(usbDeviceConnectionHandler);
                }
            } else {
                throw new IllegalArgumentException("Only the current user can register a usb " +
                        "connection handler");
            }
        }
    }

    @Override
@@ -414,16 +485,7 @@ public class UsbService extends IUsbManager.Stub {
                }
                mAlsaManager.dump(pw);

                synchronized (mLock) {
                    for (int i = 0; i < mSettingsByUser.size(); i++) {
                        final int userId = mSettingsByUser.keyAt(i);
                        final UsbSettingsManager settings = mSettingsByUser.valueAt(i);
                        pw.println("Settings for user " + userId + ":");
                        pw.increaseIndent();
                        settings.dump(pw);
                        pw.decreaseIndent();
                    }
                }
                mSettingsManager.dump(pw);
            } else if (args.length == 4 && "set-port-roles".equals(args[0])) {
                final String portId = args[1];
                final int powerRole;
+84 −1223

File changed.

Preview size limit exceeded, changes collapsed.

+1288 −0

File added.

Preview size limit exceeded, changes collapsed.