PreProvisioningController.java revision ea821b26fc845efa8058c883b0210432e9619f77
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
17ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzpackage com.android.managedprovisioning.uiflows;
18ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
19ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
20ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE;
21ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE;
22ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED;
23ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport static com.android.internal.util.Preconditions.checkNotNull;
24ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
25ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.annotation.NonNull;
26ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.annotation.Nullable;
27ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.app.ActivityManager;
28ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.app.admin.DevicePolicyManager;
29ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.app.KeyguardManager;
30ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.ComponentName;
31ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.Context;
32ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.Intent;
33ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.pm.ApplicationInfo;
34ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.pm.PackageManager;
35ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.content.pm.UserInfo;
36ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.os.AsyncTask;
37ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.os.UserHandle;
38ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.os.UserManager;
39ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.provider.Settings.Global;
40ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.service.persistentdata.PersistentDataBlockManager;
41ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport android.text.TextUtils;
42ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
43ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.internal.annotations.VisibleForTesting;
44ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
45ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.common.Utils;
46ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.EncryptDeviceActivity;
47ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.MessageParser;
48ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.ProvisionLogger;
49ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.ProvisioningParams;
50ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport com.android.managedprovisioning.R;
51ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
52ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzimport java.util.List;
53ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
54ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franzpublic class PreProvisioningController {
55ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final Context mContext;
56ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final Ui mUi;
57ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final MessageParser mMessageParser;
58ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final Utils mUtils;
59ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
60ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    // used system services
61ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final DevicePolicyManager mDevicePolicyManager;
62ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final UserManager mUserManager;
63ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final PackageManager mPackageManager;
64ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final ActivityManager mActivityManager;
65ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final KeyguardManager mKeyguardManager;
66ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private final PersistentDataBlockManager mPdbManager;
67ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
68ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private ProvisioningParams mParams;
69ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private boolean mIsProfileOwnerProvisioning;
70ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
71ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public PreProvisioningController(
72ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Context context,
73ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Ui ui) {
74ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        this(context, ui, new MessageParser(), new Utils());
75ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
76ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
77ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    @VisibleForTesting
78ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    PreProvisioningController(
79ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Context context,
80ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Ui ui,
81ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull MessageParser parser,
82ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            @NonNull Utils utils) {
83ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mContext = checkNotNull(context, "Context must not be null");
84ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUi = checkNotNull(ui, "Ui must not be null");
85ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mMessageParser = checkNotNull(parser, "MessageParser must not be null");
86ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUtils = checkNotNull(utils, "Utils must not be null");
87ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
88ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
89ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                Context.DEVICE_POLICY_SERVICE);
90ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
91ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mPackageManager = mContext.getPackageManager();
92ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
93ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
94ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mPdbManager = (PersistentDataBlockManager) mContext.getSystemService(
95ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                Context.PERSISTENT_DATA_BLOCK_SERVICE);
96ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
97ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
98ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    interface Ui {
99ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
100ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Show an error message and cancel provisioning.
101ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
102ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param resId resource id used to form the user facing error message
103ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param errorMessage an error message that gets logged for debugging
104ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
105ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void showErrorAndClose(int resId, String errorMessage);
106ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
107ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
108ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Request the user to encrypt the device.
109ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
110ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param params the {@link ProvisioningParams} object related to the ongoing provisioning
111ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
112ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void requestEncryption(ProvisioningParams params);
113ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
114ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
115ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Request the user to choose a wifi network.
116ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
117ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void requestWifiPick();
118ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
119ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
120ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Initialize the pre provisioning UI with the mdm info and the relevant strings.
121ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
122ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param headerRes resource id for the header text
123ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param titleRes resource id for the title text
124ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param consentRes resource id of the consent text
125ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param mdmInfoRes resource id for the mdm info text
126ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param params the {@link ProvisioningParams} object related to the ongoing provisioning
127ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
128ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void initiateUi(int headerRes, int titleRes, int consentRes, int mdmInfoRes,
129ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                ProvisioningParams params);
130ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
131ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
132ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Start device owner provisioning.
133ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
134ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param userId the id of the user we want to start provisioning on
135ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param params the {@link ProvisioningParams} object related to the ongoing provisioning
136ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
137ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void startDeviceOwnerProvisioning(int userId, ProvisioningParams params);
138ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
139ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
140ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Start profile owner provisioning.
141ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
142ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param params the {@link ProvisioningParams} object related to the ongoing provisioning
143ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
144ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void startProfileOwnerProvisioning(ProvisioningParams params);
145ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
146ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
147ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Show a user consent dialog.
148ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
149ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param params the {@link ProvisioningParams} object related to the ongoing provisioning
150ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param isProfileOwnerProvisioning whether we're provisioning a profile owner
151ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
152ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void showUserConsentDialog(ProvisioningParams params, boolean isProfileOwnerProvisioning);
153ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
154ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
155ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Show a dialog to delete an existing managed profile.
156ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
157ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param mdmPackageName the {@link ComponentName} of the existing profile's profile owner
158ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param domainName domain name of the organization which owns the managed profile
159ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         *
160ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * @param userId the user id of the existing profile
161ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
162ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void showDeleteManagedProfileDialog(ComponentName mdmPackageName, String domainName,
163ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                int userId);
164ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
165ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        /**
166ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * Show an error dialog indicating that the current launcher does not support managed
167ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         * profiles and ask the user to choose a different one.
168ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz         */
169ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        void showCurrentLauncherInvalid();
170ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
171ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
172ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public void initiateProvisioning(Intent intent, String callingPackage) {
173ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // Check factory reset protection as the first thing
174ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (factoryResetProtected()) {
175ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.device_owner_error_frp,
176ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    "Factory reset protection blocks provisioning.");
177ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
178ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
179ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
180ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        String action = null;
181ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        try {
182ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            action = mUtils.mapIntentToDpmAction(intent);
183ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisionLogger.logi(
184ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    "Starting provisioning for target action: " + action);
185ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } catch (IllegalProvisioningArgumentException e) {
186ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // should never happen
187ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // TODO: show generic error
188ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.device_owner_error_general, e.getMessage());
189ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
190ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
191ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
192ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mIsProfileOwnerProvisioning = mUtils.isProfileOwnerAction(action);
193ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // Check whether provisioning is allowed for the current action
194ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (!mDevicePolicyManager.isProvisioningAllowed(action)) {
195ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            showProvisioningError(action);
196ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
197ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
198ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
199ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // Read the provisioning params from the provisioning intent
200ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        try {
201ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            readParamsAndMaybeVerifyCaller(intent, callingPackage);
202ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } catch (IllegalProvisioningArgumentException e) {
203ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // TODO: make this a generic error message
204ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.device_owner_error_general, e.getMessage());
205ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
206ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
207ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
208ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // Initiate the corresponding provisioning mode
209ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mIsProfileOwnerProvisioning) {
210ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            initiateProfileOwnerProvisioning(intent);
211ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
212ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            initiateDeviceOwnerProvisioning(intent);
213ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
214ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
215ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
216ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private void readParamsAndMaybeVerifyCaller(Intent intent, String callingPackage)
217ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            throws IllegalProvisioningArgumentException {
218ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        boolean isSelfOriginated = (callingPackage != null)
219ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                && (callingPackage.equals(mContext.getPackageName()));
220ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mParams = parseIntent(intent, isSelfOriginated);
221ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (!isSelfOriginated && !mParams.startedByTrustedSource) {
222ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            verifyCaller(callingPackage);
223ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
224ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
225ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
226ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
227ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Read the ProvisioningParams from the intent.
228ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     *
229ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * @throw IllegalProvisioningArgumentException if the parameters are not valid.
230ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
231ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    // TODO: Move this logic into message parser
232ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private ProvisioningParams parseIntent(Intent intent, boolean isSelfOriginated)
233ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            throws IllegalProvisioningArgumentException {
234ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (intent.getAction().equals(ACTION_NDEF_DISCOVERED)) {
235ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return mMessageParser.parseNfcIntent(intent);
236ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else if (intent.getAction().equals(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE)) {
237ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // We trusted most of the extras from this intent because the caller is a privileged
238ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // app. But we don't support internal only APIs for this intent.
239ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return mMessageParser.parseNonNfcIntent(intent, mContext, false);
240ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else if (intent.getAction().equals(ACTION_PROVISION_MANAGED_DEVICE) ||
241ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                intent.getAction().equals(ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE)) {
242ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisioningParams params;
243ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (isSelfOriginated) {
244ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                // If we're trusted, we support all the extras.
245ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                params = mMessageParser.parseNonNfcIntent(intent, mContext, true);
246ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else {
247ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                // If we were started by another app, we don't support many extras, so use the
248ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                // minimalist version.
249ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                params = mMessageParser.parseMinimalistNonNfcIntent(intent, mContext, false);
250ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
251ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return params;
252ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else { // profile owner provisioning
253ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisioningParams params = mMessageParser.parseNonNfcIntent(intent, mContext,
254ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    isSelfOriginated);
255ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            params.deviceAdminComponentName = mUtils.findDeviceAdmin(
256ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    params.deviceAdminPackageName, params.deviceAdminComponentName, mContext);
257ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            params.deviceAdminPackageName = params.deviceAdminComponentName.getPackageName();
258ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return params;
259ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
260ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
261ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
262ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
263ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Verify that the caller is trying to set itself as owner.
264ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     *
265ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * @throws IllegalProvisioningArgumentException if the caller is trying to set a different
266ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * package as owner.
267ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
268ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private void verifyCaller(@NonNull String callingPackage)
269ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            throws IllegalProvisioningArgumentException {
270ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        checkNotNull(callingPackage,
271ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                "Calling package is null. Was startActivityForResult used to start this activity?");
272ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (!callingPackage.equals(mParams.inferDeviceAdminPackageName())) {
273ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            throw new IllegalProvisioningArgumentException("Permission denied, "
274ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    + "calling package tried to set a different package as owner. ");
275ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
276ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
277ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
278ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private void initiateDeviceOwnerProvisioning(Intent intent) {
279ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUi.initiateUi(
280ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.setup_work_device,
281ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.setup_device_start_setup,
282ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.company_controls_device,
283ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.the_following_is_your_mdm_for_device,
284ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mParams);
285ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
286ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // Ask to encrypt the device before proceeding
287ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (isEncryptionRequired(mParams.skipEncryption)) {
288ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.requestEncryption(mParams);
289ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return;
290ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
291ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
292ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // Have the user pick a wifi network if necessary.
293ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // It is not possible to ask the user to pick a wifi network if
294ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // the screen is locked.
295ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // TODO: remove this check once we know the screen will not be locked.
296ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mKeyguardManager.inKeyguardRestrictedInputMode()) {
297ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisionLogger.logi("Cannot pick wifi because the screen is locked.");
298ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // Have the user pick a wifi network if necessary.
299ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else if (!mUtils.isConnectedToNetwork(mContext)
300ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                && TextUtils.isEmpty(mParams.wifiInfo.ssid)) {
301ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (canRequestWifiPick()) {
302ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.requestWifiPick();
303ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                return;
304ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else {
305ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                ProvisionLogger.logi(
306ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Cannot pick wifi because there is no handler to the intent");
307ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
308ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
309ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        askForConsentOrStartDeviceOwnerProvisioning();
310ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
311ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
312ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private void initiateProfileOwnerProvisioning(Intent intent) {
313ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        mUi.initiateUi(
314ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.setup_work_profile,
315ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.setup_profile_start_setup,
316ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.company_controls_workspace,
317ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                R.string.the_following_is_your_mdm,
318ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mParams);
319ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
320ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // If there is already a managed profile, setup the profile deletion dialog.
321ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        int existingManagedProfileUserId = mUtils.alreadyHasManagedProfile(mContext);
322ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (existingManagedProfileUserId != -1) {
323ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ComponentName mdmPackageName = mDevicePolicyManager
324ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    .getProfileOwnerAsUser(existingManagedProfileUserId);
325ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            String domainName = mDevicePolicyManager
326ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    .getProfileOwnerNameAsUser(existingManagedProfileUserId);
327ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showDeleteManagedProfileDialog(mdmPackageName, domainName,
328ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    existingManagedProfileUserId);
329ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
330ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
331ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
332ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
333ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Start provisioning for real. In profile owner case, double check that the launcher
334ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * supports managed profiles if necessary. In device owner case, possibly create a new user
335ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * before starting provisioning.
336ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
337ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public void continueProvisioningAfterUserConsent() {
338ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (isProfileOwnerProvisioning()) {
339ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            checkLauncherAndStartProfileOwnerProvisioning();
340ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
341ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            maybeCreateUserAndStartDeviceOwnerProvisioning();
342ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
343ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
344ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
345ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
346ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Invoked when the user continues provisioning by pressing the next button.
347ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     *
348ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * <p>If device hasn't been encrypted yet, invoke the encryption flow. Otherwise, show a user
349ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * consent before starting provisioning.
350ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
351ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public void afterNavigateNext() {
352ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (isEncryptionRequired(mParams.skipEncryption)) {
353ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // only allow skipping the encryption flow for device owner provisioning
354ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisionLogger.logd("Encryption required");
355ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.requestEncryption(mParams);
356ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
357ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // Notify the user once more that the admin will have full control over the profile,
358ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // then start provisioning.
359ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showUserConsentDialog(mParams, mIsProfileOwnerProvisioning);
360ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
361ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
362ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
363ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
364ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Returns whether the device needs encryption.
365ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     *
366ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * @param skip indicating whether the parameter to skip encryption was given.
367ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
368ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private boolean isEncryptionRequired(boolean skip) {
369ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return !skip && mUtils.isEncryptionRequired();
370ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
371ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
372ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private void checkLauncherAndStartProfileOwnerProvisioning() {
373ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // Check whether the current launcher supports managed profiles.
374ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (!mUtils.currentLauncherSupportsManagedProfiles(mContext)) {
375ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showCurrentLauncherInvalid();
376ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
377ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.startProfileOwnerProvisioning(mParams);
378ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
379ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
380ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
381ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public void askForConsentOrStartDeviceOwnerProvisioning() {
382ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // If we are started by Nfc and the device supports FRP, we need to ask for user consent
383ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // since FRP will not be activated at the end of the flow.
384ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mParams.startedByTrustedSource) {
385ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (mUtils.isFrpSupported(mContext)) {
386ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showUserConsentDialog(mParams, false);
387ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else {
388ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                maybeCreateUserAndStartDeviceOwnerProvisioning();
389ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
390ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
391ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // In other provisioning modes we wait for the user to press next.
392ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
393ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
394ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private void maybeCreateUserAndStartDeviceOwnerProvisioning() {
395ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (isMeatUserCreationRequired(mParams.provisioningAction)) {
396ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // Create the primary user, and continue the provisioning in this user.
397ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            new CreatePrimaryUserTask().execute();
398ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
399ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.startDeviceOwnerProvisioning(mUserManager.getUserHandle(), mParams);
400ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
401ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
402ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
403ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private boolean factoryResetProtected() {
404ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // If we are started during setup wizard, check for factory reset protection.
405ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        // If the device is already setup successfully, do not check factory reset protection.
406ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mUtils.isDeviceProvisioned(mContext)) {
407ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisionLogger.logd("Device is provisioned, FRP not required.");
408ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return false;
409ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
410ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
411ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mPdbManager == null) {
412ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            ProvisionLogger.logd("Reset protection not supported.");
413ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return false;
414ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
415ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        int size = mPdbManager.getDataBlockSize();
416ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        ProvisionLogger.logd("Data block size: " + size);
417ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return size > 0;
418ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
419ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
420ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public boolean isMeatUserCreationRequired(String action) {
421ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mUtils.isSplitSystemUser()
422ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                && ACTION_PROVISION_MANAGED_DEVICE.equals(action)) {
423ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            List<UserInfo> users = mUserManager.getUsers();
424ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (users.size() > 1) {
425ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showErrorAndClose(R.string.device_owner_error_general,
426ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Cannot start Device Owner Provisioning because there are already "
427ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        + users.size() + " users");
428ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                return false;
429ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
430ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return true;
431ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
432ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return false;
433ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
434ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
435ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
436ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private boolean canRequestWifiPick() {
437ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return mPackageManager.resolveActivity(mUtils.getWifiPickIntent(), 0) != null;
438ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
439ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
440ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private boolean systemHasManagedProfileFeature() {
441ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
442ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
443ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
444ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    /**
445ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     * Returns whether the provisioning process is a profile owner provisioning process.
446ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz     */
447ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public boolean isProfileOwnerProvisioning() {
448ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return mIsProfileOwnerProvisioning;
449ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
450ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
451ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    @NonNull
452ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    public ProvisioningParams getParams() {
453ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (mParams == null) {
454ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            throw new IllegalStateException("ProvisioningParams are null");
455ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
456ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        return mParams;
457ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
458ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
459ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    // TODO: review the use of async task for the case where the activity might have got killed
460ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private class CreatePrimaryUserTask extends AsyncTask<Void, Void, UserInfo> {
461ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        @Override
462ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        protected UserInfo doInBackground(Void... args) {
463ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // Create the user where we're going to install the device owner.
464ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            UserInfo userInfo = mUserManager.createUser(
465ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    mContext.getString(R.string.default_first_meat_user_name),
466ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    UserInfo.FLAG_PRIMARY | UserInfo.FLAG_ADMIN);
467ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
468ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (userInfo != null) {
469ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                ProvisionLogger.logi("Created user " + userInfo.id + " to hold the device owner");
470ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
471ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            return userInfo;
472ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
473ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
474ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        @Override
475ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        protected void onPostExecute(UserInfo userInfo) {
476ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (userInfo == null) {
477ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showErrorAndClose(R.string.device_owner_error_general,
478ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Could not create user to hold the device owner");
479ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else {
480ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mActivityManager.switchUser(userInfo.id);
481ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.startDeviceOwnerProvisioning(userInfo.id, mParams);
482ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
483ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
484ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
485ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz
486ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    private void showProvisioningError(String action) {
487ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        UserInfo userInfo = mUserManager.getUserInfo(mUserManager.getUserHandle());
488ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        if (DevicePolicyManager.ACTION_PROVISION_MANAGED_USER.equals(action)) {
489ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.user_setup_incomplete,
490ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Exiting managed user provisioning, setup incomplete");
491ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE.equals(action)) {
492ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // Try to show an error message explaining why provisioning is not allowed.
493ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            if (!systemHasManagedProfileFeature()) {
494ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showErrorAndClose(R.string.managed_provisioning_not_supported,
495ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Exiting managed profile provisioning, "
496ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        + "managed profiles feature is not available");
497ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else if (!userInfo.canHaveProfile()) {
498ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showErrorAndClose(R.string.user_cannot_have_work_profile,
499ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Exiting managed profile provisioning, calling user cannot have managed"
500ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        + "profiles.");
501ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else if (mUtils.isDeviceManaged(mContext)) {
502ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                // The actual check in isProvisioningAllowed() is more than just "is there DO?",
503ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                // but for error message showing purpose, isDeviceManaged() will do.
504ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showErrorAndClose(R.string.device_owner_exists,
505ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Exiting managed profile provisioning, a device owner exists");
506ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else if (!mUserManager.canAddMoreManagedProfiles(UserHandle.myUserId(),
507ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    true /* after removing one eventual existing managed profile */)) {
508ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showErrorAndClose(R.string.maximum_user_limit_reached,
509ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        "Exiting managed profile provisioning, cannot add more managed profiles.");
510ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            } else {
511ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                mUi.showErrorAndClose(R.string.managed_provisioning_error_text, "Managed profile"
512ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                        + " provisioning not allowed for an unknown reason.");
513ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            }
514ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else if (mUtils.isDeviceProvisioned(mContext)) {
515ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.device_owner_error_already_provisioned,
516ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    "Device already provisioned.");
517ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else if (!mUtils.isCurrentUserSystem()) {
518ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.device_owner_error_general,
519ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    "Device owner can only be set up for USER_SYSTEM.");
520ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else if (action.equals(ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE) &&
521ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                !UserManager.isSplitSystemUser()) {
522ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.device_owner_error_general,
523ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    "System User Device owner can only be set on a split-user system.");
524ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        } else {
525ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            // TODO: show generic error
526ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz            mUi.showErrorAndClose(R.string.device_owner_error_general,
527ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz                    "Device Owner provisioning not allowed for an unknown reason.");
528ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz        }
529ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz    }
530ea821b26fc845efa8058c883b0210432e9619f77Benjamin Franz}
531