1 /* 2 * Copyright (C) 2017 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 package com.android.settings.system; 17 18 import android.Manifest; 19 import android.annotation.RequiresPermission; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.PackageInfo; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.os.UserManager; 26 import android.util.Log; 27 28 import androidx.activity.result.ActivityResultLauncher; 29 import androidx.activity.result.contract.ActivityResultContracts; 30 import androidx.preference.Preference; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.settings.Settings; 34 import com.android.settings.core.BasePreferenceController; 35 import com.android.settings.factory_reset.Flags; 36 37 public class FactoryResetPreferenceController extends BasePreferenceController { 38 39 private static final String TAG = "FactoryResetPreference"; 40 41 @RequiresPermission(Manifest.permission.PREPARE_FACTORY_RESET) 42 public static final String ACTION_PREPARE_FACTORY_RESET = 43 "com.android.settings.ACTION_PREPARE_FACTORY_RESET"; 44 45 private final UserManager mUm; 46 47 @VisibleForTesting 48 ActivityResultLauncher<Intent> mFactoryResetPreparationLauncher; 49 FactoryResetPreferenceController(Context context, String preferenceKey)50 public FactoryResetPreferenceController(Context context, String preferenceKey) { 51 super(context, preferenceKey); 52 mUm = (UserManager) context.getSystemService(Context.USER_SERVICE); 53 } 54 55 /** Hide "Factory reset" settings for secondary users. */ 56 @Override getAvailabilityStatus()57 public int getAvailabilityStatus() { 58 return mUm.isAdminUser() ? AVAILABLE : DISABLED_FOR_USER; 59 } 60 61 @Override handlePreferenceTreeClick(Preference preference)62 public boolean handlePreferenceTreeClick(Preference preference) { 63 if (mPreferenceKey.equals(preference.getKey())) { 64 if (Flags.enableFactoryResetWizard()) { 65 startFactoryResetPreparationActivity(); 66 } else { 67 startFactoryResetActivity(); 68 } 69 return true; 70 } 71 return false; 72 } 73 startFactoryResetPreparationActivity()74 private void startFactoryResetPreparationActivity() { 75 Intent prepareFactoryResetIntent = getPrepareFactoryResetIntent(); 76 if (prepareFactoryResetIntent != null && mFactoryResetPreparationLauncher != null) { 77 mFactoryResetPreparationLauncher.launch(prepareFactoryResetIntent); 78 } else { 79 startFactoryResetActivity(); 80 } 81 } 82 83 // We check that the activity that can handle the factory reset preparation action is indeed 84 // a system app with proper permissions. getPrepareFactoryResetIntent()85 private Intent getPrepareFactoryResetIntent() { 86 final Intent prepareFactoryResetWizardRequest = new Intent(ACTION_PREPARE_FACTORY_RESET); 87 final PackageManager pm = mContext.getPackageManager(); 88 final ResolveInfo resolution = pm.resolveActivity(prepareFactoryResetWizardRequest, 0); 89 if (resolution != null 90 && resolution.activityInfo != null) { 91 String packageName = resolution.activityInfo.packageName; 92 PackageInfo factoryResetWizardPackageInfo; 93 try { 94 factoryResetWizardPackageInfo = pm.getPackageInfo(packageName, 95 PackageManager.GET_PERMISSIONS); 96 } catch (PackageManager.NameNotFoundException e) { 97 Log.e(TAG, "Unable to resolve a Factory Reset Handler Application"); 98 return null; 99 } 100 if (factoryResetWizardPackageInfo.requestedPermissions == null 101 || factoryResetWizardPackageInfo.requestedPermissions.length == 0) { 102 Log.e(TAG, "Factory Reset Handler has no permissions requested."); 103 return null; 104 } 105 for (int i = 0; i < factoryResetWizardPackageInfo.requestedPermissions.length; i++) { 106 String permission = factoryResetWizardPackageInfo.requestedPermissions[i]; 107 boolean isGranted = 108 (factoryResetWizardPackageInfo.requestedPermissionsFlags[i] 109 & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0; 110 if (permission.equals(Manifest.permission.PREPARE_FACTORY_RESET) && isGranted) { 111 return prepareFactoryResetWizardRequest; 112 } 113 } 114 return null; 115 } 116 Log.i(TAG, "Unable to resolve a Factory Reset Handler Activity"); 117 return null; 118 } 119 setFragment(ResetDashboardFragment fragment)120 void setFragment(ResetDashboardFragment fragment) { 121 if (Flags.enableFactoryResetWizard()) { 122 mFactoryResetPreparationLauncher = fragment.registerForActivityResult( 123 new ActivityResultContracts.StartActivityForResult(), 124 result -> { 125 startFactoryResetActivity(); 126 }); 127 } 128 } 129 startFactoryResetActivity()130 private void startFactoryResetActivity() { 131 final Intent intent = new Intent(mContext, Settings.FactoryResetActivity.class); 132 mContext.startActivity(intent); 133 } 134 } 135