1a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki/*
2a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * Copyright (C) 2015 The Android Open Source Project
3a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki *
4a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License");
5a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * you may not use this file except in compliance with the License.
6a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * You may obtain a copy of the License at
7a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki *
8a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki *      http://www.apache.org/licenses/LICENSE-2.0
9a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki *
10a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * Unless required by applicable law or agreed to in writing, software
11a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS,
12a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * See the License for the specific language governing permissions and
14a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki * limitations under the License.
15a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki */
16a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
17a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukipackage com.android.server.pm;
18a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
19a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport com.google.android.collect.Sets;
20a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
211a2cd74526113b45d9108b6997609122c4311fb1Makoto Onukiimport com.android.internal.util.Preconditions;
221a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
231a2cd74526113b45d9108b6997609122c4311fb1Makoto Onukiimport android.annotation.NonNull;
241a2cd74526113b45d9108b6997609122c4311fb1Makoto Onukiimport android.annotation.Nullable;
259cbfc9e212151e84910a22387365644916dde446Fyodor Kupolovimport android.app.ActivityManager;
261d13eaea8380a43a31b12804f26d888f829feedfyuemingwimport android.app.admin.DevicePolicyManager;
274f16073556f7978708fb71c87628cfe1692412d5Makoto Onukiimport android.content.ContentResolver;
284f16073556f7978708fb71c87628cfe1692412d5Makoto Onukiimport android.content.Context;
29265c692c8ec5a50054e0279321a98e7af85c2117yuemingwimport android.content.Intent;
304f16073556f7978708fb71c87628cfe1692412d5Makoto Onukiimport android.os.Binder;
31a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport android.os.Bundle;
321d13eaea8380a43a31b12804f26d888f829feedfyuemingwimport android.os.Process;
339cbfc9e212151e84910a22387365644916dde446Fyodor Kupolovimport android.os.RemoteException;
344f16073556f7978708fb71c87628cfe1692412d5Makoto Onukiimport android.os.UserHandle;
35a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport android.os.UserManager;
366a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafovimport android.os.UserManagerInternal;
37265c692c8ec5a50054e0279321a98e7af85c2117yuemingwimport android.provider.Settings;
38acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onukiimport android.provider.Settings.Global;
39dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopraimport android.telephony.SubscriptionInfo;
40dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopraimport android.telephony.SubscriptionManager;
411a2cd74526113b45d9108b6997609122c4311fb1Makoto Onukiimport android.util.Log;
421f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onukiimport android.util.Slog;
436a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafovimport android.util.SparseArray;
44a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
45a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport org.xmlpull.v1.XmlPullParser;
46a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport org.xmlpull.v1.XmlSerializer;
47a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
48a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport java.io.IOException;
49a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport java.io.PrintWriter;
50dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopraimport java.util.List;
51a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukiimport java.util.Set;
52a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
53d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki/**
54dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra * Utility methods for user restrictions.
55d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki *
56d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki * <p>See {@link UserManagerService} for the method suffixes.
57d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki */
58a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onukipublic class UserRestrictionsUtils {
594f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki    private static final String TAG = "UserRestrictionsUtils";
604f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki
61a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki    private UserRestrictionsUtils() {
62a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki    }
63a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
641f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki    private static Set<String> newSetWithUniqueCheck(String[] strings) {
651f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki        final Set<String> ret = Sets.newArraySet(strings);
661f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki
671f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki        // Make sure there's no overlap.
681f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki        Preconditions.checkState(ret.size() == strings.length);
691f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki        return ret;
701f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki    }
711f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki
721f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki    public static final Set<String> USER_RESTRICTIONS = newSetWithUniqueCheck(new String[] {
73a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CONFIG_WIFI,
741bade5d62974544639f2b1656a7e2785b0338a6fChristine Franks            UserManager.DISALLOW_CONFIG_LOCALE,
75a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_MODIFY_ACCOUNTS,
76a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_INSTALL_APPS,
77a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_UNINSTALL_APPS,
78a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_SHARE_LOCATION,
79a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
80a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CONFIG_BLUETOOTH,
8163d5e4a7491b707235654cb081d2fc9074a5a65aLenka Trochtova            UserManager.DISALLOW_BLUETOOTH,
827f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            UserManager.DISALLOW_BLUETOOTH_SHARING,
83a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_USB_FILE_TRANSFER,
84a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CONFIG_CREDENTIALS,
85a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_REMOVE_USER,
866c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera            UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
87a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_DEBUGGING_FEATURES,
88a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CONFIG_VPN,
89a9772f360202b05858fa199088bfe94697a3f623yuemingw            UserManager.DISALLOW_CONFIG_DATE_TIME,
90a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CONFIG_TETHERING,
91a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_NETWORK_RESET,
92a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_FACTORY_RESET,
93a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_ADD_USER,
946c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera            UserManager.DISALLOW_ADD_MANAGED_PROFILE,
95a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.ENSURE_VERIFY_APPS,
96a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
97a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
98a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_APPS_CONTROL,
99a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
100a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_UNMUTE_MICROPHONE,
101a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_ADJUST_VOLUME,
102a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_OUTGOING_CALLS,
103a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_SMS,
104a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_FUN,
105a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CREATE_WINDOWS,
10622ff6f9df0b1e195f4d9daee0c7f4ba8f7ad6c9aCharles He            UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
107a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
108a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_OUTGOING_BEAM,
109a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_WALLPAPER,
110a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_SAFE_BOOT,
111a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
112a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            UserManager.DISALLOW_RECORD_AUDIO,
1139cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov            UserManager.DISALLOW_CAMERA,
114dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra            UserManager.DISALLOW_RUN_IN_BACKGROUND,
1157f1f1dfc8713fbecbab60cfbe14ab4d97d27deeeOleksandr Peletskyi            UserManager.DISALLOW_DATA_ROAMING,
116f2519814cc7136773a115b770d20cf4c92945952Oleksandr Peletskyi            UserManager.DISALLOW_SET_USER_ICON,
1173d9805d50281882b4420ee2d4ede8a8bdd94d455Mahaver Chopra            UserManager.DISALLOW_SET_WALLPAPER,
118c1205111a92b52283078f1a2e86c8d32c5928b92Tony Mak            UserManager.DISALLOW_OEM_UNLOCK,
119492b4724fb42adf29f3978f01ebc5238f893d194Esteban Talavera            UserManager.DISALLOW_UNMUTE_DEVICE,
12024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme            UserManager.DISALLOW_AUTOFILL,
121c4f87e9ceb4d5ce78c1663912bc166e0d41554aaPavel Grafov            UserManager.DISALLOW_USER_SWITCH,
122c4f87e9ceb4d5ce78c1663912bc166e0d41554aaPavel Grafov            UserManager.DISALLOW_UNIFIED_PASSWORD,
1237810b8b5a1deef711f2a3d83681bf8f23c349fd9yuemingw            UserManager.DISALLOW_CONFIG_LOCATION,
124c6ac29d34fcebf3d392dfb729f0085a87bceb6c9yuemingw            UserManager.DISALLOW_AIRPLANE_MODE,
125cc391c2c13b30c494908309659509f8426af48eaRubin Xu            UserManager.DISALLOW_CONFIG_BRIGHTNESS,
126cc391c2c13b30c494908309659509f8426af48eaRubin Xu            UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,
1275cda3aefd995dc873fb93aa4b829b33b0a040d48yuemingw            UserManager.DISALLOW_AMBIENT_DISPLAY,
128622b9f921278b308e9497675e63159f926764c91Vladislav Kuzkokov            UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
129622b9f921278b308e9497675e63159f926764c91Vladislav Kuzkokov            UserManager.DISALLOW_PRINTING
1301f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki    });
131a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
132a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki    /**
133a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki     * Set of user restriction which we don't want to persist.
134a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki     */
1351a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    private static final Set<String> NON_PERSIST_USER_RESTRICTIONS = Sets.newArraySet(
1361a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_RECORD_AUDIO
1371a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    );
1381a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
1391a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
1406a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * User restrictions that cannot be set by profile owners of secondary users. When set by DO
1416a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * they will be applied to all users.
1421a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
1436a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    private static final Set<String> PRIMARY_USER_ONLY_RESTRICTIONS = Sets.newArraySet(
14463d5e4a7491b707235654cb081d2fc9074a5a65aLenka Trochtova            UserManager.DISALLOW_BLUETOOTH,
1451a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_USB_FILE_TRANSFER,
1461a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_CONFIG_TETHERING,
1471a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_NETWORK_RESET,
1481a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_FACTORY_RESET,
1491a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_ADD_USER,
1501a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
1511a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
1521a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
1531a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_SMS,
1541a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_FUN,
1551a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_SAFE_BOOT,
156dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra            UserManager.DISALLOW_CREATE_WINDOWS,
1575fe75dc26d55a86f223fa5571b64e30731341564yuemingw            UserManager.DISALLOW_DATA_ROAMING,
1585fe75dc26d55a86f223fa5571b64e30731341564yuemingw            UserManager.DISALLOW_AIRPLANE_MODE
1591a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    );
1601a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
1611a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
162ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz     * User restrictions that cannot be set by profile owners. Applied to all users.
163ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz     */
164ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz    private static final Set<String> DEVICE_OWNER_ONLY_RESTRICTIONS = Sets.newArraySet(
165ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz            UserManager.DISALLOW_USER_SWITCH
166ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz    );
167ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz
168ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz    /**
1691a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * User restrictions that can't be changed by device owner or profile owner.
1701a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
1711a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    private static final Set<String> IMMUTABLE_BY_OWNERS = Sets.newArraySet(
1721a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_RECORD_AUDIO,
1733d9805d50281882b4420ee2d4ede8a8bdd94d455Mahaver Chopra            UserManager.DISALLOW_WALLPAPER,
1743d9805d50281882b4420ee2d4ede8a8bdd94d455Mahaver Chopra            UserManager.DISALLOW_OEM_UNLOCK
1751a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    );
1761a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
1771a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
1781a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * Special user restrictions that can be applied to a user as well as to all users globally,
1791a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * depending on callers.  When device owner sets them, they'll be applied to all users.
1801a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
1811a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    private static final Set<String> GLOBAL_RESTRICTIONS = Sets.newArraySet(
1821a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            UserManager.DISALLOW_ADJUST_VOLUME,
1837f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            UserManager.DISALLOW_BLUETOOTH_SHARING,
184a9772f360202b05858fa199088bfe94697a3f623yuemingw            UserManager.DISALLOW_CONFIG_DATE_TIME,
18522ff6f9df0b1e195f4d9daee0c7f4ba8f7ad6c9aCharles He            UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
1869cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov            UserManager.DISALLOW_RUN_IN_BACKGROUND,
187c1205111a92b52283078f1a2e86c8d32c5928b92Tony Mak            UserManager.DISALLOW_UNMUTE_MICROPHONE,
188492b4724fb42adf29f3978f01ebc5238f893d194Esteban Talavera            UserManager.DISALLOW_UNMUTE_DEVICE
1891a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    );
1901a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
1911f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki    /**
1926c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera     * User restrictions that default to {@code true} for device owners.
1936c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera     */
1946c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera    private static final Set<String> DEFAULT_ENABLED_FOR_DEVICE_OWNERS = Sets.newArraySet(
1956c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera            UserManager.DISALLOW_ADD_MANAGED_PROFILE
1966c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera    );
1976c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera
1987f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    /**
1997f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * User restrictions that default to {@code true} for managed profile owners.
2007f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     *
2017f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * NB: {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} is also set by default but it is
2027f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * not set to existing profile owners unless they used to have INSTALL_NON_MARKET_APPS disabled
2037f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * in settings. So it is handled separately.
2047f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     */
2057f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    private static final Set<String> DEFAULT_ENABLED_FOR_MANAGED_PROFILES = Sets.newArraySet(
2067f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            UserManager.DISALLOW_BLUETOOTH_SHARING
2077f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    );
2087f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov
209c4f87e9ceb4d5ce78c1663912bc166e0d41554aaPavel Grafov    /**
2106a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * Special user restrictions that are always applied to all users no matter who sets them.
2116a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     */
2126a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    private static final Set<String> PROFILE_GLOBAL_RESTRICTIONS = Sets.newArraySet(
2135fe75dc26d55a86f223fa5571b64e30731341564yuemingw            UserManager.ENSURE_VERIFY_APPS,
2145fe75dc26d55a86f223fa5571b64e30731341564yuemingw            UserManager.DISALLOW_AIRPLANE_MODE
2156a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    );
2166a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov
2176c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera    /**
2181f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki     * Throws {@link IllegalArgumentException} if the given restriction name is invalid.
2191f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki     */
2201f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki    public static boolean isValidRestriction(@NonNull String restriction) {
2211f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki        if (!USER_RESTRICTIONS.contains(restriction)) {
222ad5619d44701ef488e8d4bd41cb7a98f362097c7Makoto Onuki            Slog.e(TAG, "Unknown restriction: " + restriction);
2231f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki            return false;
2241f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki        }
2251f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki        return true;
2261f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki    }
2271f1ceef0f88a8c2758d1ec0ed6c1366bac7c9de4Makoto Onuki
2281a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    public static void writeRestrictions(@NonNull XmlSerializer serializer,
2291a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            @Nullable Bundle restrictions, @NonNull String tag) throws IOException {
2301a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        if (restrictions == null) {
2311a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            return;
2321a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
233a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
234a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        serializer.startTag(null, tag);
235ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki        for (String key : restrictions.keySet()) {
236ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki            if (NON_PERSIST_USER_RESTRICTIONS.contains(key)) {
237ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki                continue; // Don't persist.
238a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            }
239ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki            if (USER_RESTRICTIONS.contains(key)) {
240ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki                if (restrictions.getBoolean(key)) {
241ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki                    serializer.attribute(null, key, "true");
242ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki                }
243ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki                continue;
244ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki            }
245ac65e1e1dba1cf0ea237a389220ec818ade07a16Makoto Onuki            Log.w(TAG, "Unknown user restriction detected: " + key);
246a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        }
247a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        serializer.endTag(null, tag);
248a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki    }
249a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
250c48b20f8f1d3e07e8a931b195669b0ab8895006cEsteban Talavera    public static void readRestrictions(XmlPullParser parser, Bundle restrictions) {
251eafee02fdc463e765ce34b8541f4ba55989b4beeFyodor Kupolov        restrictions.clear();
252a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        for (String key : USER_RESTRICTIONS) {
253a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            final String value = parser.getAttributeValue(null, key);
254a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            if (value != null) {
255a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki                restrictions.putBoolean(key, Boolean.parseBoolean(value));
256a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            }
257a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        }
258a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki    }
259a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki
2606a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    public static Bundle readRestrictions(XmlPullParser parser) {
2616a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        final Bundle result = new Bundle();
2626a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        readRestrictions(parser, result);
2636a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        return result;
2646a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    }
2656a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov
2661a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
2671a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * @return {@code in} itself when it's not null, or an empty bundle (which can writable).
2681a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
2691a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    public static Bundle nonNull(@Nullable Bundle in) {
2701a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        return in != null ? in : new Bundle();
2711a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    }
2721a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
2731a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    public static boolean isEmpty(@Nullable Bundle in) {
2741a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        return (in == null) || (in.size() == 0);
2751a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    }
2761a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
2771a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
2786a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * Returns {@code true} if given bundle is not null and contains {@code true} for a given
2796a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * restriction.
2806a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     */
2816a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    public static boolean contains(@Nullable Bundle in, String restriction) {
2826a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        return in != null && in.getBoolean(restriction);
2836a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    }
2846a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov
2856a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    /**
2861a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * Creates a copy of the {@code in} Bundle.  If {@code in} is null, it'll return an empty
2871a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * bundle.
2881a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     *
2891a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * <p>The resulting {@link Bundle} is always writable. (i.e. it won't return
2901a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * {@link Bundle#EMPTY})
2911a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
2921a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    public static @NonNull Bundle clone(@Nullable Bundle in) {
2931a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        return (in != null) ? new Bundle(in) : new Bundle();
2941a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    }
2951a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
2961a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    public static void merge(@NonNull Bundle dest, @Nullable Bundle in) {
2971a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        Preconditions.checkNotNull(dest);
2981a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        Preconditions.checkArgument(dest != in);
299068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki        if (in == null) {
300068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki            return;
301068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki        }
302068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki        for (String key : in.keySet()) {
303068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki            if (in.getBoolean(key, false)) {
304068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki                dest.putBoolean(key, true);
305068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki            }
306068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki        }
307068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki    }
308068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki
3094f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki    /**
3106a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * Merges a sparse array of restrictions bundles into one.
3116a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     */
3126a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    @Nullable
3136a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    public static Bundle mergeAll(SparseArray<Bundle> restrictions) {
3146a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        if (restrictions.size() == 0) {
3156a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            return null;
3166a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        } else {
3176a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            final Bundle result = new Bundle();
3186a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            for (int i = 0; i < restrictions.size(); i++) {
3196a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                merge(result, restrictions.valueAt(i));
3206a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            }
3216a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            return result;
3226a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        }
3236a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    }
3246a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov
3256a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    /**
3261a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * @return true if a restriction is settable by device owner.
3271a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
3281a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    public static boolean canDeviceOwnerChange(String restriction) {
3291a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        return !IMMUTABLE_BY_OWNERS.contains(restriction);
3301a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    }
3311a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
3321a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
3335485ed46ff337769589c6e06b3469246e60b9e3bMakoto Onuki     * @return true if a restriction is settable by profile owner.  Note it takes a user ID because
3345485ed46ff337769589c6e06b3469246e60b9e3bMakoto Onuki     * some restrictions can be changed by PO only when it's running on the system user.
3351a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
3365485ed46ff337769589c6e06b3469246e60b9e3bMakoto Onuki    public static boolean canProfileOwnerChange(String restriction, int userId) {
3375485ed46ff337769589c6e06b3469246e60b9e3bMakoto Onuki        return !IMMUTABLE_BY_OWNERS.contains(restriction)
338ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz                && !DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction)
3395485ed46ff337769589c6e06b3469246e60b9e3bMakoto Onuki                && !(userId != UserHandle.USER_SYSTEM
3406a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                    && PRIMARY_USER_ONLY_RESTRICTIONS.contains(restriction));
3411a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    }
3421a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
3431a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
3446c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera     * Returns the user restrictions that default to {@code true} for device owners.
3452ea46fe658c5a977a11372d7180e8ed9abf261e8Nicolas Prevot     * These user restrictions are local, though. ie only for the device owner's user id.
3466c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera     */
3476c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera    public static @NonNull Set<String> getDefaultEnabledForDeviceOwner() {
3486c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera        return DEFAULT_ENABLED_FOR_DEVICE_OWNERS;
3496c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera    }
3506c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera
3516c9116a6430ca5cd55b1b926213a5e8de77e4fc6Esteban Talavera    /**
3527f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * Returns the user restrictions that default to {@code true} for managed profile owners.
3537f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     */
3547f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    public static @NonNull Set<String> getDefaultEnabledForManagedProfiles() {
3557f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov        return DEFAULT_ENABLED_FOR_MANAGED_PROFILES;
3567f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    }
3577f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov
3587f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    /**
3591a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * Takes restrictions that can be set by device owner, and sort them into what should be applied
3601a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * globally and what should be applied only on the current user.
3611a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
3626a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    public static void sortToGlobalAndLocal(@Nullable Bundle in, boolean isDeviceOwner,
3636a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            int cameraRestrictionScope,
3646a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            @NonNull Bundle global, @NonNull Bundle local) {
3656a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        // Camera restriction (as well as all others) goes to at most one bundle.
3666a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_GLOBALLY) {
3676a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            global.putBoolean(UserManager.DISALLOW_CAMERA, true);
3686a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        } else if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_LOCALLY) {
3696a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            local.putBoolean(UserManager.DISALLOW_CAMERA, true);
3706a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        }
3711a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        if (in == null || in.size() == 0) {
3721a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            return;
3731a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
3741a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        for (String key : in.keySet()) {
3751a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            if (!in.getBoolean(key)) {
3761a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki                continue;
3771a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            }
3786a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            if (isGlobal(isDeviceOwner, key)) {
3791a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki                global.putBoolean(key, true);
3801a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            } else {
3811a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki                local.putBoolean(key, true);
3821a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            }
3831a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
3841a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    }
3851a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
3861a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
3876a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * Whether given user restriction should be enforced globally.
3886a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     */
3896a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    private static boolean isGlobal(boolean isDeviceOwner, String key) {
3906a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        return (isDeviceOwner &&
391ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz                (PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)))
392ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz                || PROFILE_GLOBAL_RESTRICTIONS.contains(key)
393ff66fa9ef2e12654b5869cae844a9747dfc441ebBenjamin Franz                || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key);
3946a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    }
3956a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov
3966a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    /**
3971a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * @return true if two Bundles contain the same user restriction.
3981a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     * A null bundle and an empty bundle are considered to be equal.
3991a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki     */
4001a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    public static boolean areEqual(@Nullable Bundle a, @Nullable Bundle b) {
4011a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        if (a == b) {
4021a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            return true;
4031a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
4041a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        if (isEmpty(a)) {
4051a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            return isEmpty(b);
4061a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
4071a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        if (isEmpty(b)) {
4081a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            return false;
4091a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
4101a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        for (String key : a.keySet()) {
4111a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            if (a.getBoolean(key) != b.getBoolean(key)) {
4121a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki                return false;
4131a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            }
4141a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
4151a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        for (String key : b.keySet()) {
4161a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            if (a.getBoolean(key) != b.getBoolean(key)) {
4171a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki                return false;
4181a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            }
4191a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
4201a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        return true;
4211a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    }
4221a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki
4231a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki    /**
4244f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki     * Takes a new use restriction set and the previous set, and apply the restrictions that have
4254f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki     * changed.
426d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki     *
4279cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov     * <p>Note this method is called by {@link UserManagerService} without holding any locks.
4284f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki     */
4299cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov    public static void applyUserRestrictions(Context context, int userId,
430d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki            Bundle newRestrictions, Bundle prevRestrictions) {
4314f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        for (String key : USER_RESTRICTIONS) {
4324f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            final boolean newValue = newRestrictions.getBoolean(key);
4334f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            final boolean prevValue = prevRestrictions.getBoolean(key);
4344f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki
4354f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            if (newValue != prevValue) {
4369cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                applyUserRestriction(context, userId, key, newValue);
4374f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            }
4384f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        }
4394f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki    }
4409cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov
441d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki    /**
442d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki     * Apply each user restriction.
443d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki     *
4441d13eaea8380a43a31b12804f26d888f829feedfyuemingw     * <p>See also {@link #isSettingRestrictedForUser()},
44528da2e3490cff619157578c85d32a73ff979d554Makoto Onuki     * which should be in sync with this method.
446d45a4a2ecb18701b4cfadcb4a26663f2eab642feMakoto Onuki     */
4479cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov    private static void applyUserRestriction(Context context, int userId, String key,
4484f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            boolean newValue) {
4491a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        if (UserManagerService.DBG) {
4501a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki            Log.d(TAG, "Applying user restriction: userId=" + userId
4511a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki                    + " key=" + key + " value=" + newValue);
4521a2cd74526113b45d9108b6997609122c4311fb1Makoto Onuki        }
4534f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        // When certain restrictions are cleared, we don't update the system settings,
4544f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        // because these settings are changeable on the Settings UI and we don't know the original
4554f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        // value -- for example LOCATION_MODE might have been off already when the restriction was
4564f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        // set, and in that case even if the restriction is lifted, changing it to ON would be
4574f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        // wrong.  So just don't do anything in such a case.  If the user hopes to enable location
4584f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        // later, they can do it on the Settings UI.
4590ff13fce6fa4caa0cc61dae555881c4568020327Benjamin Franz        // WARNING: Remember that Settings.Global and Settings.Secure are changeable via adb.
4600ff13fce6fa4caa0cc61dae555881c4568020327Benjamin Franz        // To prevent this from happening for a given user restriction, you have to add a check to
4610ff13fce6fa4caa0cc61dae555881c4568020327Benjamin Franz        // SettingsProvider.isGlobalOrSecureSettingRestrictedForUser.
4624f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki
4634f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        final ContentResolver cr = context.getContentResolver();
4644f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        final long id = Binder.clearCallingIdentity();
4654f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        try {
4664f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            switch (key) {
467dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                case UserManager.DISALLOW_DATA_ROAMING:
468dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                    if (newValue) {
469dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                        // DISALLOW_DATA_ROAMING user restriction is set.
470dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra
471dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                        // Multi sim device.
472717f52f2dd8920d387c4d5143c7646787cec13bfJeff Sharkey                        SubscriptionManager subscriptionManager = context
473717f52f2dd8920d387c4d5143c7646787cec13bfJeff Sharkey                                .getSystemService(SubscriptionManager.class);
474dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                        final List<SubscriptionInfo> subscriptionInfoList =
475dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                            subscriptionManager.getActiveSubscriptionInfoList();
476dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                        if (subscriptionInfoList != null) {
477dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                            for (SubscriptionInfo subInfo : subscriptionInfoList) {
478dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                                android.provider.Settings.Global.putStringForUser(cr,
479dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                                    android.provider.Settings.Global.DATA_ROAMING
480dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                                    + subInfo.getSubscriptionId(), "0", userId);
481dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                            }
482dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                        }
483dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra
484dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                        // Single sim device.
485dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                        android.provider.Settings.Global.putStringForUser(cr,
486dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                            android.provider.Settings.Global.DATA_ROAMING, "0", userId);
487dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                    }
488dea471ef548f09e04e178c5ec2d71a4b79bdb8f8Mahaver Chopra                    break;
4894f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                case UserManager.DISALLOW_SHARE_LOCATION:
4904f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    if (newValue) {
4914f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                        android.provider.Settings.Secure.putIntForUser(cr,
4924f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                android.provider.Settings.Secure.LOCATION_MODE,
4934f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                android.provider.Settings.Secure.LOCATION_MODE_OFF,
4944f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                userId);
4954f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    }
4964f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    break;
4974f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                case UserManager.DISALLOW_DEBUGGING_FEATURES:
4984f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    if (newValue) {
4994f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                        // Only disable adb if changing for system user, since it is global
5004f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                        // TODO: should this be admin user?
5014f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                        if (userId == UserHandle.USER_SYSTEM) {
5024f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                            android.provider.Settings.Global.putStringForUser(cr,
5034f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                    android.provider.Settings.Global.ADB_ENABLED, "0",
5044f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                    userId);
5054f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                        }
5064f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    }
5074f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    break;
5084f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                case UserManager.ENSURE_VERIFY_APPS:
5094f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    if (newValue) {
5104f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                        android.provider.Settings.Global.putStringForUser(
5114f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                context.getContentResolver(),
5124f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, "1",
5134f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                userId);
5144f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                        android.provider.Settings.Global.putStringForUser(
5154f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                context.getContentResolver(),
5164f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1",
5174f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                                userId);
5184f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    }
5194f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    break;
5204f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES:
521e3745eed8b9599de6f413d48a81098209fd41791Suprabh Shukla                    // Since Android O, the secure setting is not available to be changed by the
522e3745eed8b9599de6f413d48a81098209fd41791Suprabh Shukla                    // user. Hence, when the restriction is cleared, we need to reset the state of
523e3745eed8b9599de6f413d48a81098209fd41791Suprabh Shukla                    // the setting to its default value which is now 1.
524e3745eed8b9599de6f413d48a81098209fd41791Suprabh Shukla                    android.provider.Settings.Secure.putIntForUser(cr,
525e3745eed8b9599de6f413d48a81098209fd41791Suprabh Shukla                            android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
526e3745eed8b9599de6f413d48a81098209fd41791Suprabh Shukla                            newValue ? 0 : 1, userId);
5274f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki                    break;
5289cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                case UserManager.DISALLOW_RUN_IN_BACKGROUND:
5299cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                    if (newValue) {
5309cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                        int currentUser = ActivityManager.getCurrentUser();
5319cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                        if (currentUser != userId && userId != UserHandle.USER_SYSTEM) {
5329cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                            try {
533dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka                                ActivityManager.getService().stopUser(userId, false, null);
5349cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                            } catch (RemoteException e) {
5359cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                                throw e.rethrowAsRuntimeException();
5369cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                            }
5379cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                        }
5389cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov                    }
5396474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    break;
5406474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                case UserManager.DISALLOW_SAFE_BOOT:
5416474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    // Unlike with the other restrictions, we want to propagate the new value to
5426474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    // the system settings even if it is false. The other restrictions modify
5436474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    // settings which could be manually changed by the user from the Settings app
5446474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    // after the policies enforcing these restrictions have been revoked, so we
5456474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    // leave re-setting of those settings to the user.
5466474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    android.provider.Settings.Global.putInt(
5476474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                            context.getContentResolver(),
5486474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                            android.provider.Settings.Global.SAFE_BOOT_DISALLOWED,
5496474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                            newValue ? 1 : 0);
5506474f0e02b9a00c1f69f985c0d73cf7f8c0fb073Lenka Trochtova                    break;
551265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                case UserManager.DISALLOW_AIRPLANE_MODE:
552265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                    if (newValue) {
553265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                        final boolean airplaneMode = Settings.Global.getInt(
554265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                                context.getContentResolver(),
555265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                                Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
556265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                        if (airplaneMode) {
557265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                            android.provider.Settings.Global.putInt(
558265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                                    context.getContentResolver(),
559265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                                    android.provider.Settings.Global.AIRPLANE_MODE_ON, 0);
560265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                            // Post the intent.
561265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                            Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
562f3b9734464a850a10c6ee8cdc66773ac1aed951ayuemingw                            intent.putExtra("state", false);
563265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                            context.sendBroadcastAsUser(intent, UserHandle.ALL);
564265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                        }
565265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                    }
566265c692c8ec5a50054e0279321a98e7af85c2117yuemingw                    break;
567c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                case UserManager.DISALLOW_AMBIENT_DISPLAY:
568c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                    if (newValue) {
5691e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                        android.provider.Settings.Secure.putIntForUser(
570c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                                context.getContentResolver(),
5711e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                                Settings.Secure.DOZE_ENABLED, 0, userId);
5721e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                        android.provider.Settings.Secure.putIntForUser(
573c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                                context.getContentResolver(),
5741e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                                Settings.Secure.DOZE_ALWAYS_ON, 0, userId);
5751e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                        android.provider.Settings.Secure.putIntForUser(
576c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                                context.getContentResolver(),
5771e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                                Settings.Secure.DOZE_PULSE_ON_PICK_UP, 0, userId);
5781e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                        android.provider.Settings.Secure.putIntForUser(
579c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                                context.getContentResolver(),
5801e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                                Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, 0, userId);
5811e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                        android.provider.Settings.Secure.putIntForUser(
582c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                                context.getContentResolver(),
5831e2b7318ba852c50554f3acd927b3bea0cdff445Alex Chau                                Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, 0, userId);
584c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                    }
585c010951c91588d0bf458eacc6358ec3cf26150b0yuemingw                    break;
586acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                case UserManager.DISALLOW_CONFIG_LOCATION:
587acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                    // When DISALLOW_CONFIG_LOCATION is set on any user, we undo the global
588acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                    // kill switch.
589acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                    if (newValue) {
590acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                        android.provider.Settings.Global.putString(
591acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                                context.getContentResolver(),
592acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                                Global.LOCATION_GLOBAL_KILL_SWITCH, "0");
593acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                    }
594acc50461bb7cec5012bb9c58acebeae9ad729232Makoto Onuki                    break;
5954f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            }
5964f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        } finally {
5974f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki            Binder.restoreCallingIdentity(id);
5984f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki        }
5994f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki    }
6004f16073556f7978708fb71c87628cfe1692412d5Makoto Onuki
6011d13eaea8380a43a31b12804f26d888f829feedfyuemingw    public static boolean isSettingRestrictedForUser(Context context, @NonNull String setting,
6021d13eaea8380a43a31b12804f26d888f829feedfyuemingw            int userId, String value, int callingUid) {
6031d13eaea8380a43a31b12804f26d888f829feedfyuemingw        Preconditions.checkNotNull(setting);
6041d13eaea8380a43a31b12804f26d888f829feedfyuemingw        final UserManager mUserManager = context.getSystemService(UserManager.class);
6051d13eaea8380a43a31b12804f26d888f829feedfyuemingw        String restriction;
6061d13eaea8380a43a31b12804f26d888f829feedfyuemingw        boolean checkAllUser = false;
6071d13eaea8380a43a31b12804f26d888f829feedfyuemingw        switch (setting) {
6081d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.LOCATION_MODE:
6091d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (mUserManager.hasUserRestriction(
6101d13eaea8380a43a31b12804f26d888f829feedfyuemingw                        UserManager.DISALLOW_CONFIG_LOCATION, UserHandle.of(userId))
6111d13eaea8380a43a31b12804f26d888f829feedfyuemingw                        && callingUid != Process.SYSTEM_UID) {
6121d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return true;
6131d13eaea8380a43a31b12804f26d888f829feedfyuemingw                } else if (String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(value)) {
6141d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    // Note LOCATION_MODE will be converted into LOCATION_PROVIDERS_ALLOWED
6151d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    // in android.provider.Settings.Secure.putStringForUser(), so we shouldn't come
6161d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    // here normally, but we still protect it here from a direct provider write.
6171d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6181d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6191d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_SHARE_LOCATION;
6201d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6211d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6221d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED:
6231d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (mUserManager.hasUserRestriction(
6241d13eaea8380a43a31b12804f26d888f829feedfyuemingw                        UserManager.DISALLOW_CONFIG_LOCATION, UserHandle.of(userId))
6251d13eaea8380a43a31b12804f26d888f829feedfyuemingw                        && callingUid != Process.SYSTEM_UID) {
6261d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return true;
6271d13eaea8380a43a31b12804f26d888f829feedfyuemingw                } else if (value != null && value.startsWith("-")) {
6281d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    // See SettingsProvider.updateLocationProvidersAllowedLocked.  "-" is to disable
6291d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    // a provider, which should be allowed even if the user restriction is set.
6301d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6311d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6321d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_SHARE_LOCATION;
6331d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6341d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6351d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS:
6361d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if ("0".equals(value)) {
6371d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6381d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6391d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES;
6401d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6411d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6421d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.ADB_ENABLED:
6431d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if ("0".equals(value)) {
6441d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6451d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6461d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_DEBUGGING_FEATURES;
6471d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6481d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6491d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE:
6501d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB:
6511d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if ("1".equals(value)) {
6521d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6531d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6541d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.ENSURE_VERIFY_APPS;
6551d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6561d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6571d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.PREFERRED_NETWORK_MODE:
6581d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS;
6591d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6601d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6611d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.ALWAYS_ON_VPN_APP:
6621d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN:
6631d13eaea8380a43a31b12804f26d888f829feedfyuemingw                // Whitelist system uid (ConnectivityService) and root uid to change always-on vpn
6641d13eaea8380a43a31b12804f26d888f829feedfyuemingw                final int appId = UserHandle.getAppId(callingUid);
6651d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
6661d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6671d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6681d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_CONFIG_VPN;
6691d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6701d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6711d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.SAFE_BOOT_DISALLOWED:
6721d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if ("1".equals(value)) {
6731d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6741d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6751d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_SAFE_BOOT;
6761d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6771d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6781d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.AIRPLANE_MODE_ON:
6791d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if ("0".equals(value)) {
6801d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6811d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6821d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_AIRPLANE_MODE;
6831d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6841d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6851d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.DOZE_ENABLED:
6861d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.DOZE_ALWAYS_ON:
6871d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.DOZE_PULSE_ON_PICK_UP:
6881d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.DOZE_PULSE_ON_LONG_PRESS:
6891d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP:
6901d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if ("0".equals(value)) {
6911d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6921d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
6931d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_AMBIENT_DISPLAY;
6941d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
6951d13eaea8380a43a31b12804f26d888f829feedfyuemingw
6961d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.LOCATION_GLOBAL_KILL_SWITCH:
6971d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if ("0".equals(value)) {
6981d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
6991d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
7001d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_CONFIG_LOCATION;
7011d13eaea8380a43a31b12804f26d888f829feedfyuemingw                checkAllUser = true;
7021d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
7031d13eaea8380a43a31b12804f26d888f829feedfyuemingw
7041d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.System.SCREEN_BRIGHTNESS:
7051d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE:
7061d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (callingUid == Process.SYSTEM_UID) {
7071d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
7081d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
7091d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_CONFIG_BRIGHTNESS;
7101d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
7111d13eaea8380a43a31b12804f26d888f829feedfyuemingw
7121d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.AUTO_TIME:
7131d13eaea8380a43a31b12804f26d888f829feedfyuemingw                DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
7141d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (dpm != null && dpm.getAutoTimeRequired()
7151d13eaea8380a43a31b12804f26d888f829feedfyuemingw                        && "0".equals(value)) {
7161d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return true;
7171d13eaea8380a43a31b12804f26d888f829feedfyuemingw                } else if (callingUid == Process.SYSTEM_UID) {
7181d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
7191d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
7201d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_CONFIG_DATE_TIME;
7211d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
7221d13eaea8380a43a31b12804f26d888f829feedfyuemingw
7231d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.Global.AUTO_TIME_ZONE:
7241d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (callingUid == Process.SYSTEM_UID) {
7251d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
7261d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
7271d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_CONFIG_DATE_TIME;
7281d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
7291d13eaea8380a43a31b12804f26d888f829feedfyuemingw
7301d13eaea8380a43a31b12804f26d888f829feedfyuemingw            case android.provider.Settings.System.SCREEN_OFF_TIMEOUT:
7311d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (callingUid == Process.SYSTEM_UID) {
7321d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    return false;
7331d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
7341d13eaea8380a43a31b12804f26d888f829feedfyuemingw                restriction = UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT;
7351d13eaea8380a43a31b12804f26d888f829feedfyuemingw                break;
7361d13eaea8380a43a31b12804f26d888f829feedfyuemingw
7371d13eaea8380a43a31b12804f26d888f829feedfyuemingw            default:
7381d13eaea8380a43a31b12804f26d888f829feedfyuemingw                if (setting.startsWith(Settings.Global.DATA_ROAMING)) {
7391d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    if ("0".equals(value)) {
7401d13eaea8380a43a31b12804f26d888f829feedfyuemingw                        return false;
7411d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    }
7421d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    restriction = UserManager.DISALLOW_DATA_ROAMING;
7431d13eaea8380a43a31b12804f26d888f829feedfyuemingw                    break;
7441d13eaea8380a43a31b12804f26d888f829feedfyuemingw                }
7451d13eaea8380a43a31b12804f26d888f829feedfyuemingw                return false;
7461d13eaea8380a43a31b12804f26d888f829feedfyuemingw        }
7471d13eaea8380a43a31b12804f26d888f829feedfyuemingw
7481d13eaea8380a43a31b12804f26d888f829feedfyuemingw        if (checkAllUser) {
7491d13eaea8380a43a31b12804f26d888f829feedfyuemingw            return mUserManager.hasUserRestrictionOnAnyUser(restriction);
7501d13eaea8380a43a31b12804f26d888f829feedfyuemingw        } else {
7511d13eaea8380a43a31b12804f26d888f829feedfyuemingw            return mUserManager.hasUserRestriction(restriction, UserHandle.of(userId));
7521d13eaea8380a43a31b12804f26d888f829feedfyuemingw        }
7531d13eaea8380a43a31b12804f26d888f829feedfyuemingw    }
7541d13eaea8380a43a31b12804f26d888f829feedfyuemingw
755a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki    public static void dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions) {
756a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        boolean noneSet = true;
757a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        if (restrictions != null) {
758a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            for (String key : restrictions.keySet()) {
759a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki                if (restrictions.getBoolean(key, false)) {
760a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki                    pw.println(prefix + key);
761a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki                    noneSet = false;
762a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki                }
763a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki            }
764068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki            if (noneSet) {
765068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki                pw.println(prefix + "none");
766068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki            }
767068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki        } else {
768068c54a5be697c3df4657dcda33cd17c4b547710Makoto Onuki            pw.println(prefix + "null");
769a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki        }
770a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki    }
7716a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov
7726a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    /**
7736a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     * Moves a particular restriction from one array of bundles to another, e.g. for all users.
7746a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov     */
7756a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    public static void moveRestriction(String restrictionKey, SparseArray<Bundle> srcRestrictions,
7766a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            SparseArray<Bundle> destRestrictions) {
7776a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        for (int i = 0; i < srcRestrictions.size(); i++) {
7787f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            final int key = srcRestrictions.keyAt(i);
7797f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            final Bundle from = srcRestrictions.valueAt(i);
7806a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            if (contains(from, restrictionKey)) {
7816a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                from.remove(restrictionKey);
7826a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                Bundle to = destRestrictions.get(key);
7836a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                if (to == null) {
7846a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                    to = new Bundle();
7856a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                    destRestrictions.append(key, to);
7866a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                }
7876a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                to.putBoolean(restrictionKey, true);
7886a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                // Don't keep empty bundles.
7896a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                if (from.isEmpty()) {
7906a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                    srcRestrictions.removeAt(i);
7916a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                    i--;
7926a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov                }
7936a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov            }
7946a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov        }
7956a40f09083fc52acc3309d0b04401fca02df6372Pavel Grafov    }
7967f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov
7977f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    /**
7987f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * Returns whether restrictions differ between two bundles.
7997f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * @param oldRestrictions old bundle of restrictions.
8007f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * @param newRestrictions new bundle of restrictions
8017f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     * @param restrictions restrictions of interest, if empty, all restrictions are checked.
8027f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov     */
8037f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    public static boolean restrictionsChanged(Bundle oldRestrictions, Bundle newRestrictions,
8047f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            String... restrictions) {
8057f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov        if (restrictions.length == 0) {
8067f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            return areEqual(oldRestrictions, newRestrictions);
8077f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov        }
8087f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov        for (final String restriction : restrictions) {
8097f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            if (oldRestrictions.getBoolean(restriction, false) !=
8107f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov                    newRestrictions.getBoolean(restriction, false)) {
8117f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov                return true;
8127f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov            }
8137f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov        }
8147f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov        return false;
8157f4ad75218bdd3f1bdf9022a146147eae032cc0cPavel Grafov    }
816a4f119790e32fcce56586e7324d508e35cb30a2aMakoto Onuki}
817