1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings; 18 19 import android.app.Activity; 20 import android.content.Intent; 21 import android.os.Bundle; 22 import android.os.storage.StorageVolume; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.widget.Button; 26 27 import com.android.internal.os.storage.ExternalStorageFormatter; 28 29 /** 30 * Confirm and execute a format of the sdcard. 31 * Multiple confirmations are required: first, a general "are you sure 32 * you want to do this?" prompt, followed by a keyguard pattern trace if the user 33 * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING 34 * ON THE SD CARD" prompt. If at any time the phone is allowed to go to sleep, is 35 * locked, et cetera, then the confirmation sequence is abandoned. 36 */ 37 public class MediaFormat extends Activity { 38 39 private static final int KEYGUARD_REQUEST = 55; 40 41 private LayoutInflater mInflater; 42 43 private View mInitialView; 44 private Button mInitiateButton; 45 46 private View mFinalView; 47 private Button mFinalButton; 48 49 /** 50 * The user has gone through the multiple confirmation, so now we go ahead 51 * and invoke the Mount Service to format the SD card. 52 */ 53 private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() { 54 public void onClick(View v) { 55 56 if (Utils.isMonkeyRunning()) { 57 return; 58 } 59 Intent intent = new Intent(ExternalStorageFormatter.FORMAT_ONLY); 60 intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME); 61 // Transfer the storage volume to the new intent 62 final StorageVolume storageVolume = getIntent().getParcelableExtra( 63 StorageVolume.EXTRA_STORAGE_VOLUME); 64 intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, storageVolume); 65 startService(intent); 66 finish(); 67 } 68 }; 69 70 /** 71 * Keyguard validation is run using the standard {@link ConfirmLockPattern} 72 * component as a subactivity 73 */ runKeyguardConfirmation(int request)74 private boolean runKeyguardConfirmation(int request) { 75 return new ChooseLockSettingsHelper(this) 76 .launchConfirmationActivity(request, 77 getText(R.string.media_format_gesture_prompt), 78 getText(R.string.media_format_gesture_explanation)); 79 } 80 81 @Override onActivityResult(int requestCode, int resultCode, Intent data)82 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 83 super.onActivityResult(requestCode, resultCode, data); 84 85 if (requestCode != KEYGUARD_REQUEST) { 86 return; 87 } 88 89 // If the user entered a valid keyguard trace, present the final 90 // confirmation prompt; otherwise, go back to the initial state. 91 if (resultCode == Activity.RESULT_OK) { 92 establishFinalConfirmationState(); 93 } else if (resultCode == Activity.RESULT_CANCELED) { 94 finish(); 95 } else { 96 establishInitialState(); 97 } 98 } 99 100 /** 101 * If the user clicks to begin the reset sequence, we next require a 102 * keyguard confirmation if the user has currently enabled one. If there 103 * is no keyguard available, we simply go to the final confirmation prompt. 104 */ 105 private Button.OnClickListener mInitiateListener = new Button.OnClickListener() { 106 public void onClick(View v) { 107 if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) { 108 establishFinalConfirmationState(); 109 } 110 } 111 }; 112 113 /** 114 * Configure the UI for the final confirmation interaction 115 */ establishFinalConfirmationState()116 private void establishFinalConfirmationState() { 117 if (mFinalView == null) { 118 mFinalView = mInflater.inflate(R.layout.media_format_final, null); 119 mFinalButton = 120 (Button) mFinalView.findViewById(R.id.execute_media_format); 121 mFinalButton.setOnClickListener(mFinalClickListener); 122 } 123 124 setContentView(mFinalView); 125 } 126 127 /** 128 * In its initial state, the activity presents a button for the user to 129 * click in order to initiate a confirmation sequence. This method is 130 * called from various other points in the code to reset the activity to 131 * this base state. 132 * 133 * <p>Reinflating views from resources is expensive and prevents us from 134 * caching widget pointers, so we use a single-inflate pattern: we lazy- 135 * inflate each view, caching all of the widget pointers we'll need at the 136 * time, then simply reuse the inflated views directly whenever we need 137 * to change contents. 138 */ establishInitialState()139 private void establishInitialState() { 140 if (mInitialView == null) { 141 mInitialView = mInflater.inflate(R.layout.media_format_primary, null); 142 mInitiateButton = 143 (Button) mInitialView.findViewById(R.id.initiate_media_format); 144 mInitiateButton.setOnClickListener(mInitiateListener); 145 } 146 147 setContentView(mInitialView); 148 } 149 150 @Override onCreate(Bundle savedState)151 protected void onCreate(Bundle savedState) { 152 super.onCreate(savedState); 153 154 mInitialView = null; 155 mFinalView = null; 156 mInflater = LayoutInflater.from(this); 157 158 establishInitialState(); 159 } 160 161 /** Abandon all progress through the confirmation sequence by returning 162 * to the initial view any time the activity is interrupted (e.g. by 163 * idle timeout). 164 */ 165 @Override onPause()166 public void onPause() { 167 super.onPause(); 168 169 if (!isFinishing()) { 170 establishInitialState(); 171 } 172 } 173 } 174