12423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood/*
22423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * Copyright (C) 2010 The Android Open Source Project
32423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood *
42423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
52423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * you may not use this file except in compliance with the License.
62423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * You may obtain a copy of the License at
72423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood *
82423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
92423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood *
102423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * Unless required by applicable law or agreed to in writing, software
112423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
122423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1346d0adf8256a42416584765625852b6e48497c90Mike Lockwood * See the License for the specific language governing permissions an
142423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood * limitations under the License.
152423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood */
162423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood
1702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodpackage com.android.server.usb;
182423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood
193a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwoodimport android.app.PendingIntent;
20fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.content.BroadcastReceiver;
212423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwoodimport android.content.Context;
22fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.content.Intent;
23fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.content.IntentFilter;
2402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodimport android.content.pm.PackageManager;
25c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodimport android.hardware.usb.IUsbManager;
26c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodimport android.hardware.usb.UsbAccessory;
27c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodimport android.hardware.usb.UsbDevice;
28e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodimport android.os.Bundle;
29e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodimport android.os.ParcelFileDescriptor;
30fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.UserHandle;
31fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.util.SparseArray;
32fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
33fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
342423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood
352423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwoodimport java.io.File;
3602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodimport java.io.FileDescriptor;
3702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodimport java.io.PrintWriter;
382423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood
392423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood/**
4046d0adf8256a42416584765625852b6e48497c90Mike Lockwood * UsbService manages all USB related state, including both host and device support.
4146d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Host related events and calls are delegated to UsbHostManager, and device related
4246d0adf8256a42416584765625852b6e48497c90Mike Lockwood * support is delegated to UsbDeviceManager.
432423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood */
4402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodpublic class UsbService extends IUsbManager.Stub {
45fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private static final String TAG = "UsbService";
46fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
472423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood    private final Context mContext;
48fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
4946d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private UsbDeviceManager mDeviceManager;
5046d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private UsbHostManager mHostManager;
51ddc6cade00bbc08fa668cf937f606538f5c29a80Mike Lockwood
52fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private final Object mLock = new Object();
53fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
54fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    /** Map from {@link UserHandle} to {@link UsbSettingsManager} */
55fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    // @GuardedBy("mLock")
56fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private final SparseArray<UsbSettingsManager>
57fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            mSettingsByUser = new SparseArray<UsbSettingsManager>();
58fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
59fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private UsbSettingsManager getSettingsForUser(int userId) {
60fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        synchronized (mLock) {
61fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            UsbSettingsManager settings = mSettingsByUser.get(userId);
62fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            if (settings == null) {
63fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                settings = new UsbSettingsManager(mContext, new UserHandle(userId));
64fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                mSettingsByUser.put(userId, settings);
65fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            }
66fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            return settings;
67fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        }
68fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    }
691c0e543638fa940651b675645146fd71c2ebd9b9Mike Lockwood
70770126a678ccc9328a89407ffc82f4d998b25427Mike Lockwood    public UsbService(Context context) {
71770126a678ccc9328a89407ffc82f4d998b25427Mike Lockwood        mContext = context;
72fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
73fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final PackageManager pm = mContext.getPackageManager();
7446d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
75fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            mHostManager = new UsbHostManager(context);
762423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood        }
7702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        if (new File("/sys/class/android_usb").exists()) {
78fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            mDeviceManager = new UsbDeviceManager(context);
79fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        }
80fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
81fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        setCurrentUser(UserHandle.USER_OWNER);
82fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
83fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final IntentFilter userFilter = new IntentFilter();
84fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        userFilter.addAction(Intent.ACTION_USER_SWITCHED);
85fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        userFilter.addAction(Intent.ACTION_USER_STOPPED);
86fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        mContext.registerReceiver(mUserReceiver, userFilter, null, null);
87fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    }
88fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
89fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
90fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        @Override
91fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        public void onReceive(Context context, Intent intent) {
92fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
93fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            final String action = intent.getAction();
94fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
95fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                setCurrentUser(userId);
96fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
97fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                synchronized (mLock) {
98fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                    mSettingsByUser.remove(userId);
99fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                }
100fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            }
101fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        }
102fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    };
103fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
104fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private void setCurrentUser(int userId) {
105fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final UsbSettingsManager userSettings = getSettingsForUser(userId);
106fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        if (mHostManager != null) {
107fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            mHostManager.setCurrentSettings(userSettings);
108fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        }
109fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        if (mDeviceManager != null) {
110fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            mDeviceManager.setCurrentSettings(userSettings);
111a8e3a898a2bc004ca1fcd278b68f5da5c344afbbMike Lockwood        }
112da39f0e87814c5acb8b6319a1877b93197fb910eMike Lockwood    }
113da39f0e87814c5acb8b6319a1877b93197fb910eMike Lockwood
11402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    public void systemReady() {
11546d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mDeviceManager != null) {
11646d0adf8256a42416584765625852b6e48497c90Mike Lockwood            mDeviceManager.systemReady();
11746d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
11846d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mHostManager != null) {
11946d0adf8256a42416584765625852b6e48497c90Mike Lockwood            mHostManager.systemReady();
1202423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood        }
1212423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood    }
1222423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood
123ddc6cade00bbc08fa668cf937f606538f5c29a80Mike Lockwood    /* Returns a list of all currently attached USB devices (host mdoe) */
124fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
125e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    public void getDeviceList(Bundle devices) {
12646d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mHostManager != null) {
12746d0adf8256a42416584765625852b6e48497c90Mike Lockwood            mHostManager.getDeviceList(devices);
128e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        }
129e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
130e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
131ddc6cade00bbc08fa668cf937f606538f5c29a80Mike Lockwood    /* Opens the specified USB device (host mode) */
132fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
133e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    public ParcelFileDescriptor openDevice(String deviceName) {
13446d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mHostManager != null) {
13546d0adf8256a42416584765625852b6e48497c90Mike Lockwood            return mHostManager.openDevice(deviceName);
13646d0adf8256a42416584765625852b6e48497c90Mike Lockwood        } else {
13746d0adf8256a42416584765625852b6e48497c90Mike Lockwood            return null;
1388b682ad08a8e55b3ce2cf58f3aff6d3464ab668bMike Lockwood        }
139e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
140e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
141ddc6cade00bbc08fa668cf937f606538f5c29a80Mike Lockwood    /* returns the currently attached USB accessory (device mode) */
142fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
1439182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood    public UsbAccessory getCurrentAccessory() {
14446d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mDeviceManager != null) {
14546d0adf8256a42416584765625852b6e48497c90Mike Lockwood            return mDeviceManager.getCurrentAccessory();
14646d0adf8256a42416584765625852b6e48497c90Mike Lockwood        } else {
14746d0adf8256a42416584765625852b6e48497c90Mike Lockwood            return null;
14846d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
1499182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood    }
1509182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood
151ddc6cade00bbc08fa668cf937f606538f5c29a80Mike Lockwood    /* opens the currently attached USB accessory (device mode) */
152fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
15302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
15446d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mDeviceManager != null) {
15502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            return mDeviceManager.openAccessory(accessory);
15646d0adf8256a42416584765625852b6e48497c90Mike Lockwood        } else {
15746d0adf8256a42416584765625852b6e48497c90Mike Lockwood            return null;
15802eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        }
15902eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
16002eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
161fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
162fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    public void setDevicePackage(UsbDevice device, String packageName, int userId) {
1637a976a43700a17a29a0671c8456e41ec0a1086b9Mike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
164fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getSettingsForUser(userId).setDevicePackage(device, packageName);
16502eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
16602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
167fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
168fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    public void setAccessoryPackage(UsbAccessory accessory, String packageName, int userId) {
1697a976a43700a17a29a0671c8456e41ec0a1086b9Mike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
170fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getSettingsForUser(userId).setAccessoryPackage(accessory, packageName);
17102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
17202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
173fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
1743a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood    public boolean hasDevicePermission(UsbDevice device) {
175fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final int userId = UserHandle.getCallingUserId();
176fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        return getSettingsForUser(userId).hasPermission(device);
1773a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood    }
1783a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood
179fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
1803a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood    public boolean hasAccessoryPermission(UsbAccessory accessory) {
181fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final int userId = UserHandle.getCallingUserId();
182fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        return getSettingsForUser(userId).hasPermission(accessory);
1833a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood    }
1843a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood
185fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
186fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) {
187fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final int userId = UserHandle.getCallingUserId();
188fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getSettingsForUser(userId).requestPermission(device, packageName, pi);
1893a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood    }
1903a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood
191fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
192fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    public void requestAccessoryPermission(
193fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            UsbAccessory accessory, String packageName, PendingIntent pi) {
194fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final int userId = UserHandle.getCallingUserId();
195fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getSettingsForUser(userId).requestPermission(accessory, packageName, pi);
1963a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood    }
1973a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood
198fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
19902eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    public void grantDevicePermission(UsbDevice device, int uid) {
2007a976a43700a17a29a0671c8456e41ec0a1086b9Mike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
201fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final int userId = UserHandle.getUserId(uid);
202fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getSettingsForUser(userId).grantDevicePermission(device, uid);
20302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
20402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
205fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
20602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
2077a976a43700a17a29a0671c8456e41ec0a1086b9Mike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
208fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final int userId = UserHandle.getUserId(uid);
209fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getSettingsForUser(userId).grantAccessoryPermission(accessory, uid);
21002eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
21102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
212fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
213fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    public boolean hasDefaults(String packageName, int userId) {
2147a976a43700a17a29a0671c8456e41ec0a1086b9Mike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
215fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        return getSettingsForUser(userId).hasDefaults(packageName);
21602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
21702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
218fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
219fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    public void clearDefaults(String packageName, int userId) {
2207a976a43700a17a29a0671c8456e41ec0a1086b9Mike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
221fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getSettingsForUser(userId).clearDefaults(packageName);
2229182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood    }
2239182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood
224fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
225f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood    public void setCurrentFunction(String function, boolean makeDefault) {
22602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
22702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        if (mDeviceManager != null) {
228166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood            mDeviceManager.setCurrentFunctions(function, makeDefault);
22902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        } else {
23002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            throw new IllegalStateException("USB device mode not supported");
23102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
23202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    }
23302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
234fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
23502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    public void setMassStorageBackingFile(String path) {
23602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
23702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        if (mDeviceManager != null) {
23802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            mDeviceManager.setMassStorageBackingFile(path);
23902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        } else {
24002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            throw new IllegalStateException("USB device mode not supported");
24102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
24202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    }
24302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
244fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
2454e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
2464e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
2474e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey);
2484e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    }
2494e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby
250fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    @Override
2514e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    public void denyUsbDebugging() {
2524e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
2534e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        mDeviceManager.denyUsbDebugging();
2544e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    }
2554e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby
25602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    @Override
257fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
258fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
259fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
26002eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
26146d0adf8256a42416584765625852b6e48497c90Mike Lockwood        pw.println("USB Manager State:");
26246d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mDeviceManager != null) {
26302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood            mDeviceManager.dump(fd, pw);
26402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        }
26546d0adf8256a42416584765625852b6e48497c90Mike Lockwood        if (mHostManager != null) {
26646d0adf8256a42416584765625852b6e48497c90Mike Lockwood            mHostManager.dump(fd, pw);
26746d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
268fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
269fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        synchronized (mLock) {
270fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            for (int i = 0; i < mSettingsByUser.size(); i++) {
271fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                final int userId = mSettingsByUser.keyAt(i);
272fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                final UsbSettingsManager settings = mSettingsByUser.valueAt(i);
273fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                pw.increaseIndent();
274fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                pw.println("Settings for user " + userId + ":");
275fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                settings.dump(fd, pw);
276fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                pw.decreaseIndent();
277fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            }
278fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        }
279fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        pw.decreaseIndent();
28002eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
2812423607a32d63a0c646b17758ebeb4dc1d0b791fMike Lockwood}
282