102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood/*
2031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * Copyright (C) 2016 The Android Open Source Project
302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood *
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
702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood *
8031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann *       http://www.apache.org/licenses/LICENSE-2.0
902eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood *
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.
1502eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood */
1602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
1702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodpackage com.android.server.usb;
1802eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
19031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.annotation.NonNull;
20031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.annotation.UserIdInt;
2102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodimport android.content.Context;
2202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwoodimport android.content.Intent;
23a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.UserInfo;
24c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodimport android.hardware.usb.UsbAccessory;
25c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodimport android.hardware.usb.UsbDevice;
26c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodimport android.hardware.usb.UsbManager;
275ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
28a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.os.UserManager;
29fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwoodimport android.util.Slog;
30031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport android.util.SparseArray;
31bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann
32031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmannimport com.android.internal.annotations.GuardedBy;
332dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brownimport com.android.internal.util.IndentingPrintWriter;
3402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
35031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann/**
36031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann * Maintains all {@link UsbUserSettingsManager} for all users.
37031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann */
38fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyclass UsbSettingsManager {
39031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private static final String LOG_TAG = UsbSettingsManager.class.getSimpleName();
40fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood    private static final boolean DEBUG = false;
41fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
42031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /** Context to be used by this module */
43031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final @NonNull Context mContext;
44163e4b6ae8a51421c8a9cccfdc2fe872afd09971Daichi Hirono
45031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /** Map from user id to {@link UsbUserSettingsManager} for the user */
46031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    @GuardedBy("mSettingsByUser")
47031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    private final SparseArray<UsbUserSettingsManager> mSettingsByUser = new SparseArray<>();
48fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
49a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
50a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Map from the parent profile's user id to {@link UsbProfileGroupSettingsManager} for the
51a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * group.
52a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
53a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    @GuardedBy("mSettingsByProfileGroup")
54a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final SparseArray<UsbProfileGroupSettingsManager> mSettingsByProfileGroup
55a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            = new SparseArray<>();
56a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private UserManager mUserManager;
57a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
58031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    public UsbSettingsManager(@NonNull Context context) {
5902eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        mContext = context;
60a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
6102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
6202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
63fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    /**
64031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * Get the {@link UsbUserSettingsManager} for a user.
65031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
66031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * @param userId The id of the user
67031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
68031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * @return The settings for the user
69fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey     */
70031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    @NonNull UsbUserSettingsManager getSettingsForUser(@UserIdInt int userId) {
71031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mSettingsByUser) {
72031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            UsbUserSettingsManager settings = mSettingsByUser.get(userId);
73031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            if (settings == null) {
74031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                settings = new UsbUserSettingsManager(mContext, new UserHandle(userId));
75031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                mSettingsByUser.put(userId, settings);
76fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            }
77031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            return settings;
78fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        }
79fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    }
80fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
81031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /**
82a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Get the {@link UsbProfileGroupSettingsManager} for a user.
83a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
84a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param user Any user of the profile group
85a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
86a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @return The settings for the profile group
87a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
88a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    @NonNull UsbProfileGroupSettingsManager getSettingsForProfileGroup(@NonNull UserHandle user) {
89a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        UserHandle parentUser;
90a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
91a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        UserInfo parentUserInfo = mUserManager.getProfileParent(user.getIdentifier());
92a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        if (parentUserInfo != null) {
93a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            parentUser = parentUserInfo.getUserHandle();
94a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } else {
95a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            parentUser = user;
96a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
97a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
98a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mSettingsByProfileGroup) {
99a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            UsbProfileGroupSettingsManager settings = mSettingsByProfileGroup.get(
100a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    parentUser.getIdentifier());
101a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (settings == null) {
102a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                settings = new UsbProfileGroupSettingsManager(mContext, parentUser, this);
103a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                mSettingsByProfileGroup.put(parentUser.getIdentifier(), settings);
104a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
105a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            return settings;
106a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
107a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
108a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
109a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
110031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * Remove the settings for a user.
111031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
112880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * @param userToRemove The user to remove
113031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     */
114880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    void remove(@NonNull UserHandle userToRemove) {
115031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mSettingsByUser) {
116880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            mSettingsByUser.remove(userToRemove.getIdentifier());
117880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        }
118880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
119880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        synchronized (mSettingsByProfileGroup) {
120880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            if (mSettingsByProfileGroup.indexOfKey(userToRemove.getIdentifier()) >= 0) {
121880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                // The user to remove is the parent user of the group. The parent is the last user
122880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                // that gets removed. All state will be removed with the user
123880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                mSettingsByProfileGroup.remove(userToRemove.getIdentifier());
124880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            } else {
125880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                // We cannot find the parent user of the user that is removed, hence try to remove
126880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                // it from all profile groups.
127880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                int numProfileGroups = mSettingsByProfileGroup.size();
128880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                for (int i = 0; i < numProfileGroups; i++) {
129880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    mSettingsByProfileGroup.valueAt(i).removeAllDefaultsForUser(userToRemove);
130880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                }
131880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            }
13202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        }
13302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
13402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
135031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /**
136031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * Dump all settings of all users.
137031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
138031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * @param pw The writer to dump to
139031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     */
140031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    void dump(@NonNull IndentingPrintWriter pw) {
141031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mSettingsByUser) {
142a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            int numUsers = mSettingsByUser.size();
143a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            for (int i = 0; i < numUsers; i++) {
144031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                final int userId = mSettingsByUser.keyAt(i);
145031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                final UsbUserSettingsManager settings = mSettingsByUser.valueAt(i);
146031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pw.println("Settings for user " + userId + ":");
147031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                pw.increaseIndent();
148031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                try {
149031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                    settings.dump(pw);
150031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                } finally {
151031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                    pw.decreaseIndent();
15202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood                }
15302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood            }
15402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        }
155a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
156a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mSettingsByProfileGroup) {
157a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            int numProfileGroups = mSettingsByProfileGroup.size();
158a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            for (int i = 0; i < numProfileGroups; i++) {
159a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                final int parentUserId = mSettingsByProfileGroup.keyAt(i);
160a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                final UsbProfileGroupSettingsManager settings = mSettingsByProfileGroup.valueAt(i);
161a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                pw.println("Settings for profile group " + parentUserId + ":");
162a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                pw.increaseIndent();
163a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                try {
164a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    settings.dump(pw);
165a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                } finally {
166a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    pw.decreaseIndent();
167a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
168a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
169a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
17002eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
17102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood
172031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /**
173031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * Remove temporary access permission and broadcast that a device was removed.
174031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
175031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * @param device The device that is removed
176031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     */
177031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    void usbDeviceRemoved(@NonNull UsbDevice device) {
178031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mSettingsByUser) {
179031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            for (int i = 0; i < mSettingsByUser.size(); i++) {
180031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                // clear temporary permissions for the device
181031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                mSettingsByUser.valueAt(i).removeDevicePermissions(device);
18202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood            }
18302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        }
184c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood
18502eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
18642a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
188163e4b6ae8a51421c8a9cccfdc2fe872afd09971Daichi Hirono
189031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        if (DEBUG) {
190031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            Slog.d(LOG_TAG, "usbDeviceRemoved, sending " + intent);
1917a976a43700a17a29a0671c8456e41ec0a1086b9Mike Lockwood        }
1925ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
193c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood    }
194c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood
195031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    /**
196031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * Remove temporary access permission and broadcast that a accessory was removed.
197031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     *
198031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     * @param accessory The accessory that is removed
199031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann     */
200031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann    void usbAccessoryRemoved(@NonNull UsbAccessory accessory) {
201031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        synchronized (mSettingsByUser) {
202031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann            for (int i = 0; i < mSettingsByUser.size(); i++) {
203031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                // clear temporary permissions for the accessory
204031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann                mSettingsByUser.valueAt(i).removeAccessoryPermissions(accessory);
2053a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood            }
2063a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood        }
2073a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood
208031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
20942a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
2103a68b8338b431eb15d28e92f06452efbbda9493eMike Lockwood        intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
211031cee90a350b7be93ef939630b277cfb28c171bPhilip P. Moltmann        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
212163e4b6ae8a51421c8a9cccfdc2fe872afd09971Daichi Hirono    }
21302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood}
214