1a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann/*
2a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * Copyright (C) 2016 The Android Open Source Project
3a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann *
4a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License");
5a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * you may not use this file except in compliance with the License.
6a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * You may obtain a copy of the License at
7a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann *
8a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann *      http://www.apache.org/licenses/LICENSE-2.0
9a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann *
10a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * Unless required by applicable law or agreed to in writing, software
11a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS,
12a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * See the License for the specific language governing permissions and
14a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann * limitations under the License.
15a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann */
16a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
17a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannpackage com.android.server.usb;
18a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
19733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmannimport static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
20733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
21a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.annotation.NonNull;
22a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.annotation.Nullable;
23a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.ActivityNotFoundException;
24a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.ComponentName;
25a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.Context;
26a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.Intent;
27a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.ActivityInfo;
28a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.ApplicationInfo;
29a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.PackageInfo;
30a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.PackageManager;
31a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.PackageManager.NameNotFoundException;
32a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.ResolveInfo;
33a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.pm.UserInfo;
34a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.content.res.XmlResourceParser;
355a633c6e4d9661c574ac34e891da22ec62b5e383Philip P. Moltmannimport android.hardware.usb.AccessoryFilter;
365a633c6e4d9661c574ac34e891da22ec62b5e383Philip P. Moltmannimport android.hardware.usb.DeviceFilter;
37a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.hardware.usb.UsbAccessory;
38a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.hardware.usb.UsbDevice;
39a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.hardware.usb.UsbManager;
40880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmannimport android.os.AsyncTask;
41a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.os.Environment;
42a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.os.UserHandle;
43a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.os.UserManager;
44371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport android.service.usb.UsbProfileGroupSettingsManagerProto;
45371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport android.service.usb.UsbSettingsAccessoryPreferenceProto;
46371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport android.service.usb.UsbSettingsDevicePreferenceProto;
47371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport android.service.usb.UserPackageProto;
48a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.util.AtomicFile;
49a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.util.Log;
50a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.util.Slog;
51733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmannimport android.util.SparseArray;
52733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmannimport android.util.SparseIntArray;
53a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport android.util.Xml;
54a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
55880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmannimport com.android.internal.annotations.GuardedBy;
56a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport com.android.internal.annotations.Immutable;
57a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport com.android.internal.content.PackageMonitor;
58a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport com.android.internal.util.FastXmlSerializer;
59a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport com.android.internal.util.XmlUtils;
60371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport com.android.internal.util.dump.DualDumpOutputStream;
61a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
62733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmannimport libcore.io.IoUtils;
63733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
64a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport org.xmlpull.v1.XmlPullParser;
65a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport org.xmlpull.v1.XmlPullParserException;
66a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
67a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.io.File;
68a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.io.FileInputStream;
69a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.io.FileNotFoundException;
70a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.io.FileOutputStream;
71a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.io.IOException;
72a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.nio.charset.StandardCharsets;
73a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.util.ArrayList;
74a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.util.HashMap;
75880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmannimport java.util.Iterator;
76a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannimport java.util.List;
77880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmannimport java.util.Map;
78a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
79a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmannclass UsbProfileGroupSettingsManager {
80a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private static final String TAG = UsbProfileGroupSettingsManager.class.getSimpleName();
81a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private static final boolean DEBUG = false;
82a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
83a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /** Legacy settings file, before multi-user */
84a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private static final File sSingleUserSettingsFile = new File(
85a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            "/data/system/usb_device_manager.xml");
86a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
87a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /** The parent user (main user of the profile group) */
88a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final UserHandle mParentUser;
89a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
90a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final AtomicFile mSettingsFile;
91a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final boolean mDisablePermissionDialogs;
92a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
93a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final Context mContext;
94a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
95a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final PackageManager mPackageManager;
96a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
97a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final UserManager mUserManager;
98a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final @NonNull UsbSettingsManager mSettingsManager;
99a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
100880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    /** Maps DeviceFilter to user preferred application package */
101880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    @GuardedBy("mLock")
102a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final HashMap<DeviceFilter, UserPackage> mDevicePreferenceMap = new HashMap<>();
103880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
104880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    /** Maps AccessoryFilter to user preferred application package */
105880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    @GuardedBy("mLock")
106a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final HashMap<AccessoryFilter, UserPackage> mAccessoryPreferenceMap = new HashMap<>();
107a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
108a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final Object mLock = new Object();
109a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
110a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
111880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * If a async task to persist the mDevicePreferenceMap and mAccessoryPreferenceMap is currently
112880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * scheduled.
113880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     */
114880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    @GuardedBy("mLock")
115880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    private boolean mIsWriteSettingsScheduled;
116880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
117880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    /**
118a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * A package of a user.
119a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
120a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    @Immutable
121a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private static class UserPackage {
122a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        /** User */
123a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        final @NonNull UserHandle user;
124a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
125a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        /** Package name */
126a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        final @NonNull String packageName;
127a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
128a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        /**
129a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann         * Create a description of a per user package.
130a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann         *
131a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann         * @param packageName The name of the package
132a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann         * @param user The user
133a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann         */
134a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        private UserPackage(@NonNull String packageName, @NonNull UserHandle user) {
135a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            this.packageName = packageName;
136a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            this.user = user;
137a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
138a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
139a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        @Override
140a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        public boolean equals(Object obj) {
141a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (!(obj instanceof UserPackage)) {
142a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                return false;
143a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } else {
144a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                UserPackage other = (UserPackage)obj;
145a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
146d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                return user.equals(other.user) && packageName.equals(other.packageName);
147a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
148a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
149a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
150a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        @Override
151a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        public int hashCode() {
152a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            int result = user.hashCode();
153a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            result = 31 * result + packageName.hashCode();
154a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            return result;
155a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
156a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
157a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        @Override
158a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        public String toString() {
159a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            return user.getIdentifier() + "/" + packageName;
160a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
161371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
162371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann        public void dump(DualDumpOutputStream dump, String idName, long id) {
163371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann            long token = dump.start(idName, id);
164371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
165371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann            dump.write("user_id", UserPackageProto.USER_ID, user.getIdentifier());
166371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann            dump.write("package_name", UserPackageProto.PACKAGE_NAME, packageName);
167371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
168371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann            dump.end(token);
169371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann        }
170a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
171a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
172a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private class MyPackageMonitor extends PackageMonitor {
173a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        @Override
174a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        public void onPackageAdded(String packageName, int uid) {
175d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            if (!mUserManager.isSameProfileGroup(mParentUser.getIdentifier(),
176d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    UserHandle.getUserId(uid))) {
177d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                return;
178d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            }
179a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
180d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            handlePackageAdded(new UserPackage(packageName, UserHandle.getUserHandleForUid(uid)));
181a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
182a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
183a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        @Override
184a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        public void onPackageRemoved(String packageName, int uid) {
185d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            if (!mUserManager.isSameProfileGroup(mParentUser.getIdentifier(),
186d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    UserHandle.getUserId(uid))) {
187d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                return;
188d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            }
189d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
190a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            clearDefaults(packageName, UserHandle.getUserHandleForUid(uid));
191a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
192a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
193a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
194a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
195a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
196a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private final MtpNotificationManager mMtpNotificationManager;
197a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
198a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
199a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Create new settings manager for a profile group.
200a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
201a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param context The context of the service
202a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param user The parent profile
203a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param settingsManager The settings manager of the service
204a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
205a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    UsbProfileGroupSettingsManager(@NonNull Context context, @NonNull UserHandle user,
206a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            @NonNull UsbSettingsManager settingsManager) {
207a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        if (DEBUG) Slog.v(TAG, "Creating settings for " + user);
208a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
209a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        Context parentUserContext;
210a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        try {
211a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            parentUserContext = context.createPackageContextAsUser("android", 0, user);
212a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } catch (NameNotFoundException e) {
213a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            throw new RuntimeException("Missing android package");
214a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
215a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
216a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mContext = context;
217a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mPackageManager = context.getPackageManager();
218a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mSettingsManager = settingsManager;
219a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
220a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
221a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mParentUser = user;
222a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mSettingsFile = new AtomicFile(new File(
223a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                Environment.getUserSystemDirectory(user.getIdentifier()),
224e17b445b6c813f6f9bc93a5e3811128a197ef50bDianne Hackborn                "usb_device_manager.xml"), "usb-state");
225a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
226a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mDisablePermissionDialogs = context.getResources().getBoolean(
227a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                com.android.internal.R.bool.config_disableUsbPermissionDialogs);
228a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
229a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
230a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (UserHandle.SYSTEM.equals(user)) {
231a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                upgradeSingleUserLocked();
232a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
233a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            readSettingsLocked();
234a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
235a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
236d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        mPackageMonitor.register(context, null, UserHandle.ALL, true);
237a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mMtpNotificationManager = new MtpNotificationManager(
238a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                parentUserContext,
239bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann                device -> resolveActivity(createDeviceAttachedIntent(device),
240bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann                        device, false /* showMtpNotification */));
241a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
242a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
243880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    /**
244880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * Remove all defaults for a user.
245880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     *
246880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * @param userToRemove The user the defaults belong to.
247880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     */
248880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    void removeAllDefaultsForUser(@NonNull UserHandle userToRemove) {
249880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        synchronized (mLock) {
250880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            boolean needToPersist = false;
251880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            Iterator<Map.Entry<DeviceFilter, UserPackage>> devicePreferenceIt = mDevicePreferenceMap
252880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    .entrySet().iterator();
253880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            while (devicePreferenceIt.hasNext()) {
254880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                Map.Entry<DeviceFilter, UserPackage> entry = devicePreferenceIt.next();
255880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
256880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                if (entry.getValue().user.equals(userToRemove)) {
257880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    devicePreferenceIt.remove();
258880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    needToPersist = true;
259880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                }
260880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            }
261880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
262880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            Iterator<Map.Entry<AccessoryFilter, UserPackage>> accessoryPreferenceIt =
263880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    mAccessoryPreferenceMap.entrySet().iterator();
264880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            while (accessoryPreferenceIt.hasNext()) {
265880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                Map.Entry<AccessoryFilter, UserPackage> entry = accessoryPreferenceIt.next();
266880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
267880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                if (entry.getValue().user.equals(userToRemove)) {
268880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    accessoryPreferenceIt.remove();
269880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    needToPersist = true;
270880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                }
271880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            }
272880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
273880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            if (needToPersist) {
274880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                scheduleWriteSettingsLocked();
275880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            }
276880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        }
277880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    }
278880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
279a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private void readPreference(XmlPullParser parser)
280a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            throws XmlPullParserException, IOException {
281a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        String packageName = null;
282a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
283a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        // If not set, assume it to be the parent profile
284a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        UserHandle user = mParentUser;
285a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
286a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        int count = parser.getAttributeCount();
287a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        for (int i = 0; i < count; i++) {
288a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if ("package".equals(parser.getAttributeName(i))) {
289a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                packageName = parser.getAttributeValue(i);
290a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
291a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if ("user".equals(parser.getAttributeName(i))) {
292a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                // Might return null if user is not known anymore
293a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                user = mUserManager
294a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        .getUserForSerialNumber(Integer.parseInt(parser.getAttributeValue(i)));
295a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
296a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
297a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
298a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        XmlUtils.nextElement(parser);
299a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        if ("usb-device".equals(parser.getName())) {
300a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            DeviceFilter filter = DeviceFilter.read(parser);
301a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (user != null) {
302a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                mDevicePreferenceMap.put(filter, new UserPackage(packageName, user));
303a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
304a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } else if ("usb-accessory".equals(parser.getName())) {
305a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            AccessoryFilter filter = AccessoryFilter.read(parser);
306a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (user != null) {
307a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                mAccessoryPreferenceMap.put(filter, new UserPackage(packageName, user));
308a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
309a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
310a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        XmlUtils.nextElement(parser);
311a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
312a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
313a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
314a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Upgrade any single-user settings from {@link #sSingleUserSettingsFile}.
315a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Should only by called by owner.
316a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
317bbab23ff97688f33c5cc41d5d0e134c0d9f58c6cAndreas Gampe    @GuardedBy("mLock")
318a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private void upgradeSingleUserLocked() {
319a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        if (sSingleUserSettingsFile.exists()) {
320a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            mDevicePreferenceMap.clear();
321a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            mAccessoryPreferenceMap.clear();
322a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
323a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            FileInputStream fis = null;
324a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            try {
325a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                fis = new FileInputStream(sSingleUserSettingsFile);
326a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                XmlPullParser parser = Xml.newPullParser();
327a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                parser.setInput(fis, StandardCharsets.UTF_8.name());
328a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
329a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                XmlUtils.nextElement(parser);
330a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
331a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    final String tagName = parser.getName();
332a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    if ("preference".equals(tagName)) {
333a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        readPreference(parser);
334a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    } else {
335a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        XmlUtils.nextElement(parser);
336a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
337a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
338bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann            } catch (IOException | XmlPullParserException e) {
339a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                Log.wtf(TAG, "Failed to read single-user settings", e);
340a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } finally {
341a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                IoUtils.closeQuietly(fis);
342a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
343a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
344880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            scheduleWriteSettingsLocked();
345a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
346a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            // Success or failure, we delete single-user file
347a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            sSingleUserSettingsFile.delete();
348a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
349a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
350a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
351bbab23ff97688f33c5cc41d5d0e134c0d9f58c6cAndreas Gampe    @GuardedBy("mLock")
352a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private void readSettingsLocked() {
353a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        if (DEBUG) Slog.v(TAG, "readSettingsLocked()");
354a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
355a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mDevicePreferenceMap.clear();
356a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mAccessoryPreferenceMap.clear();
357a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
358a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        FileInputStream stream = null;
359a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        try {
360a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            stream = mSettingsFile.openRead();
361a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            XmlPullParser parser = Xml.newPullParser();
362a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            parser.setInput(stream, StandardCharsets.UTF_8.name());
363a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
364a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            XmlUtils.nextElement(parser);
365a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
366a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                String tagName = parser.getName();
367a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                if ("preference".equals(tagName)) {
368a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    readPreference(parser);
369a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                } else {
370a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    XmlUtils.nextElement(parser);
371a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
372a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
373a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } catch (FileNotFoundException e) {
374a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (DEBUG) Slog.d(TAG, "settings file not found");
375a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } catch (Exception e) {
376a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            Slog.e(TAG, "error reading settings file, deleting to start fresh", e);
377a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            mSettingsFile.delete();
378a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } finally {
379a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            IoUtils.closeQuietly(stream);
380a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
381a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
382a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
383880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    /**
384880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * Schedule a async task to persist {@link #mDevicePreferenceMap} and
385880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * {@link #mAccessoryPreferenceMap}. If a task is already scheduled but not completed, do
386880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * nothing as the currently scheduled one will do the work.
387880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * <p>Called with {@link #mLock} held.</p>
388880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * <p>In the uncommon case that the system crashes in between the scheduling and the write the
389880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     * update is lost.</p>
390880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann     */
391bbab23ff97688f33c5cc41d5d0e134c0d9f58c6cAndreas Gampe    @GuardedBy("mLock")
392880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann    private void scheduleWriteSettingsLocked() {
393880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        if (mIsWriteSettingsScheduled) {
394880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            return;
395880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        } else {
396880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            mIsWriteSettingsScheduled = true;
397880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        }
398a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
399880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        AsyncTask.execute(() -> {
400880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann            synchronized (mLock) {
401880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                FileOutputStream fos = null;
402880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                try {
403880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    fos = mSettingsFile.startWrite();
404880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
405880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    FastXmlSerializer serializer = new FastXmlSerializer();
406880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    serializer.setOutput(fos, StandardCharsets.UTF_8.name());
407880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    serializer.startDocument(null, true);
408880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
409880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                                    true);
410880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    serializer.startTag(null, "settings");
411880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
412880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
413880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.startTag(null, "preference");
414880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.attribute(null, "package",
415880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                                mDevicePreferenceMap.get(filter).packageName);
416880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.attribute(null, "user",
417880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                                String.valueOf(getSerial(mDevicePreferenceMap.get(filter).user)));
418880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        filter.write(serializer);
419880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.endTag(null, "preference");
420880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    }
421a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
422880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    for (AccessoryFilter filter : mAccessoryPreferenceMap.keySet()) {
423880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.startTag(null, "preference");
424880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.attribute(null, "package",
425880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                                mAccessoryPreferenceMap.get(filter).packageName);
426880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.attribute(null, "user", String.valueOf(
427880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                                        getSerial(mAccessoryPreferenceMap.get(filter).user)));
428880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        filter.write(serializer);
429880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        serializer.endTag(null, "preference");
430880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    }
431a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
432880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    serializer.endTag(null, "settings");
433880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    serializer.endDocument();
434a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
435880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    mSettingsFile.finishWrite(fos);
436880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                } catch (IOException e) {
437880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    Slog.e(TAG, "Failed to write settings", e);
438880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    if (fos != null) {
439880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                        mSettingsFile.failWrite(fos);
440880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                    }
441880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                }
442880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann
443880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                mIsWriteSettingsScheduled = false;
444a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
445880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann        });
446a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
447a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
448a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    // Checks to see if a package matches a device or accessory.
449a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    // Only one of device and accessory should be non-null.
450a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private boolean packageMatchesLocked(ResolveInfo info, String metaDataName,
451a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            UsbDevice device, UsbAccessory accessory) {
4520d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        if (isForwardMatch(info)) {
453a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            return true;
454a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
455a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
456a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        ActivityInfo ai = info.activityInfo;
457a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
458a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        XmlResourceParser parser = null;
459a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        try {
460a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            parser = ai.loadXmlMetaData(mPackageManager, metaDataName);
461a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (parser == null) {
462a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                Slog.w(TAG, "no meta-data for " + info);
463a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                return false;
464a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
465a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
466a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            XmlUtils.nextElement(parser);
467a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
468a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                String tagName = parser.getName();
469a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                if (device != null && "usb-device".equals(tagName)) {
470a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    DeviceFilter filter = DeviceFilter.read(parser);
471a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    if (filter.matches(device)) {
472a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        return true;
473a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
474a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
475a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                else if (accessory != null && "usb-accessory".equals(tagName)) {
476a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    AccessoryFilter filter = AccessoryFilter.read(parser);
477a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    if (filter.matches(accessory)) {
478a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        return true;
479a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
480a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
481a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                XmlUtils.nextElement(parser);
482a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
483a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } catch (Exception e) {
484a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            Slog.w(TAG, "Unable to load component info " + info.toString(), e);
485a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } finally {
486a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (parser != null) parser.close();
487a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
488a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        return false;
489a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
490a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
491a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
492a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Resolve all activities that match an intent for all profiles of this group.
493a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
494a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param intent The intent to resolve
495a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
496a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @return The {@link ResolveInfo}s for all profiles of the group
497a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
498a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private @NonNull ArrayList<ResolveInfo> queryIntentActivitiesForAllProfiles(
499a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            @NonNull Intent intent) {
500a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        List<UserInfo> profiles = mUserManager.getEnabledProfiles(mParentUser.getIdentifier());
501a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
502a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        ArrayList<ResolveInfo> resolveInfos = new ArrayList<>();
503a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        int numProfiles = profiles.size();
504a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        for (int i = 0; i < numProfiles; i++) {
505a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            resolveInfos.addAll(mPackageManager.queryIntentActivitiesAsUser(intent,
506a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    PackageManager.GET_META_DATA, profiles.get(i).id));
507a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
508a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
509a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        return resolveInfos;
510a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
511a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
512733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann    /**
5130d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     * If this match used to forward the intent to another profile?
5140d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     *
5150d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     * @param match The match
5160d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     *
5170d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     * @return {@code true} iff this is such a forward match
5180d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     */
5190d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    private boolean isForwardMatch(@NonNull ResolveInfo match) {
5200d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        return match.getComponentInfo().name.equals(FORWARD_INTENT_TO_MANAGED_PROFILE);
5210d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    }
5220d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
5230d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    /**
524733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann     * Only return those matches with the highest priority.
525733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann     *
526733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann     * @param matches All matches, some might have lower priority
527733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann     *
528733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann     * @return The matches with the highest priority
529733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann     */
530733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann    @NonNull
5310d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    private ArrayList<ResolveInfo> preferHighPriority(@NonNull ArrayList<ResolveInfo> matches) {
532733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        SparseArray<ArrayList<ResolveInfo>> highestPriorityMatchesByUserId = new SparseArray<>();
533733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        SparseIntArray highestPriorityByUserId = new SparseIntArray();
5340d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        ArrayList<ResolveInfo> forwardMatches = new ArrayList<>();
535733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
536733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        // Create list of highest priority matches per user in highestPriorityMatchesByUserId
537733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        int numMatches = matches.size();
538733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        for (int matchNum = 0; matchNum < numMatches; matchNum++) {
539733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            ResolveInfo match = matches.get(matchNum);
540733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
5410d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            // Unnecessary forward matches are filtered out later, hence collect them all to add
5420d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            // them below
5430d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            if (isForwardMatch(match)) {
5440d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                forwardMatches.add(match);
5450d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                continue;
5460d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            }
5470d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
548733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            // If this a previously unknown user?
549733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            if (highestPriorityByUserId.indexOfKey(match.targetUserId) < 0) {
550733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann                highestPriorityByUserId.put(match.targetUserId, Integer.MIN_VALUE);
551733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann                highestPriorityMatchesByUserId.put(match.targetUserId, new ArrayList<>());
552733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            }
553733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
554733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            // Find current highest priority matches for the current user
555733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            int highestPriority = highestPriorityByUserId.get(match.targetUserId);
556733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            ArrayList<ResolveInfo> highestPriorityMatches = highestPriorityMatchesByUserId.get(
557733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann                    match.targetUserId);
558733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
559733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            if (match.priority == highestPriority) {
560733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann                highestPriorityMatches.add(match);
561733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            } else if (match.priority > highestPriority) {
562733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann                highestPriorityByUserId.put(match.targetUserId, match.priority);
563733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
564733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann                highestPriorityMatches.clear();
565733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann                highestPriorityMatches.add(match);
566733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            }
567733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        }
568733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
5690d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        // Combine all users (+ forward matches) back together. This means that all non-forward
5700d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        // matches have the same priority for a user. Matches for different users might have
5710d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        // different priority.
5720d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        ArrayList<ResolveInfo> combinedMatches = new ArrayList<>(forwardMatches);
573733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        int numMatchArrays = highestPriorityMatchesByUserId.size();
574733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        for (int matchArrayNum = 0; matchArrayNum < numMatchArrays; matchArrayNum++) {
575733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann            combinedMatches.addAll(highestPriorityMatchesByUserId.valueAt(matchArrayNum));
576733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        }
577733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
578733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann        return combinedMatches;
579733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann    }
580733d322cf594bb29a57e5e44c5c8100c4cf3ffccPhilip P. Moltmann
5810d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    /**
5820d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     * If there are no matches for a profile, remove the forward intent to this profile.
5830d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     *
5840d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     * @param rawMatches The matches that contain all forward intents
5850d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     *
5860d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     * @return The matches with the unnecessary forward intents removed
5870d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     */
5880d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    @NonNull private ArrayList<ResolveInfo> removeForwardIntentIfNotNeeded(
5890d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            @NonNull ArrayList<ResolveInfo> rawMatches) {
5900d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        final int numRawMatches = rawMatches.size();
5910d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
5920d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        // The raw matches contain the activities that can be started but also the intents to
5930d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        // forward the intent to the other profile
5940d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        int numParentActivityMatches = 0;
5950d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        int numNonParentActivityMatches = 0;
5960d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        for (int i = 0; i < numRawMatches; i++) {
5970d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            final ResolveInfo rawMatch = rawMatches.get(i);
5980d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            if (!isForwardMatch(rawMatch)) {
5990d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                if (UserHandle.getUserHandleForUid(
6000d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                        rawMatch.activityInfo.applicationInfo.uid).equals(mParentUser)) {
6010d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                    numParentActivityMatches++;
6020d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                } else {
6030d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                    numNonParentActivityMatches++;
6040d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                }
6050d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            }
6060d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        }
6070d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
6080d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        // If only one profile has activity matches, we need to remove all switch intents
6090d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        if (numParentActivityMatches == 0 || numNonParentActivityMatches == 0) {
6100d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            ArrayList<ResolveInfo> matches = new ArrayList<>(
6110d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                    numParentActivityMatches + numNonParentActivityMatches);
6120d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
6130d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            for (int i = 0; i < numRawMatches; i++) {
6140d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                ResolveInfo rawMatch = rawMatches.get(i);
6150d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                if (!isForwardMatch(rawMatch)) {
6160d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                    matches.add(rawMatch);
6170d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                }
6180d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            }
6190d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            return matches;
6200d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
6210d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        } else {
6220d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann            return rawMatches;
6230d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        }
6240d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    }
6250d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
626bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann    private ArrayList<ResolveInfo> getDeviceMatchesLocked(UsbDevice device, Intent intent) {
627bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann        ArrayList<ResolveInfo> matches = new ArrayList<>();
628a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        List<ResolveInfo> resolveInfos = queryIntentActivitiesForAllProfiles(intent);
629a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        int count = resolveInfos.size();
630a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        for (int i = 0; i < count; i++) {
631a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            ResolveInfo resolveInfo = resolveInfos.get(i);
632a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (packageMatchesLocked(resolveInfo, intent.getAction(), device, null)) {
633a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                matches.add(resolveInfo);
634a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
635a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
6360d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
6370d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        return removeForwardIntentIfNotNeeded(preferHighPriority(matches));
638a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
639a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
640bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann    private ArrayList<ResolveInfo> getAccessoryMatchesLocked(
641a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            UsbAccessory accessory, Intent intent) {
642bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann        ArrayList<ResolveInfo> matches = new ArrayList<>();
643a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        List<ResolveInfo> resolveInfos = queryIntentActivitiesForAllProfiles(intent);
644a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        int count = resolveInfos.size();
645a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        for (int i = 0; i < count; i++) {
646a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            ResolveInfo resolveInfo = resolveInfos.get(i);
647a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (packageMatchesLocked(resolveInfo, intent.getAction(), null, accessory)) {
648a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                matches.add(resolveInfo);
649a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
650a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
6510d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann
6520d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        return removeForwardIntentIfNotNeeded(preferHighPriority(matches));
653a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
654a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
655a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    public void deviceAttached(UsbDevice device) {
656a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        final Intent intent = createDeviceAttachedIntent(device);
657a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
658a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        // Send broadcast to running activities with registered intent
659a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
660a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
661a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        resolveActivity(intent, device, true /* showMtpNotification */);
662a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
663a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
664a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono    private void resolveActivity(Intent intent, UsbDevice device, boolean showMtpNotification) {
665a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        final ArrayList<ResolveInfo> matches;
666a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        final ActivityInfo defaultActivity;
667a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
668a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            matches = getDeviceMatchesLocked(device, intent);
669a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            defaultActivity = getDefaultActivityLocked(
670a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                    matches, mDevicePreferenceMap.get(new DeviceFilter(device)));
671a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        }
672a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono
673a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        if (showMtpNotification && MtpNotificationManager.shouldShowNotification(
674a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                mPackageManager, device) && defaultActivity == null) {
675a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            // Show notification if the device is MTP storage.
676a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            mMtpNotificationManager.showNotification(device);
677a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            return;
678a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
679a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
680a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        // Start activity with registered intent
681a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        resolveActivity(intent, matches, defaultActivity, device, null);
682a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
683a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
684a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    public void deviceAttachedForFixedHandler(UsbDevice device, ComponentName component) {
685a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        final Intent intent = createDeviceAttachedIntent(device);
686a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
687a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        // Send broadcast to running activity with registered intent
688a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mContext.sendBroadcast(intent);
689a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
690a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        ApplicationInfo appInfo;
691a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        try {
692d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            // Fixed handlers are always for parent user
693d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            appInfo = mPackageManager.getApplicationInfoAsUser(component.getPackageName(), 0,
694d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    mParentUser.getIdentifier());
695a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } catch (NameNotFoundException e) {
696d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            Slog.e(TAG, "Default USB handling package (" + component.getPackageName()
697d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    + ") not found  for user " + mParentUser);
698a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            return;
699a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
700a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
701a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mSettingsManager.getSettingsForUser(UserHandle.getUserId(appInfo.uid))
702a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                .grantDevicePermission(device, appInfo.uid);
703a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
704a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        Intent activityIntent = new Intent(intent);
705a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        activityIntent.setComponent(component);
706a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        try {
707a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            mContext.startActivityAsUser(activityIntent, mParentUser);
708a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } catch (ActivityNotFoundException e) {
709a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            Slog.e(TAG, "unable to start activity " + activityIntent);
710a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
711a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
712a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
713a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
714a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Remove notifications for a usb device.
715a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
716a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param device The device the notifications are for.
717a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
718a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    void usbDeviceRemoved(@NonNull UsbDevice device) {
719a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        mMtpNotificationManager.hideNotification(device.getDeviceId());
720a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
721a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
722a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    public void accessoryAttached(UsbAccessory accessory) {
723a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
724a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
72542a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate        intent.addFlags(
72642a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate                Intent.FLAG_ACTIVITY_NEW_TASK |
72742a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate                Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
728a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
729a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        final ArrayList<ResolveInfo> matches;
730a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        final ActivityInfo defaultActivity;
731a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
732a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            matches = getAccessoryMatchesLocked(accessory, intent);
733a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            defaultActivity = getDefaultActivityLocked(
734a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                    matches, mAccessoryPreferenceMap.get(new AccessoryFilter(accessory)));
735a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
736a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
737a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        resolveActivity(intent, matches, defaultActivity, null, accessory);
738a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
739a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
740a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
741a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Start the appropriate package when an device/accessory got attached.
742a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
743a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param intent The intent to start the package
7440d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann     * @param matches The available resolutions of the intent
745a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono     * @param defaultActivity The default activity for the device (if set)
746a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param device The device if a device was attached
747a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param accessory The accessory if a device was attached
748a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
7490d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann    private void resolveActivity(@NonNull Intent intent, @NonNull ArrayList<ResolveInfo> matches,
750a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            @Nullable ActivityInfo defaultActivity, @Nullable UsbDevice device,
751a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            @Nullable UsbAccessory accessory) {
752a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        // don't show the resolver activity if there are no choices available
7530d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann        if (matches.size() == 0) {
754a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (accessory != null) {
755a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                String uri = accessory.getUri();
756a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                if (uri != null && uri.length() > 0) {
757a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    // display URI to user
758a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    Intent dialogIntent = new Intent();
759a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    dialogIntent.setClassName("com.android.systemui",
760a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                            "com.android.systemui.usb.UsbAccessoryUriActivity");
761a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
762a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    dialogIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
763a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    dialogIntent.putExtra("uri", uri);
764a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    try {
765a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        mContext.startActivityAsUser(dialogIntent, mParentUser);
766a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    } catch (ActivityNotFoundException e) {
767a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        Slog.e(TAG, "unable to start UsbAccessoryUriActivity");
768a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
769a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
770a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
771a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
772a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            // do nothing
773a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            return;
774a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
775a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
776a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        if (defaultActivity != null) {
777a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            UsbUserSettingsManager defaultRIUserSettings = mSettingsManager.getSettingsForUser(
778a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                    UserHandle.getUserId(defaultActivity.applicationInfo.uid));
779a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            // grant permission for default activity
780a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (device != null) {
781a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                defaultRIUserSettings.
782a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                        grantDevicePermission(device, defaultActivity.applicationInfo.uid);
783a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } else if (accessory != null) {
784a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                defaultRIUserSettings.grantAccessoryPermission(accessory,
785a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                        defaultActivity.applicationInfo.uid);
786a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
787a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
788a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            // start default activity directly
789a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            try {
790a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                intent.setComponent(
791a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                        new ComponentName(defaultActivity.packageName, defaultActivity.name));
792a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
793a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                UserHandle user = UserHandle.getUserHandleForUid(
794a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                        defaultActivity.applicationInfo.uid);
795a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                mContext.startActivityAsUser(intent, user);
796a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } catch (ActivityNotFoundException e) {
797a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                Slog.e(TAG, "startActivity failed", e);
798a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
799a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } else {
800a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            Intent resolverIntent = new Intent();
801a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            resolverIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
802a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            UserHandle user;
803a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
804ebc8ee266c8fa99aae5567f9da920f4a81c04c4aPhilip P. Moltmann            if (matches.size() == 1) {
805a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                ResolveInfo rInfo = matches.get(0);
806a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
807a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                // start UsbConfirmActivity if there is only one choice
808a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                resolverIntent.setClassName("com.android.systemui",
809a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        "com.android.systemui.usb.UsbConfirmActivity");
810a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                resolverIntent.putExtra("rinfo", rInfo);
811a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                user = UserHandle.getUserHandleForUid(rInfo.activityInfo.applicationInfo.uid);
812a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
813a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                if (device != null) {
814a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    resolverIntent.putExtra(UsbManager.EXTRA_DEVICE, device);
815a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                } else {
816a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    resolverIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
817a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
818a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } else {
819a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                user = mParentUser;
820a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
821a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                // start UsbResolverActivity so user can choose an activity
822a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                resolverIntent.setClassName("com.android.systemui",
823a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        "com.android.systemui.usb.UsbResolverActivity");
824a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                resolverIntent.putParcelableArrayListExtra("rlist", matches);
825a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                resolverIntent.putExtra(Intent.EXTRA_INTENT, intent);
826a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
827a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            try {
828a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                mContext.startActivityAsUser(resolverIntent, user);
829a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } catch (ActivityNotFoundException e) {
830a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                Slog.e(TAG, "unable to start activity " + resolverIntent, e);
831a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
832a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
833a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
834a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
835a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono    /**
836a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono     * Returns a default activity for matched ResolveInfo.
837a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono     * @param matches Resolved activities matched with connected device/accesary.
838a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono     * @param userPackage Default activity choosed by a user before. Should be null if no activity
839a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono     *     is choosed by a user.
840a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono     * @return Default activity
841a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono     */
842a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono    private @Nullable ActivityInfo getDefaultActivityLocked(
843a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            @NonNull ArrayList<ResolveInfo> matches,
844a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            @Nullable UserPackage userPackage) {
845a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        if (userPackage != null) {
846a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            // look for default activity
847a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            for (final ResolveInfo info : matches) {
848d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                if (info.activityInfo != null && userPackage.equals(
849d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                        new UserPackage(info.activityInfo.packageName,
850d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                                UserHandle.getUserHandleForUid(
851d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                                        info.activityInfo.applicationInfo.uid)))) {
852a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                    return info.activityInfo;
853a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                }
854a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            }
855a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        }
856a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono
857a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        if (matches.size() == 1) {
858a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            final ActivityInfo activityInfo = matches.get(0).activityInfo;
859a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            if (activityInfo != null) {
860a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                if (mDisablePermissionDialogs) {
861a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                    return activityInfo;
862a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                }
8630d78363a39de01232097a90933cfeb9f8bbe823dPhilip P. Moltmann                // System apps are considered default unless there are other matches
864a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                if (activityInfo.applicationInfo != null
865a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                        && (activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
866a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                                != 0) {
867a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                    return activityInfo;
868a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono                }
869a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono            }
870a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        }
871a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono
872a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono        return null;
873a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono    }
874a455dd9f0939f36438b39c0ae6b69e4c82e6ff02Daichi Hirono
875bbab23ff97688f33c5cc41d5d0e134c0d9f58c6cAndreas Gampe    @GuardedBy("mLock")
876d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann    private boolean clearCompatibleMatchesLocked(@NonNull UserPackage userPackage,
877d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            @NonNull DeviceFilter filter) {
878d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        ArrayList<DeviceFilter> keysToRemove = new ArrayList<>();
879d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
880d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        // The keys in mDevicePreferenceMap are filters that match devices very narrowly
881d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        for (DeviceFilter device : mDevicePreferenceMap.keySet()) {
882d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            if (filter.contains(device)) {
883d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                UserPackage currentMatch = mDevicePreferenceMap.get(device);
884d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                if (!currentMatch.equals(userPackage)) {
885d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    keysToRemove.add(device);
886f4a2e1df940f75534af364b7d7dad46a4b25bd44David Stevens                }
887a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
888a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
889d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
890d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        if (!keysToRemove.isEmpty()) {
891d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            for (DeviceFilter keyToRemove : keysToRemove) {
892d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                mDevicePreferenceMap.remove(keyToRemove);
893d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            }
894d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        }
895d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
896d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        return !keysToRemove.isEmpty();
897a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
898a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
899bbab23ff97688f33c5cc41d5d0e134c0d9f58c6cAndreas Gampe    @GuardedBy("mLock")
900d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann    private boolean clearCompatibleMatchesLocked(@NonNull UserPackage userPackage,
901d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            @NonNull AccessoryFilter filter) {
902d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        ArrayList<AccessoryFilter> keysToRemove = new ArrayList<>();
903d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
904d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        // The keys in mAccessoryPreferenceMap are filters that match accessories very narrowly
905d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        for (AccessoryFilter accessory : mAccessoryPreferenceMap.keySet()) {
906d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            if (filter.contains(accessory)) {
907d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                UserPackage currentMatch = mAccessoryPreferenceMap.get(accessory);
908d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                if (!currentMatch.equals(userPackage)) {
909d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    keysToRemove.add(accessory);
910f4a2e1df940f75534af364b7d7dad46a4b25bd44David Stevens                }
911a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
912a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
913d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
914d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        if (!keysToRemove.isEmpty()) {
915d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            for (AccessoryFilter keyToRemove : keysToRemove) {
916d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                mAccessoryPreferenceMap.remove(keyToRemove);
917d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            }
918d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        }
919d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
920d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann        return !keysToRemove.isEmpty();
921a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
922a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
923bbab23ff97688f33c5cc41d5d0e134c0d9f58c6cAndreas Gampe    @GuardedBy("mLock")
924d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann    private boolean handlePackageAddedLocked(UserPackage userPackage, ActivityInfo aInfo,
925a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            String metaDataName) {
926a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        XmlResourceParser parser = null;
927a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        boolean changed = false;
928a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
929a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        try {
930a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            parser = aInfo.loadXmlMetaData(mPackageManager, metaDataName);
931a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (parser == null) return false;
932a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
933a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            XmlUtils.nextElement(parser);
934a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
935a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                String tagName = parser.getName();
936a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                if ("usb-device".equals(tagName)) {
937a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    DeviceFilter filter = DeviceFilter.read(parser);
938d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    if (clearCompatibleMatchesLocked(userPackage, filter)) {
939a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        changed = true;
940a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
941a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
942a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                else if ("usb-accessory".equals(tagName)) {
943a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    AccessoryFilter filter = AccessoryFilter.read(parser);
944d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    if (clearCompatibleMatchesLocked(userPackage, filter)) {
945a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        changed = true;
946a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
947a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
948a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                XmlUtils.nextElement(parser);
949a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
950a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } catch (Exception e) {
951a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            Slog.w(TAG, "Unable to load component info " + aInfo.toString(), e);
952a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        } finally {
953a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (parser != null) parser.close();
954a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
955a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        return changed;
956a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
957a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
958a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    // Check to see if the package supports any USB devices or accessories.
959d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann    // If so, clear any preferences for matching devices/accessories.
960d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann    private void handlePackageAdded(@NonNull UserPackage userPackage) {
961a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
962a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            PackageInfo info;
963a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            boolean changed = false;
964a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
965a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            try {
966d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                info = mPackageManager.getPackageInfoAsUser(userPackage.packageName,
967d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                        PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA,
968d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                        userPackage.user.getIdentifier());
969a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } catch (NameNotFoundException e) {
970d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                Slog.e(TAG, "handlePackageUpdate could not find package " + userPackage, e);
971a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                return;
972a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
973a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
974a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            ActivityInfo[] activities = info.activities;
975a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (activities == null) return;
976a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            for (int i = 0; i < activities.length; i++) {
977a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                // check for meta-data, both for devices and accessories
978d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                if (handlePackageAddedLocked(userPackage, activities[i],
979a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
980a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    changed = true;
981a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
982d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
983d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                if (handlePackageAddedLocked(userPackage, activities[i],
984a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        UsbManager.ACTION_USB_ACCESSORY_ATTACHED)) {
985a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    changed = true;
986a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
987a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
988a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
989a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (changed) {
990880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                scheduleWriteSettingsLocked();
991a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
992a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
993a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
994a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
995a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
996a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Get the serial number for a user handle.
997a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
998a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param user The user handle
999a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1000a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @return The serial number
1001a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
1002a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private int getSerial(@NonNull UserHandle user) {
1003a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        return mUserManager.getUserSerialNumber(user.getIdentifier());
1004a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1005a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1006a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
1007a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Set a package as default handler for a device.
1008a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1009a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param device The device that should be handled by default
1010a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param packageName The default handler package
1011a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param user The user the package belongs to
1012a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
1013a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    void setDevicePackage(@NonNull UsbDevice device, @Nullable String packageName,
1014d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            @NonNull UserHandle user) {
1015a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        DeviceFilter filter = new DeviceFilter(device);
1016bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann        boolean changed;
1017a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
1018a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (packageName == null) {
1019a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                changed = (mDevicePreferenceMap.remove(filter) != null);
1020a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } else {
1021d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                UserPackage userPackage = new UserPackage(packageName, user);
1022d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
1023d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                changed = !userPackage.equals(mDevicePreferenceMap.get(filter));
1024a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                if (changed) {
1025d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    mDevicePreferenceMap.put(filter, userPackage);
1026a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
1027a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1028a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (changed) {
1029880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                scheduleWriteSettingsLocked();
1030a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1031a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
1032a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1033a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1034a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
1035a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Set a package as default handler for a accessory.
1036a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1037a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param accessory The accessory that should be handled by default
1038a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param packageName The default handler package
1039a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param user The user the package belongs to
1040a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
1041a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    void setAccessoryPackage(@NonNull UsbAccessory accessory, @Nullable String packageName,
1042d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann            @NonNull UserHandle user) {
1043a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        AccessoryFilter filter = new AccessoryFilter(accessory);
1044bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann        boolean changed;
1045a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
1046a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (packageName == null) {
1047a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                changed = (mAccessoryPreferenceMap.remove(filter) != null);
1048a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            } else {
1049d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                UserPackage userPackage = new UserPackage(packageName, user);
1050d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann
1051d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                changed = !userPackage.equals(mAccessoryPreferenceMap.get(filter));
1052a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                if (changed) {
1053d4b09d4e16a9dc2bb08b1e06b87c02de3f46308cPhilip P. Moltmann                    mAccessoryPreferenceMap.put(filter, userPackage);
1054a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
1055a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1056a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (changed) {
1057880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                scheduleWriteSettingsLocked();
1058a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1059a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
1060a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1061a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1062a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
1063a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Check if a package has is the default handler for any usb device or accessory.
1064a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1065a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param packageName The package name
1066a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param user The user the package belongs to
1067a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1068a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @return {@code true} iff the package is default for any usb device or accessory
1069a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
1070a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    boolean hasDefaults(@NonNull String packageName, @NonNull UserHandle user) {
1071a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        UserPackage userPackage = new UserPackage(packageName, user);
1072a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
1073a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (mDevicePreferenceMap.values().contains(userPackage)) return true;
1074bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann            return mAccessoryPreferenceMap.values().contains(userPackage);
1075a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
1076a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1077a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1078a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
1079a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Clear defaults for a package from any preference.
1080a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1081a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param packageName The package to remove
1082a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param user The user the package belongs to
1083a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
1084a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    void clearDefaults(@NonNull String packageName, @NonNull UserHandle user) {
1085a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        UserPackage userPackage = new UserPackage(packageName, user);
1086a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1087a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
1088a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (clearPackageDefaultsLocked(userPackage)) {
1089880389e6cc8044f751dd8569f2172ca61eaf2cd3Philip P. Moltmann                scheduleWriteSettingsLocked();
1090a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1091a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
1092a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1093a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1094a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    /**
1095a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * Clear defaults for a package from any preference (does not persist).
1096a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1097a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @param userPackage The package to remove
1098a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     *
1099a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     * @return {@code true} iff at least one preference was cleared
1100a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann     */
1101a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private boolean clearPackageDefaultsLocked(@NonNull UserPackage userPackage) {
1102a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        boolean cleared = false;
1103a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
1104a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (mDevicePreferenceMap.containsValue(userPackage)) {
1105a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                // make a copy of the key set to avoid ConcurrentModificationException
1106bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann                DeviceFilter[] keys = mDevicePreferenceMap.keySet().toArray(new DeviceFilter[0]);
1107a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                for (int i = 0; i < keys.length; i++) {
1108bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann                    DeviceFilter key = keys[i];
1109a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    if (userPackage.equals(mDevicePreferenceMap.get(key))) {
1110a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        mDevicePreferenceMap.remove(key);
1111a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        cleared = true;
1112a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
1113a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
1114a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1115a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            if (mAccessoryPreferenceMap.containsValue(userPackage)) {
1116a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                // make a copy of the key set to avoid ConcurrentModificationException
1117bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann                AccessoryFilter[] keys =
1118bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann                        mAccessoryPreferenceMap.keySet().toArray(new AccessoryFilter[0]);
1119a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                for (int i = 0; i < keys.length; i++) {
1120bee04d08b555b030c6e6cf31b10124862411eeb1Philip P. Moltmann                    AccessoryFilter key = keys[i];
1121a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    if (userPackage.equals(mAccessoryPreferenceMap.get(key))) {
1122a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        mAccessoryPreferenceMap.remove(key);
1123a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                        cleared = true;
1124a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                    }
1125a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann                }
1126a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1127a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            return cleared;
1128a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
1129a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1130a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1131371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann    public void dump(@NonNull DualDumpOutputStream dump, @NonNull String idName, long id) {
1132371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann        long token = dump.start(idName, id);
1133371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1134a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        synchronized (mLock) {
1135371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann            dump.write("parent_user_id", UsbProfileGroupSettingsManagerProto.PARENT_USER_ID,
1136371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                    mParentUser.getIdentifier());
1137371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1138a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
1139371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                long devicePrefToken = dump.start("device_preferences",
1140371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                        UsbProfileGroupSettingsManagerProto.DEVICE_PREFERENCES);
1141371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1142371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                filter.dump(dump, "filter", UsbSettingsDevicePreferenceProto.FILTER);
1143371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1144371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                mDevicePreferenceMap.get(filter).dump(dump, "user_package",
1145371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                        UsbSettingsDevicePreferenceProto.USER_PACKAGE);
1146371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1147371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                dump.end(devicePrefToken);
1148a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1149a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            for (AccessoryFilter filter : mAccessoryPreferenceMap.keySet()) {
1150371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                long accessoryPrefToken = dump.start("accessory_preferences",
1151371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                        UsbProfileGroupSettingsManagerProto.ACCESSORY_PREFERENCES);
1152371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1153371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                filter.dump(dump, "filter", UsbSettingsAccessoryPreferenceProto.FILTER);
1154371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1155371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                mAccessoryPreferenceMap.get(filter).dump(dump, "user_package",
1156371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                        UsbSettingsAccessoryPreferenceProto.USER_PACKAGE);
1157371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1158371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                dump.end(accessoryPrefToken);
1159a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann            }
1160a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        }
1161371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann
1162371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann        dump.end(token);
1163a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1164a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann
1165a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    private static Intent createDeviceAttachedIntent(UsbDevice device) {
1166a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
1167a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
116842a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate        intent.addFlags(
116942a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate                Intent.FLAG_ACTIVITY_NEW_TASK |
117042a386b7717300bf6d75cbd3b4f7ad00f294be0dChristopher Tate                Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
1171a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann        return intent;
1172a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann    }
1173a6bf206649b24cabcf1348219e1b00f38214e06aPhilip P. Moltmann}
1174