1 /* 2 * Copyright 2019 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.car.settings.system; 18 19 import android.app.ActivityManager; 20 import android.app.ProgressDialog; 21 import android.content.Intent; 22 import android.content.SharedPreferences; 23 import android.os.AsyncTask; 24 import android.os.Bundle; 25 import android.provider.Settings; 26 import android.service.oemlock.OemLockManager; 27 import android.service.persistentdata.PersistentDataBlockManager; 28 29 import androidx.annotation.VisibleForTesting; 30 import androidx.preference.PreferenceManager; 31 32 import com.android.car.settings.R; 33 import com.android.car.settings.common.SettingsFragment; 34 import com.android.car.ui.toolbar.MenuItem; 35 36 import java.util.Collections; 37 import java.util.List; 38 39 /** 40 * Presents the user with a final warning before issuing the request to reset the head unit to its 41 * default "factory" state. 42 */ 43 public class FactoryResetConfirmFragment extends SettingsFragment { 44 45 private MenuItem mClearConfirmButton; 46 @VisibleForTesting 47 AsyncTask<Void, Void, Void> mPersistentDataWipeTask; 48 49 private MenuItem.OnClickListener mFinalClickListener = i -> { 50 if (ActivityManager.isUserAMonkey()) { 51 return; 52 } 53 54 PersistentDataBlockManager pdbManager = requireContext().getSystemService( 55 PersistentDataBlockManager.class); 56 OemLockManager oemLockManager = requireContext().getSystemService(OemLockManager.class); 57 if (pdbManager != null && !oemLockManager.isOemUnlockAllowed() 58 && isDeviceProvisioned()) { 59 // If OEM unlock is allowed, the persistent data block will be wiped during the factory 60 // reset process. If disabled, it will be wiped here, unless the device is still being 61 // provisioned, in which case the persistent data block will be preserved. 62 mPersistentDataWipeTask = new WipePersistentDataBlockAsyncTask(pdbManager); 63 mPersistentDataWipeTask.execute(); 64 } else { 65 resetEverything(); 66 } 67 }; 68 69 @Override getPreferenceScreenResId()70 protected int getPreferenceScreenResId() { 71 return R.xml.factory_reset_confirm_fragment; 72 } 73 74 @Override getToolbarMenuItems()75 protected List<MenuItem> getToolbarMenuItems() { 76 return Collections.singletonList(mClearConfirmButton); 77 } 78 79 @Override onCreate(Bundle savedInstanceState)80 public void onCreate(Bundle savedInstanceState) { 81 super.onCreate(savedInstanceState); 82 83 mClearConfirmButton = new MenuItem.Builder(getContext()) 84 .setTitle(R.string.factory_reset_confirm_button_text) 85 .setOnClickListener(mFinalClickListener) 86 .build(); 87 } 88 89 @VisibleForTesting getProgressDialog()90 ProgressDialog getProgressDialog() { 91 ProgressDialog progressDialog = new ProgressDialog(requireContext()); 92 progressDialog.setIndeterminate(true); 93 progressDialog.setCancelable(false); 94 progressDialog.setTitle(requireContext().getString(R.string.factory_reset_progress_title)); 95 progressDialog.setMessage(requireContext().getString(R.string.factory_reset_progress_text)); 96 return progressDialog; 97 } 98 isDeviceProvisioned()99 private boolean isDeviceProvisioned() { 100 return Settings.Global.getInt(requireContext().getContentResolver(), 101 Settings.Global.DEVICE_PROVISIONED, 0) != 0; 102 } 103 resetEverything()104 private void resetEverything() { 105 Intent intent = new Intent(Intent.ACTION_FACTORY_RESET); 106 intent.setPackage("android"); 107 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 108 intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm"); 109 intent.putExtra(Intent.EXTRA_WIPE_ESIMS, shouldResetEsim()); 110 requireActivity().sendBroadcast(intent); 111 } 112 shouldResetEsim()113 private boolean shouldResetEsim() { 114 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences( 115 requireContext()); 116 return sharedPreferences.getBoolean( 117 requireContext().getString(R.string.pk_factory_reset_reset_esim), false); 118 } 119 120 private class WipePersistentDataBlockAsyncTask extends AsyncTask<Void, Void, Void> { 121 private final PersistentDataBlockManager mPdbManager; 122 private ProgressDialog mProgressDialog; 123 WipePersistentDataBlockAsyncTask(PersistentDataBlockManager pdbManager)124 WipePersistentDataBlockAsyncTask(PersistentDataBlockManager pdbManager) { 125 mPdbManager = pdbManager; 126 } 127 128 @Override doInBackground(Void... params)129 protected Void doInBackground(Void... params) { 130 mPdbManager.wipe(); 131 return null; 132 } 133 134 @Override onPostExecute(Void aVoid)135 protected void onPostExecute(Void aVoid) { 136 mProgressDialog.hide(); 137 if (getActivity() != null) { 138 resetEverything(); 139 } 140 } 141 142 @Override onPreExecute()143 protected void onPreExecute() { 144 mProgressDialog = getProgressDialog(); 145 mProgressDialog.show(); 146 } 147 } 148 } 149