1ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz/*
2ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * Copyright 2016, The Android Open Source Project
3ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz *
4ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * Licensed under the Apache License, Version 2.0 (the "License");
5ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * you may not use this file except in compliance with the License.
6ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * You may obtain a copy of the License at
7ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz *
8ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz *      http://www.apache.org/licenses/LICENSE-2.0
9ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz *
10ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * Unless required by applicable law or agreed to in writing, software
11ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * distributed under the License is distributed on an "AS IS" BASIS,
12ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * See the License for the specific language governing permissions and
14ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz * limitations under the License.
15ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz */
16ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
17f7a9eea8fe577f2f5edbbe6e73891a54351286c6Benjamin Franzpackage com.android.managedprovisioning.preprovisioning;
18ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
19ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
2055312a63a09f7168ed9b40325b5ce088b69aaedaVictor Changimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE;
2192ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
22ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE;
2392ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
24d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernándezimport static android.app.admin.DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED;
2592ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE;
2692ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.CODE_HAS_DEVICE_OWNER;
2792ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED;
2892ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER;
2992ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT;
3092ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.CODE_OK;
3192ec1bff8d03110052b836e9176184c51e5bd043Mahaverimport static android.app.admin.DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER;
3255312a63a09f7168ed9b40325b5ce088b69aaedaVictor Changimport static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED;
3389a9e9754a5c68791ab0e43cf2c51e92dfcfe6b6Jakub Gielzak
3492013087f0eb359c2ab56564b08be8d3382afbceTamas Berghammerimport static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_PREPROVISIONING_ACTIVITY_TIME_MS;
35ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static com.android.internal.util.Preconditions.checkNotNull;
3695c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopraimport static com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker.CANCELLED_BEFORE_PROVISIONING;
37c79c4bc4e83edd3938e13dc4a434d5a1bb638498Benjamin Franzimport static com.android.managedprovisioning.common.Globals.ACTION_RESUME_PROVISIONING;
38ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
39ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.annotation.NonNull;
4089a9e9754a5c68791ab0e43cf2c51e92dfcfe6b6Jakub Gielzakimport android.annotation.Nullable;
41ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.app.ActivityManager;
42ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.app.KeyguardManager;
43c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzakimport android.app.admin.DevicePolicyManager;
44ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.ComponentName;
45ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.Context;
46ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.Intent;
47d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtovaimport android.content.pm.PackageInfo;
48ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.pm.PackageManager;
49ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.pm.UserInfo;
5021d7fee248eb5cc5465cc986683bfb88e71aea57Victor Changimport android.graphics.Bitmap;
5121d7fee248eb5cc5465cc986683bfb88e71aea57Victor Changimport android.graphics.BitmapFactory;
5221d7fee248eb5cc5465cc986683bfb88e71aea57Victor Changimport android.graphics.drawable.BitmapDrawable;
53c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzakimport android.graphics.drawable.Drawable;
54ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.os.AsyncTask;
55ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.os.UserManager;
56ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.service.persistentdata.PersistentDataBlockManager;
57d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtovaimport android.text.TextUtils;
58ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
59ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.internal.annotations.VisibleForTesting;
60c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzakimport com.android.managedprovisioning.R;
615752705d941f30e094daf01b947ac971d316481aMahaver Chopraimport com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
62c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzakimport com.android.managedprovisioning.analytics.TimeLogger;
63ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
64c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzakimport com.android.managedprovisioning.common.MdmPackageInfo;
65c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzakimport com.android.managedprovisioning.common.ProvisionLogger;
6648132dd835f559e3d01ee7d2198c285bf4972e35Benjamin Franzimport com.android.managedprovisioning.common.SettingsFacade;
6777bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzakimport com.android.managedprovisioning.common.StoreUtils;
68ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.common.Utils;
692d9df010d67dfa884c8af3164d37da028ea6b741Jakub Gielzakimport com.android.managedprovisioning.model.CustomizationParams;
707079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.model.ProvisioningParams;
717079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.parser.MessageParser;
7277bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzakimport com.android.managedprovisioning.preprovisioning.terms.TermsDocument;
7377bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzakimport com.android.managedprovisioning.preprovisioning.terms.TermsProvider;
74ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
75ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport java.util.List;
7677bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzakimport java.util.stream.Collectors;
77ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
78ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzpublic class PreProvisioningController {
79ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final Context mContext;
80ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final Ui mUi;
81ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final MessageParser mMessageParser;
82ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final Utils mUtils;
8348132dd835f559e3d01ee7d2198c285bf4972e35Benjamin Franz    private final SettingsFacade mSettingsFacade;
840a964a32b7e8e7b2207416530f8f4575e1cde46eBenjamin Franz    private final EncryptionController mEncryptionController;
85ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
86ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    // used system services
87ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final DevicePolicyManager mDevicePolicyManager;
88ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final UserManager mUserManager;
89ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final PackageManager mPackageManager;
90ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final ActivityManager mActivityManager;
91ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final KeyguardManager mKeyguardManager;
92ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final PersistentDataBlockManager mPdbManager;
933ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra    private final TimeLogger mTimeLogger;
94bbb4eef7beb9a0171eac722e3cb79a8b7181da02Mahaver Chopra    private final ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker;
95ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
96ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private ProvisioningParams mParams;
97ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
98ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public PreProvisioningController(
99ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Context context,
100ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Ui ui) {
101a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra        this(context, ui,
1023ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra                new TimeLogger(context, PROVISIONING_PREPROVISIONING_ACTIVITY_TIME_MS),
10390f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang                new MessageParser(context), new Utils(), new SettingsFacade(),
10448132dd835f559e3d01ee7d2198c285bf4972e35Benjamin Franz                EncryptionController.getInstance(context));
105ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
106ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
107ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    @VisibleForTesting
108ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    PreProvisioningController(
109ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Context context,
110ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Ui ui,
1113ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra            @NonNull TimeLogger timeLogger,
112ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull MessageParser parser,
1130a964a32b7e8e7b2207416530f8f4575e1cde46eBenjamin Franz            @NonNull Utils utils,
11448132dd835f559e3d01ee7d2198c285bf4972e35Benjamin Franz            @NonNull SettingsFacade settingsFacade,
1150a964a32b7e8e7b2207416530f8f4575e1cde46eBenjamin Franz            @NonNull EncryptionController encryptionController) {
116ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mContext = checkNotNull(context, "Context must not be null");
117ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUi = checkNotNull(ui, "Ui must not be null");
1183ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra        mTimeLogger = checkNotNull(timeLogger, "Time logger must not be null");
119ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mMessageParser = checkNotNull(parser, "MessageParser must not be null");
12048132dd835f559e3d01ee7d2198c285bf4972e35Benjamin Franz        mSettingsFacade = checkNotNull(settingsFacade);
121ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUtils = checkNotNull(utils, "Utils must not be null");
1220a964a32b7e8e7b2207416530f8f4575e1cde46eBenjamin Franz        mEncryptionController = checkNotNull(encryptionController,
1230a964a32b7e8e7b2207416530f8f4575e1cde46eBenjamin Franz                "EncryptionController must not be null");
124ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
125ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
126ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                Context.DEVICE_POLICY_SERVICE);
127ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
128ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mPackageManager = mContext.getPackageManager();
129ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
130ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
131ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mPdbManager = (PersistentDataBlockManager) mContext.getSystemService(
132ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                Context.PERSISTENT_DATA_BLOCK_SERVICE);
133bbb4eef7beb9a0171eac722e3cb79a8b7181da02Mahaver Chopra        mProvisioningAnalyticsTracker = ProvisioningAnalyticsTracker.getInstance();
134ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
135ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
136ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    interface Ui {
137ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
138ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Show an error message and cancel provisioning.
139121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak         * @param titleId resource id used to form the user facing error title
140121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak         * @param messageId resource id used to form the user facing error message
141ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param errorMessage an error message that gets logged for debugging
142ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
143d4c471e22aae4572795c67096e41367c23ef4164Victor Chang        void showErrorAndClose(Integer titleId, int messageId, String errorMessage);
144ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
145ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
146ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Request the user to encrypt the device.
147ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param params the {@link ProvisioningParams} object related to the ongoing provisioning
148ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
149ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void requestEncryption(ProvisioningParams params);
150ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
151ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
152ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Request the user to choose a wifi network.
153ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
154ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void requestWifiPick();
155ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
156ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
1576cf9a785c31b297dc427e041315d54d2ef6a5fcfJakub Gielzak         * Initialize the pre provisioning UI
1586cf9a785c31b297dc427e041315d54d2ef6a5fcfJakub Gielzak         * @param layoutRes resource id for the layout
159ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param titleRes resource id for the title text
1603cc3880a7d61101d439cf6c5fdd351e22fdc8f4fJakub Gielzak         * @param packageLabel package label
1613760737d7e3f245ea6583b0aa8d4fa031f434f98Jakub Gielzak         * @param packageIcon package icon
1623760737d7e3f245ea6583b0aa8d4fa031f434f98Jakub Gielzak         * @param isProfileOwnerProvisioning false for Device Owner provisioning
1632d9df010d67dfa884c8af3164d37da028ea6b741Jakub Gielzak         * @param isComp true if in COMP provisioning mode
1643760737d7e3f245ea6583b0aa8d4fa031f434f98Jakub Gielzak         * @param termsHeaders list of terms headers
1653cc3880a7d61101d439cf6c5fdd351e22fdc8f4fJakub Gielzak         * @param customization customization parameters
166ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
1673cc3880a7d61101d439cf6c5fdd351e22fdc8f4fJakub Gielzak        void initiateUi(int layoutRes, int titleRes, @Nullable String packageLabel,
1682d9df010d67dfa884c8af3164d37da028ea6b741Jakub Gielzak                @Nullable Drawable packageIcon, boolean isProfileOwnerProvisioning, boolean isComp,
1693cc3880a7d61101d439cf6c5fdd351e22fdc8f4fJakub Gielzak                @NonNull List<String> termsHeaders, @NonNull CustomizationParams customization);
170ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
171ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
172c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak         * Start provisioning.
173ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param userId the id of the user we want to start provisioning on
174ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param params the {@link ProvisioningParams} object related to the ongoing provisioning
175ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
176c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        void startProvisioning(int userId, ProvisioningParams params);
177ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
178ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
179ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Show a dialog to delete an existing managed profile.
180ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param mdmPackageName the {@link ComponentName} of the existing profile's profile owner
181ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param domainName domain name of the organization which owns the managed profile
182ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param userId the user id of the existing profile
183ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
184ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void showDeleteManagedProfileDialog(ComponentName mdmPackageName, String domainName,
185ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                int userId);
186ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
187ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
188ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Show an error dialog indicating that the current launcher does not support managed
189ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * profiles and ask the user to choose a different one.
190ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
191ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void showCurrentLauncherInvalid();
192ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
193ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
194a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra    /**
195a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     * Initiates Profile owner and device owner provisioning.
196a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     * @param intent Intent that started provisioning.
19790f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang     * @param params cached ProvisioningParams if it has been parsed from Intent
198a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     * @param callingPackage Package that started provisioning.
199a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     */
20090f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang    public void initiateProvisioning(Intent intent, ProvisioningParams params,
20190f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang            String callingPackage) {
20234293e3049bf44310b23d70c6f3ff5224ca655d7Mahaver        mProvisioningAnalyticsTracker.logProvisioningSessionStarted(mContext);
20334293e3049bf44310b23d70c6f3ff5224ca655d7Mahaver
204d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        if (!tryParseParameters(intent, params)) {
205ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
206ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
207ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
208d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        if (!checkFactoryResetProtection(mParams, callingPackage)) {
209c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            return;
210c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        }
211c79c4bc4e83edd3938e13dc4a434d5a1bb638498Benjamin Franz
21255312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        if (!verifyActionAndCaller(intent, callingPackage)) {
213ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
214ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
215ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
216c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // Check whether provisioning is allowed for the current action
217c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (!checkDevicePolicyPreconditions()) {
218c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            return;
219c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        }
220c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak
221c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // PO preconditions
222c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        boolean waitForUserDelete = false;
223c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (isProfileOwnerProvisioning()) {
224c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            // If there is already a managed profile, setup the profile deletion dialog.
225c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            int existingManagedProfileUserId = mUtils.alreadyHasManagedProfile(mContext);
226c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            if (existingManagedProfileUserId != -1) {
227c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                ComponentName mdmPackageName = mDevicePolicyManager
228c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                        .getProfileOwnerAsUser(existingManagedProfileUserId);
229c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                String domainName = mDevicePolicyManager
230c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                        .getProfileOwnerNameAsUser(existingManagedProfileUserId);
231c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mUi.showDeleteManagedProfileDialog(mdmPackageName, domainName,
232c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                        existingManagedProfileUserId);
233c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                waitForUserDelete = true;
234c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            }
235c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        }
236c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak
237c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // DO preconditions
238c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (!isProfileOwnerProvisioning()) {
239c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            // TODO: make a general test based on deviceAdminDownloadInfo field
240c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            // PO doesn't ever initialize that field, so OK as a general case
241c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            if (!mUtils.isConnectedToNetwork(mContext) && mParams.wifiInfo == null
242c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    && mParams.deviceAdminDownloadInfo != null) {
243c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // Have the user pick a wifi network if necessary.
244c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // It is not possible to ask the user to pick a wifi network if
245c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // the screen is locked.
246c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // TODO: remove this check once we know the screen will not be locked.
247c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                if (mKeyguardManager.inKeyguardRestrictedInputMode()) {
248c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    // TODO: decide on what to do in that case; fail? retry on screen unlock?
249c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    ProvisionLogger.logi("Cannot pick wifi because the screen is locked.");
250c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                } else if (canRequestWifiPick()) {
251c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    // we resume this method after a successful WiFi pick
252c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    // TODO: refactor as evil - logic should be less spread out
253c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    mUi.requestWifiPick();
254c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    return;
255c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                } else {
256121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                    mUi.showErrorAndClose(R.string.cant_set_up_device,
257121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                            R.string.contact_your_admin_for_help,
258c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                            "Cannot pick WiFi because there is no handler to the intent");
259c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                }
260c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            }
261ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
262ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
2633ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra        mTimeLogger.start();
2647e9f77a5b5c403c165949dd8df3b25ba19f28333Mahaver Chopra        mProvisioningAnalyticsTracker.logPreProvisioningStarted(mContext, intent);
265c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak
266c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // as of now this is only true for COMP provisioning, where we already have a user consent
267c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // since the DPC is DO already
268c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (mParams.skipUserConsent || isSilentProvisioningForTestingDeviceOwner()
269c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                || isSilentProvisioningForTestingManagedProfile()) {
270c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            if (!waitForUserDelete) {
271c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                continueProvisioningAfterUserConsent();
272c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            }
273c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            return;
274c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        }
2753760737d7e3f245ea6583b0aa8d4fa031f434f98Jakub Gielzak
2763cc3880a7d61101d439cf6c5fdd351e22fdc8f4fJakub Gielzak        CustomizationParams customization = CustomizationParams.createInstance(mParams, mContext,
2773cc3880a7d61101d439cf6c5fdd351e22fdc8f4fJakub Gielzak                mUtils);
27889a9e9754a5c68791ab0e43cf2c51e92dfcfe6b6Jakub Gielzak
279c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // show UI so we can get user's consent to continue
280c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (isProfileOwnerProvisioning()) {
2812d9df010d67dfa884c8af3164d37da028ea6b741Jakub Gielzak            boolean isComp = mDevicePolicyManager.isDeviceManaged();
28277bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak            mUi.initiateUi(R.layout.intro_profile_owner, R.string.setup_profile, null, null, true,
28377bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak                    isComp, getDisclaimerHeadings(), customization);
284ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
285c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            String packageName = mParams.inferDeviceAdminPackageName();
286c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            MdmPackageInfo packageInfo = MdmPackageInfo.createFromPackageName(mContext,
287c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    packageName);
28821d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang            // Always take packageInfo first for installed app since PackageManager is more reliable
28921d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang            String packageLabel = packageInfo != null ? packageInfo.appLabel
29021d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang                    : mParams.deviceAdminLabel != null ? mParams.deviceAdminLabel : packageName;
29121d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang            Drawable packageIcon = packageInfo != null ? packageInfo.packageIcon
29221d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang                    : getDeviceAdminIconDrawable(mParams.deviceAdminIconFilePath);
293c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            mUi.initiateUi(R.layout.intro_device_owner,
2942d9ad3273f375a84cf32ea33b55a9bcde43d7bc7Jakub Gielzak                    R.string.setup_device,
29521d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang                    packageLabel,
29621d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang                    packageIcon,
2972d9df010d67dfa884c8af3164d37da028ea6b741Jakub Gielzak                    false  /* isProfileOwnerProvisioning */,
2982d9df010d67dfa884c8af3164d37da028ea6b741Jakub Gielzak                    false, /* isComp */
29977bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak                    getDisclaimerHeadings(),
3002d9df010d67dfa884c8af3164d37da028ea6b741Jakub Gielzak                    customization);
3013760737d7e3f245ea6583b0aa8d4fa031f434f98Jakub Gielzak        }
3023760737d7e3f245ea6583b0aa8d4fa031f434f98Jakub Gielzak    }
3033760737d7e3f245ea6583b0aa8d4fa031f434f98Jakub Gielzak
30477bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak    private @NonNull List<String> getDisclaimerHeadings() {
30577bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak        // TODO: only fetch headings, no need to fetch content; now not fast, but at least correct
30677bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak        return new TermsProvider(mContext, StoreUtils::readString, mUtils)
30777bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak                .getTerms(mParams, TermsProvider.Flags.SKIP_GENERAL_DISCLAIMER)
30877bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak                .stream()
30977bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak                .map(TermsDocument::getHeading)
31077bde860481225e2ecdff18e9669f877d2a74ae7Jakub Gielzak                .collect(Collectors.toList());
311ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
312ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
31321d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang    private Drawable getDeviceAdminIconDrawable(String deviceAdminIconFilePath) {
31421d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang        if (deviceAdminIconFilePath == null) {
31521d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang            return null;
31621d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang        }
31721d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang
31821d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang        Bitmap bitmap = BitmapFactory.decodeFile(mParams.deviceAdminIconFilePath);
31921d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang        if (bitmap == null) {
32021d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang            return null;
32121d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang        }
32221d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang        return new BitmapDrawable(mContext.getResources(), bitmap);
32321d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang    }
32421d7fee248eb5cc5465cc986683bfb88e71aea57Victor Chang
325ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
326c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * Start provisioning for real. In profile owner case, double check that the launcher
327c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * supports managed profiles if necessary. In device owner case, possibly create a new user
328c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * before starting provisioning.
329ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
330c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    public void continueProvisioningAfterUserConsent() {
331c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // check if encryption is required
33262d6a02ae6b1b4dd1132099dff306dd03d219c54Benjamin Franz        if (isEncryptionRequired()) {
333c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            if (mDevicePolicyManager.getStorageEncryptionStatus()
334c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    == DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED) {
335121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_set_up_device,
336121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.device_doesnt_allow_encryption_contact_admin,
337c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                        "This device does not support encryption, and "
338c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                                + DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION
339c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                                + " was not passed.");
340c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            } else {
341c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mUi.requestEncryption(mParams);
342c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // we come back to this method after returning from encryption dialog
343c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // TODO: refactor as evil - logic should be less spread out
344c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            }
345ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
346ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
347ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
348c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (isProfileOwnerProvisioning()) { // PO case
349c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            // Check whether the current launcher supports managed profiles.
350c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            if (!mUtils.currentLauncherSupportsManagedProfiles(mContext)) {
351c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mUi.showCurrentLauncherInvalid();
352c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // we come back to this method after returning from launcher dialog
353c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // TODO: refactor as evil - logic should be less spread out
354ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                return;
355ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else {
356c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // Cancel the boot reminder as provisioning has now started.
357c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mEncryptionController.cancelEncryptionReminder();
358c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                stopTimeLogger();
359c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mUi.startProvisioning(mUserManager.getUserHandle(), mParams);
360c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            }
361c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        } else { // DO case
362c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            // Cancel the boot reminder as provisioning has now started.
363c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            mEncryptionController.cancelEncryptionReminder();
364c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            if (isMeatUserCreationRequired(mParams.provisioningAction)) {
365c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // Create the primary user, and continue the provisioning in this user.
366c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // successful end of this task triggers provisioning
367c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // TODO: refactor as evil - logic should be less spread out
368c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                new CreatePrimaryUserTask().execute();
369c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            } else {
370c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                stopTimeLogger();
371c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mUi.startProvisioning(mUserManager.getUserHandle(), mParams);
372ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
373ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
374ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
375ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
376c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    /** @return False if condition preventing further provisioning */
377d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova    @VisibleForTesting
378d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova    boolean checkFactoryResetProtection(ProvisioningParams params, String callingPackage) {
379d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        if (skipFactoryResetProtectionCheck(params, callingPackage)) {
380d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            return true;
381d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        }
382c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (factoryResetProtected()) {
383121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak            mUi.showErrorAndClose(R.string.cant_set_up_device,
384121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                    R.string.device_has_reset_protection_contact_admin,
385c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    "Factory reset protection blocks provisioning.");
386c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            return false;
387349f226ff616048752c693d42fd7ae4d74fbc97dVictor Chang        }
388c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        return true;
389349f226ff616048752c693d42fd7ae4d74fbc97dVictor Chang    }
390349f226ff616048752c693d42fd7ae4d74fbc97dVictor Chang
391d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova    private boolean skipFactoryResetProtectionCheck(
392d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            ProvisioningParams params, String callingPackage) {
393d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        if (TextUtils.isEmpty(callingPackage)) {
394d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            return false;
395d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        }
396d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        String persistentDataPackageName = mContext.getResources()
397d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova                .getString(com.android.internal.R.string.config_persistentDataPackageName);
398d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        try {
399d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            // Only skip the FRP check if the caller is the package responsible for maintaining FRP
400e19d44a5abc68b4facc5980c479080e2f8d08357Lenka Trochtova            // - i.e. if this is a flow for restoring device owner after factory reset.
401d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            PackageInfo callingPackageInfo = mPackageManager.getPackageInfo(callingPackage, 0);
402d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            return callingPackageInfo != null
403d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova                    && callingPackageInfo.applicationInfo != null
404d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova                    && callingPackageInfo.applicationInfo.isSystemApp()
405d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova                    && !TextUtils.isEmpty(persistentDataPackageName)
406d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova                    && callingPackage.equals(persistentDataPackageName)
407d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova                    && params != null
408d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova                    && params.startedByTrustedSource;
409d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        } catch (PackageManager.NameNotFoundException e) {
410d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            ProvisionLogger.loge("Calling package not found.", e);
411d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova            return false;
412d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova        }
413d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova    }
414d14a45868da1277cb2fb3c28ff74473475708c30Lenka Trochtova
415c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    /** @return False if condition preventing further provisioning */
416b0e275f0511cfe10c698d6a260fcfdb194e7c810Jakub Gielzak    @VisibleForTesting protected boolean checkDevicePolicyPreconditions() {
417c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // If isSilentProvisioningForTestingDeviceOwner returns true, the component must be
418c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // current device owner, and we can safely ignore isProvisioningAllowed as we don't call
419c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // setDeviceOwner.
420c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (isSilentProvisioningForTestingDeviceOwner()) {
421c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            return true;
422ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
423349f226ff616048752c693d42fd7ae4d74fbc97dVictor Chang
424c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        int provisioningPreCondition = mDevicePolicyManager.checkProvisioningPreCondition(
425c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mParams.provisioningAction, mParams.inferDeviceAdminPackageName());
426c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        // Check whether provisioning is allowed for the current action.
427c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (provisioningPreCondition != CODE_OK) {
428c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            mProvisioningAnalyticsTracker.logProvisioningNotAllowed(mContext,
429c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    provisioningPreCondition);
430c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            showProvisioningErrorAndClose(mParams.provisioningAction, provisioningPreCondition);
431c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            return false;
432349f226ff616048752c693d42fd7ae4d74fbc97dVictor Chang        }
433c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        return true;
434c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    }
435349f226ff616048752c693d42fd7ae4d74fbc97dVictor Chang
436c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    /** @return False if condition preventing further provisioning */
43790f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang    private boolean tryParseParameters(Intent intent, ProvisioningParams params) {
438c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        try {
439c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            // Read the provisioning params from the provisioning intent
44090f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang            mParams = params == null ? mMessageParser.parse(intent) : params;
441c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        } catch (IllegalProvisioningArgumentException e) {
442121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak            mUi.showErrorAndClose(R.string.cant_set_up_device, R.string.contact_your_admin_for_help,
443121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                    e.getMessage());
444c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            return false;
445c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        }
446c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        return true;
447ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
448ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
449c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    /** @return False if condition preventing further provisioning */
45055312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang    @VisibleForTesting protected boolean verifyActionAndCaller(Intent intent,
45155312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            String callingPackage) {
45255312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        if (verifyActionAndCallerInner(intent, callingPackage)) {
453465e1458cc5d6108826ea914d1a3007b73ea748eVictor Chang            return true;
45455312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        } else {
455121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak            mUi.showErrorAndClose(R.string.cant_set_up_device, R.string.contact_your_admin_for_help,
45655312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang                    "invalid intent or calling package");
457465e1458cc5d6108826ea914d1a3007b73ea748eVictor Chang            return false;
458ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
459ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
460ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
46155312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang    private boolean verifyActionAndCallerInner(Intent intent, String callingPackage) {
46255312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        // If this is a resume after encryption or trusted intent, we verify the activity alias.
46355312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        // Otherwise, verify that the calling app is trying to set itself as Device/ProfileOwner
46455312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        if (ACTION_RESUME_PROVISIONING.equals(intent.getAction())) {
46555312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return verifyActivityAlias(intent, "PreProvisioningActivityAfterEncryption");
46655312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        } else if (ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
46755312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return verifyActivityAlias(intent, "PreProvisioningActivityViaNfc");
46855312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        } else if (ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE.equals(intent.getAction())) {
46955312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return verifyActivityAlias(intent, "PreProvisioningActivityViaTrustedApp");
47055312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        } else {
47155312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return verifyCaller(callingPackage);
47255312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        }
47355312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang    }
47455312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang
47555312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang    private boolean verifyActivityAlias(Intent intent, String activityAlias) {
47655312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        ComponentName componentName = intent.getComponent();
47755312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        if (componentName == null || componentName.getClassName() == null) {
47855312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            ProvisionLogger.loge("null class in component when verifying activity alias "
47955312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang                    + activityAlias);
48055312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return false;
48155312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        }
48255312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang
48355312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        if (!componentName.getClassName().endsWith(activityAlias)) {
48455312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            ProvisionLogger.loge("Looking for activity alias " + activityAlias + ", but got "
48555312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang                    + componentName.getClassName());
48655312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return false;
48755312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        }
48855312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang
48955312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        return true;
49055312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang    }
49155312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang
492ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
493c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * Verify that the caller is trying to set itself as owner.
49455312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang     * @return false if the caller is trying to set a different package as owner.
495ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
49655312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang    private boolean verifyCaller(@NonNull String callingPackage) {
497465e1458cc5d6108826ea914d1a3007b73ea748eVictor Chang        if (callingPackage == null) {
49855312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            ProvisionLogger.loge("Calling package is null. Was startActivityForResult used to "
49955312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang                    + "start this activity?");
50055312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return false;
501465e1458cc5d6108826ea914d1a3007b73ea748eVictor Chang        }
502465e1458cc5d6108826ea914d1a3007b73ea748eVictor Chang
503c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (!callingPackage.equals(mParams.inferDeviceAdminPackageName())) {
50455312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            ProvisionLogger.loge("Permission denied, "
505c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                    + "calling package tried to set a different package as owner. ");
50655312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang            return false;
507ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
50855312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang
50955312a63a09f7168ed9b40325b5ce088b69aaedaVictor Chang        return true;
510ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
511ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
512ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
513ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Returns whether the device needs encryption.
514ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
51562d6a02ae6b1b4dd1132099dff306dd03d219c54Benjamin Franz    private boolean isEncryptionRequired() {
51662d6a02ae6b1b4dd1132099dff306dd03d219c54Benjamin Franz        return !mParams.skipEncryption && mUtils.isEncryptionRequired();
51762d6a02ae6b1b4dd1132099dff306dd03d219c54Benjamin Franz    }
51862d6a02ae6b1b4dd1132099dff306dd03d219c54Benjamin Franz
5192ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang    private boolean isSilentProvisioningForTestingDeviceOwner() {
5202ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang        final ComponentName currentDeviceOwner =
5212ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                mDevicePolicyManager.getDeviceOwnerComponentOnCallingUser();
5222ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang        final ComponentName targetDeviceAdmin = mParams.deviceAdminComponentName;
5232ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang
524c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        switch (mParams.provisioningAction) {
5252ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang            case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE:
5262ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                return isPackageTestOnly()
5272ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                        && currentDeviceOwner != null
5282ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                        && targetDeviceAdmin != null
5292ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                        && currentDeviceOwner.equals(targetDeviceAdmin);
5302ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang            default:
5312ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                return false;
5322ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang        }
5332ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang    }
5342ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang
5352ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang    private boolean isSilentProvisioningForTestingManagedProfile() {
5362ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang        return DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE.equals(
5372ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                mParams.provisioningAction) && isPackageTestOnly();
5382ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang    }
5392ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang
5402ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang    private boolean isPackageTestOnly() {
5412ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang        return mUtils.isPackageTestOnly(mContext.getPackageManager(),
5422ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang                mParams.inferDeviceAdminPackageName(), mUserManager.getUserHandle());
5432ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang    }
5442ecfc6315b527e62bd5a303cd726a4d7009f774aVictor Chang
54562d6a02ae6b1b4dd1132099dff306dd03d219c54Benjamin Franz    /**
546a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     * Returns whether the device is frp protected during setup wizard.
547a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     */
548ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private boolean factoryResetProtected() {
549ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // If we are started during setup wizard, check for factory reset protection.
550ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // If the device is already setup successfully, do not check factory reset protection.
55148132dd835f559e3d01ee7d2198c285bf4972e35Benjamin Franz        if (mSettingsFacade.isDeviceProvisioned(mContext)) {
552ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisionLogger.logd("Device is provisioned, FRP not required.");
553ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return false;
554ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
555ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
556ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mPdbManager == null) {
557ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisionLogger.logd("Reset protection not supported.");
558ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return false;
559ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
560ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        int size = mPdbManager.getDataBlockSize();
561ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        ProvisionLogger.logd("Data block size: " + size);
562ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return size > 0;
563ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
564ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
565a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra    /**
566a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     * Returns whether meat user creation is required or not.
567a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     * @param action Intent action that started provisioning
568a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     */
569ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public boolean isMeatUserCreationRequired(String action) {
570ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mUtils.isSplitSystemUser()
571ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                && ACTION_PROVISION_MANAGED_DEVICE.equals(action)) {
572ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            List<UserInfo> users = mUserManager.getUsers();
573ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (users.size() > 1) {
574121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_set_up_device,
575121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.contact_your_admin_for_help,
576ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Cannot start Device Owner Provisioning because there are already "
577c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                                + users.size() + " users");
578ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                return false;
579ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
580ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return true;
581ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
582ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return false;
583ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
584ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
585ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
586a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra    /**
587a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     * Returns whether activity to pick wifi can be requested or not.
588a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     */
589ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private boolean canRequestWifiPick() {
590ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return mPackageManager.resolveActivity(mUtils.getWifiPickIntent(), 0) != null;
591ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
592ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
593a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra    /**
594ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Returns whether the provisioning process is a profile owner provisioning process.
595ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
596ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public boolean isProfileOwnerProvisioning() {
597c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        return mUtils.isProfileOwnerAction(mParams.provisioningAction);
598ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
599ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
600304c8097d5254d27f9d58bbdb470579183031acfVictor Chang    @Nullable
601ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public ProvisioningParams getParams() {
602ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return mParams;
603ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
604ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
605a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra    /**
6063ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra     * Notifies the time logger to stop.
607a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra     */
6083ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra    public void stopTimeLogger() {
6093ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra        mTimeLogger.stop();
610a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra    }
611a484df862718abde1fd5de2fcc682366576ed258Mahaver Chopra
61295c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra    /**
61395c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra     * Log if PreProvisioning was cancelled.
61495c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra     */
61595c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra    public void logPreProvisioningCancelled() {
61695c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra        mProvisioningAnalyticsTracker.logProvisioningCancelled(mContext,
61795c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra                CANCELLED_BEFORE_PROVISIONING);
61895c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra    }
61995c75734581a997a2e1ed005bbf7f84bc34de43cMahaver Chopra
620c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    /**
621c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * Removes a user profile. If we are in COMP case, and were blocked by having to delete a user,
622c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * resumes COMP provisioning.
623c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     */
624c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    public void removeUser(int userProfileId) {
6256f73d0286a3b39d5d0996d5ad7a1892a8ae3b220Nicolas Prevot        // There is a possibility that the DO has set the disallow remove managed profile user
6266f73d0286a3b39d5d0996d5ad7a1892a8ae3b220Nicolas Prevot        // restriction, but is initiating the provisioning. In this case, we still want to remove
6276f73d0286a3b39d5d0996d5ad7a1892a8ae3b220Nicolas Prevot        // the managed profile.
6286f73d0286a3b39d5d0996d5ad7a1892a8ae3b220Nicolas Prevot        // We know that we can remove the managed profile because we checked
6296f73d0286a3b39d5d0996d5ad7a1892a8ae3b220Nicolas Prevot        // DevicePolicyManager.checkProvisioningPreCondition
6306f73d0286a3b39d5d0996d5ad7a1892a8ae3b220Nicolas Prevot        mUserManager.removeUserEvenWhenDisallowed(userProfileId);
631c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    }
632c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak
633c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    /**
634c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * See comment in place of usage. Check if we were in silent provisioning, got blocked, and now
635c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     * can resume.
636c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak     */
637c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    public void checkResumeSilentProvisioning() {
638c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        if (mParams.skipUserConsent || isSilentProvisioningForTestingDeviceOwner()
639c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                || isSilentProvisioningForTestingManagedProfile()) {
640c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak            continueProvisioningAfterUserConsent();
641c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak        }
642c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    }
643c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak
644ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    // TODO: review the use of async task for the case where the activity might have got killed
645ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private class CreatePrimaryUserTask extends AsyncTask<Void, Void, UserInfo> {
646ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        @Override
647ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        protected UserInfo doInBackground(Void... args) {
648ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // Create the user where we're going to install the device owner.
649ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            UserInfo userInfo = mUserManager.createUser(
650ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    mContext.getString(R.string.default_first_meat_user_name),
651ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    UserInfo.FLAG_PRIMARY | UserInfo.FLAG_ADMIN);
652ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
653ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (userInfo != null) {
654ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                ProvisionLogger.logi("Created user " + userInfo.id + " to hold the device owner");
655ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
656ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return userInfo;
657ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
658ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
659ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        @Override
660ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        protected void onPostExecute(UserInfo userInfo) {
661ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (userInfo == null) {
662121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_set_up_device,
663121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.contact_your_admin_for_help,
664ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Could not create user to hold the device owner");
665ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else {
666ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mActivityManager.switchUser(userInfo.id);
6673ca9dd8858c6cce10838af405ac0257b8ceab9beMahaver Chopra                stopTimeLogger();
668c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                // TODO: refactor as evil - logic should be less spread out
669c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                mUi.startProvisioning(userInfo.id, mParams);
670ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
671ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
672ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
673ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
674c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    private void showProvisioningErrorAndClose(String action, int provisioningPreCondition) {
67592ec1bff8d03110052b836e9176184c51e5bd043Mahaver        // Try to show an error message explaining why provisioning is not allowed.
67692ec1bff8d03110052b836e9176184c51e5bd043Mahaver        switch (action) {
67792ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case ACTION_PROVISION_MANAGED_USER:
678121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_set_up_device,
679121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.contact_your_admin_for_help,
680ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Exiting managed user provisioning, setup incomplete");
68192ec1bff8d03110052b836e9176184c51e5bd043Mahaver                return;
68292ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case ACTION_PROVISION_MANAGED_PROFILE:
683c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                showManagedProfileErrorAndClose(provisioningPreCondition);
68492ec1bff8d03110052b836e9176184c51e5bd043Mahaver                return;
68592ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case ACTION_PROVISION_MANAGED_DEVICE:
68692ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE:
687c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak                showDeviceOwnerErrorAndClose(provisioningPreCondition);
68892ec1bff8d03110052b836e9176184c51e5bd043Mahaver                return;
68992ec1bff8d03110052b836e9176184c51e5bd043Mahaver        }
69092ec1bff8d03110052b836e9176184c51e5bd043Mahaver        // This should never be the case, as showProvisioningError is always called after
69192ec1bff8d03110052b836e9176184c51e5bd043Mahaver        // verifying the supported provisioning actions.
69292ec1bff8d03110052b836e9176184c51e5bd043Mahaver    }
69392ec1bff8d03110052b836e9176184c51e5bd043Mahaver
694c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    private void showManagedProfileErrorAndClose(int provisioningPreCondition) {
69592ec1bff8d03110052b836e9176184c51e5bd043Mahaver        UserInfo userInfo = mUserManager.getUserInfo(mUserManager.getUserHandle());
696d4c471e22aae4572795c67096e41367c23ef4164Victor Chang        ProvisionLogger.logw("DevicePolicyManager.checkProvisioningPreCondition returns code: "
697d4c471e22aae4572795c67096e41367c23ef4164Victor Chang                + provisioningPreCondition);
69892ec1bff8d03110052b836e9176184c51e5bd043Mahaver        switch (provisioningPreCondition) {
699d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández            case CODE_ADD_MANAGED_PROFILE_DISALLOWED:
70092ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case CODE_MANAGED_USERS_NOT_SUPPORTED:
701121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_add_work_profile,
702e29467640b23f7c34f8c02787718e5b3cf5e986dVictor Chang                        R.string.work_profile_cant_be_added_contact_admin,
703121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        "Exiting managed profile provisioning, managed profiles feature is not available");
704d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                break;
70592ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case CODE_CANNOT_ADD_MANAGED_PROFILE:
70692ec1bff8d03110052b836e9176184c51e5bd043Mahaver                if (!userInfo.canHaveProfile()) {
707121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                    mUi.showErrorAndClose(R.string.cant_add_work_profile,
708e29467640b23f7c34f8c02787718e5b3cf5e986dVictor Chang                            R.string.work_profile_cant_be_added_contact_admin,
709d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                            "Exiting managed profile provisioning, calling user cannot have managed profiles");
710d4c471e22aae4572795c67096e41367c23ef4164Victor Chang                } else if (isRemovingManagedProfileDisallowed()){
711e29467640b23f7c34f8c02787718e5b3cf5e986dVictor Chang                    mUi.showErrorAndClose(R.string.cant_replace_or_remove_work_profile,
712e29467640b23f7c34f8c02787718e5b3cf5e986dVictor Chang                            R.string.for_help_contact_admin,
713d4c471e22aae4572795c67096e41367c23ef4164Victor Chang                            "Exiting managed profile provisioning, removing managed profile is disallowed");
71492ec1bff8d03110052b836e9176184c51e5bd043Mahaver                } else {
715121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                    mUi.showErrorAndClose(R.string.cant_add_work_profile,
716e29467640b23f7c34f8c02787718e5b3cf5e986dVictor Chang                            R.string.work_profile_cant_be_added_contact_admin,
717d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                            "Exiting managed profile provisioning, cannot add more managed profiles");
71892ec1bff8d03110052b836e9176184c51e5bd043Mahaver                }
719d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                break;
72092ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER:
721121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_add_work_profile,
722121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.contact_your_admin_for_help,
723ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Exiting managed profile provisioning, a device owner exists");
724d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                break;
725d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández            default:
726d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                mUi.showErrorAndClose(R.string.cant_add_work_profile,
727d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                        R.string.contact_your_admin_for_help,
728d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                        "Managed profile provisioning not allowed for an unknown " +
729d521ceaa7cde29ee3e5e5413579ccd97d3566453Alejandro Fernández                        "reason, code: " + provisioningPreCondition);
73092ec1bff8d03110052b836e9176184c51e5bd043Mahaver        }
73192ec1bff8d03110052b836e9176184c51e5bd043Mahaver    }
73292ec1bff8d03110052b836e9176184c51e5bd043Mahaver
733d4c471e22aae4572795c67096e41367c23ef4164Victor Chang    private boolean isRemovingManagedProfileDisallowed() {
734d4c471e22aae4572795c67096e41367c23ef4164Victor Chang        return mUtils.alreadyHasManagedProfile(mContext) != -1
735d4c471e22aae4572795c67096e41367c23ef4164Victor Chang                && mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE);
736d4c471e22aae4572795c67096e41367c23ef4164Victor Chang    }
737d4c471e22aae4572795c67096e41367c23ef4164Victor Chang
738c2607104b8f3c197366780cf8252a2fdfc67096bJakub Gielzak    private void showDeviceOwnerErrorAndClose(int provisioningPreCondition) {
73992ec1bff8d03110052b836e9176184c51e5bd043Mahaver        switch (provisioningPreCondition) {
74092ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case CODE_HAS_DEVICE_OWNER:
741121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.device_already_set_up,
742121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.if_questions_contact_admin, "Device already provisioned.");
74392ec1bff8d03110052b836e9176184c51e5bd043Mahaver                return;
74492ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case CODE_NOT_SYSTEM_USER:
745121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_set_up_device,
746121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.contact_your_admin_for_help,
74792ec1bff8d03110052b836e9176184c51e5bd043Mahaver                        "Device owner can only be set up for USER_SYSTEM.");
74892ec1bff8d03110052b836e9176184c51e5bd043Mahaver                return;
74992ec1bff8d03110052b836e9176184c51e5bd043Mahaver            case CODE_NOT_SYSTEM_USER_SPLIT:
750121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                mUi.showErrorAndClose(R.string.cant_set_up_device,
751121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak                        R.string.contact_your_admin_for_help,
75292ec1bff8d03110052b836e9176184c51e5bd043Mahaver                        "System User Device owner can only be set on a split-user system.");
75392ec1bff8d03110052b836e9176184c51e5bd043Mahaver                return;
754ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
755121804ae42a986fe444757e8c1718c9667952c46Jakub Gielzak        mUi.showErrorAndClose(R.string.cant_set_up_device, R.string.contact_your_admin_for_help,
75692ec1bff8d03110052b836e9176184c51e5bd043Mahaver                "Device Owner provisioning not allowed for an unknown reason.");
757ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
758e19d44a5abc68b4facc5980c479080e2f8d08357Lenka Trochtova}
759