1e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina/*
2e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * Copyright 2014, The Android Open Source Project
3e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina *
4e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * Licensed under the Apache License, Version 2.0 (the "License");
5e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * you may not use this file except in compliance with the License.
6e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * You may obtain a copy of the License at
7e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina *
8e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina *      http://www.apache.org/licenses/LICENSE-2.0
9e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina *
10e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * Unless required by applicable law or agreed to in writing, software
11e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * distributed under the License is distributed on an "AS IS" BASIS,
12e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * See the License for the specific language governing permissions and
14e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina * limitations under the License.
15e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina */
16e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina
178119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummelpackage com.android.managedprovisioning;
188119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummel
19f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnseimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
2090bf3144e89abfff8af1d3c35afe2a59bb680397Jessica Hummelimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
214af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Leeimport static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME;
224af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Leeimport static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME_TARGET;
234af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Leeimport static com.android.managedprovisioning.EncryptDeviceActivity.TARGET_PROFILE_OWNER;
24935e3239fc0d4648536c5392d0917297c3ce5656Jessica Hummel
258119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummelimport android.app.Activity;
2622265143c1264eab25977402777f81cb027229ebJessica Hummelimport android.app.AlertDialog;
2714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.BroadcastReceiver;
284af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Leeimport android.content.ComponentName;
29b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummelimport android.content.Context;
3022265143c1264eab25977402777f81cb027229ebJessica Hummelimport android.content.DialogInterface;
31b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummelimport android.content.Intent;
323581ff92276be14f8b4b8c3bcc341b8f9c0b7b36Nicolas Prevotimport android.content.IntentFilter;
330ea830dd25796752ba54031923aed85915cd1e77Jessica Hummelimport android.content.pm.ApplicationInfo;
34b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummelimport android.content.pm.PackageManager;
352d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnseimport android.content.pm.ResolveInfo;
36e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghinaimport android.content.pm.PackageManager.NameNotFoundException;
37c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummelimport android.content.pm.UserInfo;
380ea830dd25796752ba54031923aed85915cd1e77Jessica Hummelimport android.graphics.drawable.Drawable;
392d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnseimport android.os.Build;
408119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummelimport android.os.Bundle;
41f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnseimport android.os.PersistableBundle;
42928febf764007c038e9a0eaeca5e0f2ce7604d3bEsteban Talaveraimport android.os.Process;
438bf486ee7dd8d9d076c0515f970dd069e4230c6cAmith Yamasaniimport android.os.SystemProperties;
44928febf764007c038e9a0eaeca5e0f2ce7604d3bEsteban Talaveraimport android.os.UserHandle;
45c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummelimport android.os.UserManager;
4681fe104ecfc98f1fb4356891acfe696e7445acb8Jessica Hummelimport android.support.v4.content.LocalBroadcastManager;
47e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghinaimport android.text.TextUtils;
48a08b23e2f5b35dcfee5d9fadb1e3d17e0335e882Jessica Hummelimport android.view.LayoutInflater;
49a08b23e2f5b35dcfee5d9fadb1e3d17e0335e882Jessica Hummelimport android.view.View;
500ea830dd25796752ba54031923aed85915cd1e77Jessica Hummelimport android.widget.ImageView;
518ce0c515bf9177ef4c6d15845ae2d1636c59dc2aSander Alewijnseimport android.widget.TextView;
520ea830dd25796752ba54031923aed85915cd1e77Jessica Hummelimport android.widget.Button;
533581ff92276be14f8b4b8c3bcc341b8f9c0b7b36Nicolas Prevot
54c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummelimport java.util.List;
558119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummel
56c6d71b86baf721d5de568248d1f538cc7d4adcd0Jason Monk/**
5714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * Managed provisioning sets up a separate profile on a device whose primary user is already set up.
5814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * The typical example is setting up a corporate profile that is controlled by their employer on a
5914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * users personal device to keep personal and work data separate.
6014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel *
6114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * The activity handles the input validation and UI for managed profile provisioning.
6214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * and starts the {@link ManagedProvisioningService}, which runs through the setup steps in an
6314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * async task.
64c6d71b86baf721d5de568248d1f538cc7d4adcd0Jason Monk */
65c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel// TODO: Proper error handling to report back to the user and potentially the mdm.
668119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummelpublic class ManagedProvisioningActivity extends Activity {
678119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummel
6801fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel    private static final String MANAGE_USERS_PERMISSION = "android.permission.MANAGE_USERS";
6901fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel
702d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    // Note: must match the constant defined in HomeSettings
712d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    private static final String EXTRA_SUPPORT_MANAGED_PROFILES = "support_managed_profiles";
722d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
734af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee    protected static final String EXTRA_USER_HAS_CONSENTED_PROVISIONING =
742e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel            "com.android.managedprovisioning.EXTRA_USER_HAS_CONSENTED_PROVISIONING";
752e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel
764af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee    // Aliases to start managed provisioning with and without MANAGE_USERS permission
774af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee    protected static final ComponentName ALIAS_CHECK_CALLER =
784af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            new ComponentName("com.android.managedprovisioning",
794af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                    "com.android.managedprovisioning.ManagedProvisioningActivity");
804af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee
814af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee    protected static final ComponentName ALIAS_NO_CHECK_CALLER =
824af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            new ComponentName("com.android.managedprovisioning",
834af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                    "com.android.managedprovisioning.ManagedProvisioningActivityNoCallerCheck");
844af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee
8514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    protected static final int ENCRYPT_DEVICE_REQUEST_CODE = 2;
862d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    protected static final int CHANGE_LAUNCHER_REQUEST_CODE = 1;
87935e3239fc0d4648536c5392d0917297c3ce5656Jessica Hummel
88c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel    private String mMdmPackageName;
8914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private BroadcastReceiver mServiceMessageReceiver;
90b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummel
9122265143c1264eab25977402777f81cb027229ebJessica Hummel    private View mContentView;
9214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private View mMainTextView;
9314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private View mProgressView;
94b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummel
958119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummel    @Override
96c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel    protected void onCreate(Bundle savedInstanceState) {
978119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummel        super.onCreate(savedInstanceState);
98b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummel
99c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel        ProvisionLogger.logd("Managed provisioning activity ONCREATE");
1007b5e9bac63172d03b0d8b7fff88c97c20842b67fJessica Hummel
1012d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        final LayoutInflater inflater = getLayoutInflater();
1022d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        mContentView = inflater.inflate(R.layout.user_consent, null);
1032d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        mMainTextView = mContentView.findViewById(R.id.main_text_container);
1042d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        mProgressView = mContentView.findViewById(R.id.progress_container);
1052d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        setContentView(mContentView);
1062d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
1072d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        // Check whether system has the required managed profile feature.
1082d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        if (!systemHasManagedProfileFeature()) {
10995a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel            showErrorAndClose(R.string.managed_provisioning_not_supported,
11095a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel                    "Exiting managed provisioning, managed profiles feature is not available");
1117f8c6e7c8978419718274c665638f4239d34eaf6Adam Connors            return;
1127f8c6e7c8978419718274c665638f4239d34eaf6Adam Connors        }
113928febf764007c038e9a0eaeca5e0f2ce7604d3bEsteban Talavera        if (Process.myUserHandle().getIdentifier() != UserHandle.USER_OWNER) {
114928febf764007c038e9a0eaeca5e0f2ce7604d3bEsteban Talavera            showErrorAndClose(R.string.user_is_not_owner,
115928febf764007c038e9a0eaeca5e0f2ce7604d3bEsteban Talavera                    "Exiting managed provisioning, calling user is not owner.");
116928febf764007c038e9a0eaeca5e0f2ce7604d3bEsteban Talavera            return;
117928febf764007c038e9a0eaeca5e0f2ce7604d3bEsteban Talavera        }
1187f8c6e7c8978419718274c665638f4239d34eaf6Adam Connors
11914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        // Setup broadcast receiver for feedback from service.
12014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        mServiceMessageReceiver = new ServiceMessageReceiver();
12114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        IntentFilter filter = new IntentFilter();
12214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        filter.addAction(ManagedProvisioningService.ACTION_PROVISIONING_SUCCESS);
12314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        filter.addAction(ManagedProvisioningService.ACTION_PROVISIONING_ERROR);
12481fe104ecfc98f1fb4356891acfe696e7445acb8Jessica Hummel        LocalBroadcastManager.getInstance(this).registerReceiver(mServiceMessageReceiver, filter);
12514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
12695a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel        // Initialize member variables from the intent, stop if the intent wasn't valid.
12795a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel        try {
12895a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel            initialize(getIntent());
12995a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel        } catch (ManagedProvisioningFailedException e) {
13095a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel            showErrorAndClose(R.string.managed_provisioning_error_text, e.getMessage());
13195a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel            return;
132e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina        }
133b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummel
13422265143c1264eab25977402777f81cb027229ebJessica Hummel        setMdmIcon(mMdmPackageName, mContentView);
13501fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel
1364af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee        // If the caller started us via ALIAS_NO_CHECK_CALLER then they must have permission to
1374af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee        // MANAGE_USERS since it is a restricted intent. Otherwise, check the calling package.
1384af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee        boolean hasManageUsersPermission = (getComponentName().equals(ALIAS_NO_CHECK_CALLER));
1394af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee        if (!hasManageUsersPermission) {
1404af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            // Calling package has to equal the requested device admin package or has to be system.
1414af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            String callingPackage = getCallingPackage();
1424af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            if (callingPackage == null) {
1434af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                showErrorAndClose(R.string.managed_provisioning_error_text,
1444af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                        "Calling package is null. " +
1454af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                        "Was startActivityForResult used to start this activity?");
1464af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                return;
1474af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            }
1484af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            if (!callingPackage.equals(mMdmPackageName)
1494af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                    && !packageHasManageUsersPermission(callingPackage)) {
1504af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                showErrorAndClose(R.string.managed_provisioning_error_text, "Permission denied, "
1514af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                        + "calling package tried to set a different package as profile owner. "
1524af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                        + "The system MANAGE_USERS permission is required.");
1534af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                return;
1544af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            }
15593bc0c0ea19461de6ff6843c91ef7a2d3cf2f0d0Sander Alewijnse        }
15693bc0c0ea19461de6ff6843c91ef7a2d3cf2f0d0Sander Alewijnse
15722265143c1264eab25977402777f81cb027229ebJessica Hummel        // If there is already a managed profile, allow the user to cancel or delete it.
15822265143c1264eab25977402777f81cb027229ebJessica Hummel        int existingManagedProfileUserId = alreadyHasManagedProfile();
15922265143c1264eab25977402777f81cb027229ebJessica Hummel        if (existingManagedProfileUserId != -1) {
16022265143c1264eab25977402777f81cb027229ebJessica Hummel            showManagedProfileExistsDialog(existingManagedProfileUserId);
16122265143c1264eab25977402777f81cb027229ebJessica Hummel        } else {
16222265143c1264eab25977402777f81cb027229ebJessica Hummel            showStartProvisioningScreen();
16322265143c1264eab25977402777f81cb027229ebJessica Hummel        }
16422265143c1264eab25977402777f81cb027229ebJessica Hummel    }
16522265143c1264eab25977402777f81cb027229ebJessica Hummel
16622265143c1264eab25977402777f81cb027229ebJessica Hummel    private void showStartProvisioningScreen() {
1675c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel        Button positiveButton = (Button) mContentView.findViewById(R.id.positive_button);
1685c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel        positiveButton.setOnClickListener(new View.OnClickListener() {
1695c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel            @Override
1705c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel            public void onClick(View v) {
1715c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel                checkEncryptedAndStartProvisioningService();
1725c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel            }
1735c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel        });
17401fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel    }
17501fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel
17693bc0c0ea19461de6ff6843c91ef7a2d3cf2f0d0Sander Alewijnse    private boolean packageHasManageUsersPermission(String pkg) {
17793bc0c0ea19461de6ff6843c91ef7a2d3cf2f0d0Sander Alewijnse        int packagePermission = this.getPackageManager()
17893bc0c0ea19461de6ff6843c91ef7a2d3cf2f0d0Sander Alewijnse                .checkPermission(MANAGE_USERS_PERMISSION, pkg);
17993bc0c0ea19461de6ff6843c91ef7a2d3cf2f0d0Sander Alewijnse        if (packagePermission == PackageManager.PERMISSION_GRANTED) {
18001fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel            return true;
18101fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel        } else {
18201fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel            return false;
1830ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel        }
1840ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel    }
1850ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel
1862d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    private boolean systemHasManagedProfileFeature() {
1872d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        PackageManager pm = getPackageManager();
188afa8cd8dba608d0b0c42adb6e8ee4c30b414069eAmith Yamasani        return pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
1892d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    }
1902d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
1912d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    private boolean currentLauncherSupportsManagedProfiles() {
1922d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        Intent intent = new Intent(Intent.ACTION_MAIN);
1932d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        intent.addCategory(Intent.CATEGORY_HOME);
1942d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
1952d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        PackageManager pm = getPackageManager();
1962d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        ResolveInfo launcherResolveInfo
1972d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
1982d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        try {
1992d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse            ApplicationInfo launcherAppInfo = getPackageManager().getApplicationInfo(
2002d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                    launcherResolveInfo.activityInfo.packageName, 0 /* default flags */);
2012d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse            return versionNumberAtLeastL(launcherAppInfo.targetSdkVersion);
2022d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        } catch (PackageManager.NameNotFoundException e) {
2032d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse            return false;
2042d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        }
2052d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    }
2062d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
2072d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    private boolean versionNumberAtLeastL(int versionNumber) {
2081d065428ecfd8fd8f73f37625713b2a8522b0867Dianne Hackborn        return versionNumber >= Build.VERSION_CODES.LOLLIPOP;
2092d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    }
2102d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
21114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    class ServiceMessageReceiver extends BroadcastReceiver {
21214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        @Override
21314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        public void onReceive(Context context, Intent intent) {
21414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            String action = intent.getAction();
21514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            if (action.equals(ManagedProvisioningService.ACTION_PROVISIONING_SUCCESS)) {
21615b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                ProvisionLogger.logd("Successfully provisioned."
21715b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                        + "Finishing ManagedProvisioningActivity");
21801fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel                ManagedProvisioningActivity.this.setResult(Activity.RESULT_OK);
21901fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel                ManagedProvisioningActivity.this.finish();
22014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                return;
22114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            } else if (action.equals(ManagedProvisioningService.ACTION_PROVISIONING_ERROR)) {
22214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                String errorLogMessage = intent.getStringExtra(
22314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                        ManagedProvisioningService.EXTRA_LOG_MESSAGE_KEY);
22414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                ProvisionLogger.logd("Error reported: " + errorLogMessage);
22514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                showErrorAndClose(R.string.managed_provisioning_error_text, errorLogMessage);
22614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                return;
22714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            }
22814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        }
22914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
23014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
2310ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel    private void setMdmIcon(String packageName, View contentView) {
2320ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel        if (packageName != null) {
2330ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel            PackageManager pm = getPackageManager();
2340ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel            try {
2350ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                ApplicationInfo ai = pm.getApplicationInfo(packageName, /* default flags */ 0);
2360ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                if (ai != null) {
2370ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                    Drawable packageIcon = pm.getApplicationIcon(packageName);
2380ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                    ImageView imageView = (ImageView) contentView.findViewById(R.id.mdm_icon_view);
2390ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                    imageView.setImageDrawable(packageIcon);
2400ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel
2410ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                    String appLabel = pm.getApplicationLabel(ai).toString();
2420ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                    TextView deviceManagerName = (TextView) contentView
2430ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                            .findViewById(R.id.device_manager_name);
2440ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                    deviceManagerName.setText(appLabel);
2450ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                }
2460ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel            } catch (PackageManager.NameNotFoundException e) {
2470ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                // Package does not exist, ignore. Should never happen.
2480ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel                ProvisionLogger.loge("Package does not exist. Should never happen.");
2490ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel            }
250b0ad5b563efa27b471f2fbbe18f23a94bfabea06Nicolas Prevot        }
2518119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummel    }
252b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummel
25314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    /**
25414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * Checks if all required provisioning parameters are provided.
25588d5d0ec233f6039b0e65ea66a73ba882a365e28Sander Alewijnse     * Does not check for extras that are optional such as wifi ssid.
256f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse     * Also checks whether type of admin extras bundle (if present) is PersistableBundle.
25714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     *
25814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * @param intent The intent that started provisioning
25914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     */
26014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void initialize(Intent intent) throws ManagedProvisioningFailedException {
261f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        // Check if the admin extras bundle is of the right type.
262f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        try {
263f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse            PersistableBundle bundle = (PersistableBundle) getIntent().getParcelableExtra(
264f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                    EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);
265f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        } catch (ClassCastException e) {
266f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse            throw new ManagedProvisioningFailedException("Extra "
267f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                    + EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
268f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                    + " must be of type PersistableBundle.", e);
269f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        }
27014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
27114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        // Validate package name and check if the package is installed
272ff364bd8dafb6bb72a8acc3672edd884625771b5Jessica Hummel        mMdmPackageName = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
27395a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel        if (TextUtils.isEmpty(mMdmPackageName)) {
27495a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel            throw new ManagedProvisioningFailedException("Missing intent extra: "
27590bf3144e89abfff8af1d3c35afe2a59bb680397Jessica Hummel                    + EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
27690bf3144e89abfff8af1d3c35afe2a59bb680397Jessica Hummel        } else {
27790bf3144e89abfff8af1d3c35afe2a59bb680397Jessica Hummel            try {
27895a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel                this.getPackageManager().getPackageInfo(mMdmPackageName, 0);
27990bf3144e89abfff8af1d3c35afe2a59bb680397Jessica Hummel            } catch (NameNotFoundException e) {
28095a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel                throw new ManagedProvisioningFailedException("Mdm "+ mMdmPackageName
281f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                        + " is not installed. ", e);
28290bf3144e89abfff8af1d3c35afe2a59bb680397Jessica Hummel            }
283e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina        }
284e9965bbb03204d1863767f7e6c81d08208477358Alexandra Gherghina    }
285c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel
286b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummel    @Override
287c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel    public void onBackPressed() {
288c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel        // TODO: Handle this graciously by stopping the provisioning flow and cleaning up.
289935e3239fc0d4648536c5392d0917297c3ce5656Jessica Hummel    }
290fe18f4574f5029775ce242656d22b67660891595Adam Connors
29114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    @Override
29214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    public void onDestroy() {
29381fe104ecfc98f1fb4356891acfe696e7445acb8Jessica Hummel        LocalBroadcastManager.getInstance(this).unregisterReceiver(mServiceMessageReceiver);
29414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        super.onDestroy();
29514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
29614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
29714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    /**
29814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * If the device is encrypted start the service which does the provisioning, otherwise ask for
29914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * user consent to encrypt the device.
30014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     */
30114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void checkEncryptedAndStartProvisioningService() {
3028bf486ee7dd8d9d076c0515f970dd069e4230c6cAmith Yamasani        if (EncryptDeviceActivity.isDeviceEncrypted()
3038bf486ee7dd8d9d076c0515f970dd069e4230c6cAmith Yamasani                || SystemProperties.getBoolean("persist.sys.no_req_encrypt", false)) {
30483d65ead6ecd2af15b7eaf7044585100c4354723Jessica Hummel
30583d65ead6ecd2af15b7eaf7044585100c4354723Jessica Hummel            // Notify the user once more that the admin will have full control over the profile,
30683d65ead6ecd2af15b7eaf7044585100c4354723Jessica Hummel            // then start provisioning.
3077a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse            new UserConsentDialog(this, UserConsentDialog.PROFILE_OWNER, new Runnable() {
3087a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse                    @Override
3097a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse                    public void run() {
3107a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse                        setupEnvironmentAndProvision();
3117a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse                    }
3127a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse                } /* onUserConsented */ , null /* onCancel */).show(getFragmentManager(),
3137a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse                        "UserConsentDialogFragment");
3140df3a2feb2e93934b805b156801abdb7ef98a50cNicolas Prevot        } else {
31528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            Bundle resumeExtras = getIntent().getExtras();
3164af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            resumeExtras.putString(EXTRA_RESUME_TARGET, TARGET_PROFILE_OWNER);
3170df3a2feb2e93934b805b156801abdb7ef98a50cNicolas Prevot            Intent encryptIntent = new Intent(this, EncryptDeviceActivity.class)
3184af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                    .putExtra(EXTRA_RESUME, resumeExtras);
3190df3a2feb2e93934b805b156801abdb7ef98a50cNicolas Prevot            startActivityForResult(encryptIntent, ENCRYPT_DEVICE_REQUEST_CODE);
32014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            // Continue in onActivityResult or after reboot.
3210df3a2feb2e93934b805b156801abdb7ef98a50cNicolas Prevot        }
3220df3a2feb2e93934b805b156801abdb7ef98a50cNicolas Prevot    }
3230df3a2feb2e93934b805b156801abdb7ef98a50cNicolas Prevot
3247a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse    private void setupEnvironmentAndProvision() {
3257a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        // Remove any pre-provisioning UI in favour of progress display
3267a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        BootReminder.cancelProvisioningReminder(
3277a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse                ManagedProvisioningActivity.this);
3287a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        mProgressView.setVisibility(View.VISIBLE);
3297a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        mMainTextView.setVisibility(View.GONE);
3307a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse
3317a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        // Check whether the current launcher supports managed profiles.
3327a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        if (!currentLauncherSupportsManagedProfiles()) {
3337a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse            showCurrentLauncherInvalid();
3347a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        } else {
3357a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse            startManagedProvisioningService();
3367a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse        }
3377a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse    }
3387a85694423d9c0246ddb477cb2fc0add9b7841e2Sander Alewijnse
3392d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    private void pickLauncher() {
3402d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        Intent changeLauncherIntent = new Intent("android.settings.HOME_SETTINGS");
3412d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        changeLauncherIntent.putExtra(EXTRA_SUPPORT_MANAGED_PROFILES, true);
3422d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        startActivityForResult(changeLauncherIntent, CHANGE_LAUNCHER_REQUEST_CODE);
3432d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        // Continue in onActivityResult.
3442d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    }
3452d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
3462d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    private void startManagedProvisioningService() {
3472d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        Intent intent = new Intent(this, ManagedProvisioningService.class);
3482d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        intent.putExtras(getIntent());
3492d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        startService(intent);
3502d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    }
3512d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
352935e3239fc0d4648536c5392d0917297c3ce5656Jessica Hummel    @Override
353935e3239fc0d4648536c5392d0917297c3ce5656Jessica Hummel    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
3540ea830dd25796752ba54031923aed85915cd1e77Jessica Hummel        if (requestCode == ENCRYPT_DEVICE_REQUEST_CODE) {
355bfb20ba4c61320f5b8d6e1e0163970e52c17f682Jessica Hummel            if (resultCode == RESULT_CANCELED) {
356de8b4640d578686b3a74e466750cbecda18e9b02Robin Lee                ProvisionLogger.loge("User canceled device encryption.");
35701fe4babdd237a80514f92997e55e4b7cd90327aJessica Hummel                setResult(Activity.RESULT_CANCELED);
358de8b4640d578686b3a74e466750cbecda18e9b02Robin Lee                finish();
3593ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee            }
3602d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        } else if (requestCode == CHANGE_LAUNCHER_REQUEST_CODE) {
3612d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse            if (resultCode == RESULT_CANCELED) {
3622d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                showCurrentLauncherInvalid();
3632d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse            } else if (resultCode == RESULT_OK) {
3642d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                startManagedProvisioningService();
3652d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse            }
366bfb20ba4c61320f5b8d6e1e0163970e52c17f682Jessica Hummel        }
367b5f001d0a8dc50ed3e1d946361b799bf9c2e603bJessica Hummel    }
36839259237a3cac02285decb00100d3f60ad31d22bJessica Hummel
3692d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    private void showCurrentLauncherInvalid() {
3702d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse        new AlertDialog.Builder(this)
371c3fc45efe7786451f779cdba5c012b1a0e0362b2Jessica Hummel                .setCancelable(false)
3722d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                .setMessage(R.string.managed_provisioning_not_supported_by_launcher)
3732d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                .setNegativeButton(R.string.cancel_provisioning,
3742d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                        new DialogInterface.OnClickListener() {
3752d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                            @Override
3762d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                            public void onClick(DialogInterface dialog,int id) {
3772d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                                dialog.dismiss();
3782d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                                setResult(Activity.RESULT_CANCELED);
3792d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                                finish();
3802d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                            }
3812d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                        })
3822d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                .setPositiveButton(R.string.pick_launcher,
3832d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                        new DialogInterface.OnClickListener() {
3842d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                            @Override
3852d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                            public void onClick(DialogInterface dialog,int id) {
3862d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                                pickLauncher();
3872d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                            }
3882d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse                        }).show();
3892d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse    }
3902d0a093eb86ad4f276385585a9fd02f521fa71b0Sander Alewijnse
39195a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel    public void showErrorAndClose(int resourceId, String logText) {
39295a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel        ProvisionLogger.loge(logText);
39395a210f0bba8f236d5b546f9aa3a05b35eff3afbJessica Hummel        new ManagedProvisioningErrorDialog(getString(resourceId))
394b3762e394c984b5376d4eb109d5de5528b47df10Alexandra Gherghina              .show(getFragmentManager(), "ErrorDialogFragment");
395fe18f4574f5029775ce242656d22b67660891595Adam Connors    }
396b0ad5b563efa27b471f2fbbe18f23a94bfabea06Nicolas Prevot
39722265143c1264eab25977402777f81cb027229ebJessica Hummel    /**
39822265143c1264eab25977402777f81cb027229ebJessica Hummel     * @return The User id of an already existing managed profile or -1 if none
39922265143c1264eab25977402777f81cb027229ebJessica Hummel     * exists
40022265143c1264eab25977402777f81cb027229ebJessica Hummel     */
40122265143c1264eab25977402777f81cb027229ebJessica Hummel    int alreadyHasManagedProfile() {
402b0ad5b563efa27b471f2fbbe18f23a94bfabea06Nicolas Prevot        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
40351397d2507746aa4c47f031017c66fb874afa7e3Kenny Guy        List<UserInfo> profiles = userManager.getProfiles(getUserId());
40451397d2507746aa4c47f031017c66fb874afa7e3Kenny Guy        for (UserInfo userInfo : profiles) {
40522265143c1264eab25977402777f81cb027229ebJessica Hummel            if (userInfo.isManagedProfile()) {
40622265143c1264eab25977402777f81cb027229ebJessica Hummel                return userInfo.getUserHandle().getIdentifier();
40722265143c1264eab25977402777f81cb027229ebJessica Hummel            }
408b0ad5b563efa27b471f2fbbe18f23a94bfabea06Nicolas Prevot        }
40922265143c1264eab25977402777f81cb027229ebJessica Hummel        return -1;
410b0ad5b563efa27b471f2fbbe18f23a94bfabea06Nicolas Prevot    }
41188e1f540c92dafd6f64760be40c2962086a14b16Jessica Hummel
4124db254787bf5340f11409ac64d7c52fa6d1adf6dAlexandra Gherghina    /**
41322265143c1264eab25977402777f81cb027229ebJessica Hummel     * Builds a dialog that allows the user to remove an existing managed profile after they were
41422265143c1264eab25977402777f81cb027229ebJessica Hummel     * shown an additional warning.
41522265143c1264eab25977402777f81cb027229ebJessica Hummel     */
41622265143c1264eab25977402777f81cb027229ebJessica Hummel    private void showManagedProfileExistsDialog(
41722265143c1264eab25977402777f81cb027229ebJessica Hummel            final int existingManagedProfileUserId) {
41822265143c1264eab25977402777f81cb027229ebJessica Hummel
41922265143c1264eab25977402777f81cb027229ebJessica Hummel        // Before deleting, show a warning dialog
42022265143c1264eab25977402777f81cb027229ebJessica Hummel        DialogInterface.OnClickListener warningListener =
42122265143c1264eab25977402777f81cb027229ebJessica Hummel                new DialogInterface.OnClickListener() {
42222265143c1264eab25977402777f81cb027229ebJessica Hummel            @Override
42322265143c1264eab25977402777f81cb027229ebJessica Hummel            public void onClick(DialogInterface dialog, int which) {
42422265143c1264eab25977402777f81cb027229ebJessica Hummel                // Really delete the profile if the user clicks delete on the warning dialog.
42522265143c1264eab25977402777f81cb027229ebJessica Hummel                final DialogInterface.OnClickListener deleteListener =
42622265143c1264eab25977402777f81cb027229ebJessica Hummel                        new DialogInterface.OnClickListener() {
42722265143c1264eab25977402777f81cb027229ebJessica Hummel                    @Override
42822265143c1264eab25977402777f81cb027229ebJessica Hummel                    public void onClick(DialogInterface dialog, int which) {
42922265143c1264eab25977402777f81cb027229ebJessica Hummel                        UserManager userManager =
43022265143c1264eab25977402777f81cb027229ebJessica Hummel                                (UserManager) getSystemService(Context.USER_SERVICE);
43122265143c1264eab25977402777f81cb027229ebJessica Hummel                        userManager.removeUser(existingManagedProfileUserId);
43222265143c1264eab25977402777f81cb027229ebJessica Hummel                        showStartProvisioningScreen();
43322265143c1264eab25977402777f81cb027229ebJessica Hummel                    }
43422265143c1264eab25977402777f81cb027229ebJessica Hummel                };
43522265143c1264eab25977402777f81cb027229ebJessica Hummel                buildDeleteManagedProfileDialog(
43622265143c1264eab25977402777f81cb027229ebJessica Hummel                        getString(R.string.sure_you_want_to_delete_profile),
43722265143c1264eab25977402777f81cb027229ebJessica Hummel                        deleteListener).show();
43822265143c1264eab25977402777f81cb027229ebJessica Hummel            }
43922265143c1264eab25977402777f81cb027229ebJessica Hummel        };
44022265143c1264eab25977402777f81cb027229ebJessica Hummel
44122265143c1264eab25977402777f81cb027229ebJessica Hummel        buildDeleteManagedProfileDialog(
44222265143c1264eab25977402777f81cb027229ebJessica Hummel                getString(R.string.managed_profile_already_present),
44322265143c1264eab25977402777f81cb027229ebJessica Hummel                warningListener).show();
44422265143c1264eab25977402777f81cb027229ebJessica Hummel    }
44522265143c1264eab25977402777f81cb027229ebJessica Hummel
44622265143c1264eab25977402777f81cb027229ebJessica Hummel    private AlertDialog buildDeleteManagedProfileDialog(String message,
44722265143c1264eab25977402777f81cb027229ebJessica Hummel            DialogInterface.OnClickListener deleteListener) {
44822265143c1264eab25977402777f81cb027229ebJessica Hummel        DialogInterface.OnClickListener cancelListener =
44922265143c1264eab25977402777f81cb027229ebJessica Hummel                new DialogInterface.OnClickListener() {
45022265143c1264eab25977402777f81cb027229ebJessica Hummel            @Override
45122265143c1264eab25977402777f81cb027229ebJessica Hummel            public void onClick(DialogInterface dialog, int which) {
45222265143c1264eab25977402777f81cb027229ebJessica Hummel                ManagedProvisioningActivity.this.finish();
45322265143c1264eab25977402777f81cb027229ebJessica Hummel            }
45422265143c1264eab25977402777f81cb027229ebJessica Hummel        };
45522265143c1264eab25977402777f81cb027229ebJessica Hummel
45622265143c1264eab25977402777f81cb027229ebJessica Hummel        AlertDialog.Builder builder = new AlertDialog.Builder(this);
45722265143c1264eab25977402777f81cb027229ebJessica Hummel        builder.setMessage(message)
458c3fc45efe7786451f779cdba5c012b1a0e0362b2Jessica Hummel                .setCancelable(false)
459c3fc45efe7786451f779cdba5c012b1a0e0362b2Jessica Hummel                .setPositiveButton(getString(R.string.delete_profile), deleteListener)
460c3fc45efe7786451f779cdba5c012b1a0e0362b2Jessica Hummel                .setNegativeButton(getString(R.string.cancel_delete_profile), cancelListener);
46122265143c1264eab25977402777f81cb027229ebJessica Hummel
46222265143c1264eab25977402777f81cb027229ebJessica Hummel        return builder.create();
46322265143c1264eab25977402777f81cb027229ebJessica Hummel    }
46422265143c1264eab25977402777f81cb027229ebJessica Hummel    /**
4654db254787bf5340f11409ac64d7c52fa6d1adf6dAlexandra Gherghina     * Exception thrown when the managed provisioning has failed completely.
4664db254787bf5340f11409ac64d7c52fa6d1adf6dAlexandra Gherghina     *
46714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * We're using a custom exception to avoid catching subsequent exceptions that might be
4684db254787bf5340f11409ac64d7c52fa6d1adf6dAlexandra Gherghina     * significant.
4694db254787bf5340f11409ac64d7c52fa6d1adf6dAlexandra Gherghina     */
4704db254787bf5340f11409ac64d7c52fa6d1adf6dAlexandra Gherghina    private class ManagedProvisioningFailedException extends Exception {
471f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        public ManagedProvisioningFailedException(String message) {
472f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse            super(message);
473f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        }
474f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse
475f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        public ManagedProvisioningFailedException(String message, Throwable t) {
476f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse            super(message, t);
477f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        }
4784db254787bf5340f11409ac64d7c52fa6d1adf6dAlexandra Gherghina    }
4798119e129fd46232edb1cab7708c86db8d8b9ddd0Jessica Hummel}
480c4d5d2b9d065707a51134d494cf64c10b8c3af99Jessica Hummel
481