1031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann/*
2031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * Copyright (C) 2011 The Android Open Source Project
3031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann *
4031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License");
5031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * you may not use this file except in compliance with the License.
6031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * You may obtain a copy of the License at
7031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann *
8031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann *      http://www.apache.org/licenses/LICENSE-2.0
9031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann *
10031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * Unless required by applicable law or agreed to in writing, software
11031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS,
12031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * See the License for the specific language governing permissions and
14031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * limitations under the License.
15031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann */
16031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
17031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannpackage com.android.server.usb;
18031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
19031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.annotation.NonNull;
20031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.app.PendingIntent;
21031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.content.ActivityNotFoundException;
22031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.content.Context;
23031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.content.Intent;
24031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.content.pm.ApplicationInfo;
25031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.content.pm.PackageManager;
26031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.content.pm.PackageManager.NameNotFoundException;
27031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.hardware.usb.UsbAccessory;
28031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.hardware.usb.UsbDevice;
29031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.hardware.usb.UsbManager;
30031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.os.Binder;
31031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.os.Process;
32031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.os.UserHandle;
33031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.util.Slog;
34031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.util.SparseBooleanArray;
35031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport com.android.internal.util.IndentingPrintWriter;
36031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
37031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport java.util.HashMap;
38031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
39031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannclass UsbUserSettingsManager {
40031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private static final String TAG = "UsbUserSettingsManager";
41031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private static final boolean DEBUG = false;
42031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
43031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final UserHandle mUser;
44031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final boolean mDisablePermissionDialogs;
45031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
46031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final Context mUserContext;
47031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final PackageManager mPackageManager;
48031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
49031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    // Temporary mapping USB device name to list of UIDs with permissions for the device
50031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final HashMap<String, SparseBooleanArray> mDevicePermissionMap =
51031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            new HashMap<String, SparseBooleanArray>();
52031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    // Temporary mapping UsbAccessory to list of UIDs with permissions for the accessory
53031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final HashMap<UsbAccessory, SparseBooleanArray> mAccessoryPermissionMap =
54031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            new HashMap<UsbAccessory, SparseBooleanArray>();
55031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
56031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final Object mLock = new Object();
57031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
58031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public UsbUserSettingsManager(Context context, UserHandle user) {
59031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        if (DEBUG) Slog.v(TAG, "Creating settings for " + user);
60031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
61031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        try {
62031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            mUserContext = context.createPackageContextAsUser("android", 0, user);
63031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        } catch (NameNotFoundException e) {
64031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            throw new RuntimeException("Missing android package");
65031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
66031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
67031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        mPackageManager = mUserContext.getPackageManager();
68031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
69031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        mUser = user;
70031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
71031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        mDisablePermissionDialogs = context.getResources().getBoolean(
72031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                com.android.internal.R.bool.config_disableUsbPermissionDialogs);
73031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
74031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
75031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /**
76031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * Remove all access permission for a device.
77031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
78031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * @param device The device the permissions are for
79031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     */
80031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    void removeDevicePermissions(@NonNull UsbDevice device) {
81031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mLock) {
82031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            mDevicePermissionMap.remove(device.getDeviceName());
83031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
84031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
85031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
86031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /**
87031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * Remove all access permission for a accessory.
88031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
89031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * @param accessory The accessory the permissions are for
90031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     */
91031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    void removeAccessoryPermissions(@NonNull UsbAccessory accessory) {
92031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mLock) {
93031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            mAccessoryPermissionMap.remove(accessory);
94031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
95031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
96031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
97031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
98031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public boolean hasPermission(UsbDevice device) {
99031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mLock) {
100031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            int uid = Binder.getCallingUid();
101031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
102031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                return true;
103031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
104031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());
105031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (uidList == null) {
106031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                return false;
107031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
108031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            return uidList.get(uid);
109031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
110031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
111031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
112031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public boolean hasPermission(UsbAccessory accessory) {
113031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mLock) {
114031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            int uid = Binder.getCallingUid();
115031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
116031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                return true;
117031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
118031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
119031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (uidList == null) {
120031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                return false;
121031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
122031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            return uidList.get(uid);
123031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
124031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
125031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
126031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public void checkPermission(UsbDevice device) {
127031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        if (!hasPermission(device)) {
128031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            throw new SecurityException("User has not given permission to device " + device);
129031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
130031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
131031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
132031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public void checkPermission(UsbAccessory accessory) {
133031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        if (!hasPermission(accessory)) {
134031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            throw new SecurityException("User has not given permission to accessory " + accessory);
135031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
136031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
137031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
138031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private void requestPermissionDialog(Intent intent, String packageName, PendingIntent pi) {
139031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        final int uid = Binder.getCallingUid();
140031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
141031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        // compare uid with packageName to foil apps pretending to be someone else
142031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        try {
143031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            ApplicationInfo aInfo = mPackageManager.getApplicationInfo(packageName, 0);
144031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (aInfo.uid != uid) {
145031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                throw new IllegalArgumentException("package " + packageName +
146031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                        " does not match caller's uid " + uid);
147031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
148031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        } catch (PackageManager.NameNotFoundException e) {
149031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            throw new IllegalArgumentException("package " + packageName + " not found");
150031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
151031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
152031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        long identity = Binder.clearCallingIdentity();
153031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        intent.setClassName("com.android.systemui",
154031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                "com.android.systemui.usb.UsbPermissionActivity");
155031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
156031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        intent.putExtra(Intent.EXTRA_INTENT, pi);
157031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        intent.putExtra("package", packageName);
158031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        intent.putExtra(Intent.EXTRA_UID, uid);
159031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        try {
160031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            mUserContext.startActivityAsUser(intent, mUser);
161031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        } catch (ActivityNotFoundException e) {
162031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            Slog.e(TAG, "unable to start UsbPermissionActivity");
163031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        } finally {
164031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            Binder.restoreCallingIdentity(identity);
165031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
166031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
167031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
168031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public void requestPermission(UsbDevice device, String packageName, PendingIntent pi) {
169031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann      Intent intent = new Intent();
170031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
171031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        // respond immediately if permission has already been granted
172031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann      if (hasPermission(device)) {
173031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            intent.putExtra(UsbManager.EXTRA_DEVICE, device);
174031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
175031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            try {
176031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pi.send(mUserContext, 0, intent);
177031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            } catch (PendingIntent.CanceledException e) {
178031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");
179031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
180031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            return;
181031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
182031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
183031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        // start UsbPermissionActivity so user can choose an activity
184031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
185031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        requestPermissionDialog(intent, packageName, pi);
186031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
187031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
188031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi) {
189031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        Intent intent = new Intent();
190031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
191031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        // respond immediately if permission has already been granted
192031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        if (hasPermission(accessory)) {
193031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
194031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
195031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            try {
196031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pi.send(mUserContext, 0, intent);
197031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            } catch (PendingIntent.CanceledException e) {
198031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");
199031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
200031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            return;
201031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
202031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
203031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
204031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        requestPermissionDialog(intent, packageName, pi);
205031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
206031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
207031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public void grantDevicePermission(UsbDevice device, int uid) {
208031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mLock) {
209031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            String deviceName = device.getDeviceName();
210031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
211031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (uidList == null) {
212031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                uidList = new SparseBooleanArray(1);
213031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                mDevicePermissionMap.put(deviceName, uidList);
214031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
215031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            uidList.put(uid, true);
216031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
217031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
218031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
219031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
220031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mLock) {
221031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
222031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (uidList == null) {
223031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                uidList = new SparseBooleanArray(1);
224031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                mAccessoryPermissionMap.put(accessory, uidList);
225031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
226031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            uidList.put(uid, true);
227031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
228031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
229031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann
230031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public void dump(IndentingPrintWriter pw) {
231031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mLock) {
232031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            pw.println("Device permissions:");
233031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            for (String deviceName : mDevicePermissionMap.keySet()) {
234031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pw.print("  " + deviceName + ": ");
235031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
236031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                int count = uidList.size();
237031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                for (int i = 0; i < count; i++) {
238031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                    pw.print(Integer.toString(uidList.keyAt(i)) + " ");
239031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                }
240031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pw.println();
241031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
242031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            pw.println("Accessory permissions:");
243031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            for (UsbAccessory accessory : mAccessoryPermissionMap.keySet()) {
244031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pw.print("  " + accessory + ": ");
245031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
246031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                int count = uidList.size();
247031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                for (int i = 0; i < count; i++) {
248031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                    pw.print(Integer.toString(uidList.keyAt(i)) + " ");
249031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                }
250031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pw.println();
251031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            }
252031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        }
253031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    }
254031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann}
255