1b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani/*
2b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * Copyright (C) 2010 The Android Open Source Project
3b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani *
4b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
5b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * you may not use this file except in compliance with the License.
6b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * You may obtain a copy of the License at
7b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani *
8b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
9b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani *
10b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * Unless required by applicable law or agreed to in writing, software
11b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
12b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * See the License for the specific language governing permissions and
14b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * limitations under the License.
15b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani */
16b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
17b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasanipackage com.android.settings;
18b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
19ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Moralesimport android.app.ProgressDialog;
207ab8929cc6ecbd1ba14c0d6ecb393b31f9a6fcdaAndres Moralesimport android.content.Context;
21ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Moralesimport android.content.pm.ActivityInfo;
22ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Moralesimport android.os.AsyncTask;
237ab8929cc6ecbd1ba14c0d6ecb393b31f9a6fcdaAndres Moralesimport android.service.persistentdata.PersistentDataBlockManager;
24b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport com.android.internal.os.storage.ExternalStorageFormatter;
25b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
26b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport android.app.Fragment;
27b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport android.content.Intent;
28b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport android.os.Bundle;
292c53933e8d35ba50d0791a29e46fa3156e9cab7cJulia Reynoldsimport android.os.UserManager;
30b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport android.view.LayoutInflater;
31b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport android.view.View;
32b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport android.view.ViewGroup;
33b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasaniimport android.widget.Button;
34b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
35b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani/**
36b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * Confirm and execute a reset of the device to a clean "just out of the box"
37b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * state.  Multiple confirmations are required: first, a general "are you sure
38b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * you want to do this?" prompt, followed by a keyguard pattern trace if the user
39b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING
40b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * ON THE PHONE" prompt.  If at any time the phone is allowed to go to sleep, is
41b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * locked, et cetera, then the confirmation sequence is abandoned.
42b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani *
43b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani * This is the confirmation screen.
44b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani */
45b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasanipublic class MasterClearConfirm extends Fragment {
46b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
47b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    private View mContentView;
48b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    private boolean mEraseSdCard;
49b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
50b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    /**
51b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani     * The user has gone through the multiple confirmation, so now we go ahead
52b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani     * and invoke the Checkin Service to reset the device to its factory-default
53b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani     * state (rebooting in the process).
54b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani     */
55b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
56b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
57b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani        public void onClick(View v) {
58b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani            if (Utils.isMonkeyRunning()) {
59b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani                return;
60b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani            }
61b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
62ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager)
637ab8929cc6ecbd1ba14c0d6ecb393b31f9a6fcdaAndres Morales                    getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
647ab8929cc6ecbd1ba14c0d6ecb393b31f9a6fcdaAndres Morales
65e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales            if (pdbManager != null && !pdbManager.getOemUnlockEnabled()) {
66ae58323a6b172f4a8607e6b187ea5c45b9b8e185Andres Morales                // if OEM unlock is enabled, this will be wiped during FR process.
67e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                final ProgressDialog progressDialog = getProgressDialog();
68e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                progressDialog.show();
69ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales
70e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                // need to prevent orientation changes as we're about to go into
71e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                // a long IO request, so we won't be able to access inflate resources on flash
72e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                final int oldOrientation = getActivity().getRequestedOrientation();
73e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
74e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                new AsyncTask<Void, Void, Void>() {
75e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                    @Override
76e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                    protected Void doInBackground(Void... params) {
77e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                        pdbManager.wipe();
78e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                        return null;
79e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                    }
807ab8929cc6ecbd1ba14c0d6ecb393b31f9a6fcdaAndres Morales
81e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                    @Override
82e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                    protected void onPostExecute(Void aVoid) {
83e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                        progressDialog.hide();
84e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                        getActivity().setRequestedOrientation(oldOrientation);
85e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                        doMasterClear();
86e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                    }
87e6bf2a5609b9aabbd790c3c3680172f4b50a3f8eAndres Morales                }.execute();
88b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani            } else {
89ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales                doMasterClear();
90b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani            }
91b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani        }
92ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales
93ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales        private ProgressDialog getProgressDialog() {
94ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            final ProgressDialog progressDialog = new ProgressDialog(getActivity());
95ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            progressDialog.setIndeterminate(true);
96ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            progressDialog.setCancelable(false);
97ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            progressDialog.setTitle(
98ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales                    getActivity().getString(R.string.master_clear_progress_title));
99ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            progressDialog.setMessage(
100ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales                    getActivity().getString(R.string.master_clear_progress_text));
101ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            return progressDialog;
102ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales        }
103b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    };
104b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
105ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales    private void doMasterClear() {
106ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales        if (mEraseSdCard) {
107ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
1081de688d911cf96eff39eddc5a7070e3c44efefc1Jeff Sharkey            intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
109ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
110ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            getActivity().startService(intent);
111ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales        } else {
1121de688d911cf96eff39eddc5a7070e3c44efefc1Jeff Sharkey            Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
1131de688d911cf96eff39eddc5a7070e3c44efefc1Jeff Sharkey            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1141de688d911cf96eff39eddc5a7070e3c44efefc1Jeff Sharkey            intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
1151de688d911cf96eff39eddc5a7070e3c44efefc1Jeff Sharkey            getActivity().sendBroadcast(intent);
116ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales            // Intent handling is asynchronous -- assume it will happen soon.
117ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales        }
118ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales    }
119ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales
120b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    /**
121b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani     * Configure the UI for the final confirmation interaction
122b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani     */
123b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    private void establishFinalConfirmationState() {
124ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales        mContentView.findViewById(R.id.execute_master_clear)
125ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales                .setOnClickListener(mFinalClickListener);
126b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    }
127b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
128b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    @Override
129b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    public View onCreateView(LayoutInflater inflater, ViewGroup container,
130b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani            Bundle savedInstanceState) {
1312c53933e8d35ba50d0791a29e46fa3156e9cab7cJulia Reynolds        if (UserManager.get(getActivity()).hasUserRestriction(
1322c53933e8d35ba50d0791a29e46fa3156e9cab7cJulia Reynolds                UserManager.DISALLOW_FACTORY_RESET)) {
1332c53933e8d35ba50d0791a29e46fa3156e9cab7cJulia Reynolds            return inflater.inflate(R.layout.master_clear_disallowed_screen, null);
1342c53933e8d35ba50d0791a29e46fa3156e9cab7cJulia Reynolds        }
135b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani        mContentView = inflater.inflate(R.layout.master_clear_confirm, null);
136b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani        establishFinalConfirmationState();
137b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani        return mContentView;
138b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    }
139b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
140b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    @Override
141b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    public void onCreate(Bundle savedInstanceState) {
142b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani        super.onCreate(savedInstanceState);
143b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani
144b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani        Bundle args = getArguments();
145ab61b0df4af1a504e845c7008224ebadb5400ce9Andres Morales        mEraseSdCard = args != null && args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA);
146b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani    }
147b14e1e04939ca610fd5f2439f879265450b0a6cdAmith Yamasani}
148