1 /* 2 * Copyright (C) 2021 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.admin; 18 19 import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_PARKED; 20 21 import android.app.Activity; 22 import android.app.AlertDialog; 23 import android.app.NotificationManager; 24 import android.app.PendingIntent; 25 import android.car.Car; 26 import android.car.ICarResultReceiver; 27 import android.car.drivingstate.CarDrivingStateEvent; 28 import android.car.drivingstate.CarDrivingStateManager; 29 import android.content.Intent; 30 import android.os.Bundle; 31 import android.os.IBinder; 32 import android.widget.Toast; 33 34 import com.android.car.settings.R; 35 import com.android.car.settings.common.Logger; 36 37 38 /** 39 * Activity shown when a factory request is imminent, it gives the user the option to reset now or 40 * wait until the device is rebooted / resumed from suspend. 41 */ 42 public final class FactoryResetActivity extends Activity { 43 private static final String EXTRA_FACTORY_RESET_CALLBACK = "factory_reset_callback"; 44 private static final int FACTORY_RESET_NOTIFICATION_ID = 42; 45 private static final Logger LOG = new Logger(FactoryResetActivity.class); 46 private ICarResultReceiver mCallback; 47 private Car mCar; 48 private CarDrivingStateManager mCarDrivingStateManager; 49 50 @Override onCreate(Bundle savedInstanceState)51 protected void onCreate(Bundle savedInstanceState) { 52 super.onCreate(savedInstanceState); 53 54 Intent intent = getIntent(); 55 Object binder = null; 56 57 try { 58 binder = intent.getExtra(EXTRA_FACTORY_RESET_CALLBACK); 59 mCallback = ICarResultReceiver.Stub.asInterface((IBinder) binder); 60 } catch (Exception e) { 61 LOG.w("error getting IResultReveiver from " + EXTRA_FACTORY_RESET_CALLBACK 62 + " extra (" + binder + ") on " + intent, e); 63 } 64 65 if (mCallback == null) { 66 LOG.wtf("no ICarResultReceiver / " + EXTRA_FACTORY_RESET_CALLBACK 67 + " extra on " + intent); 68 finish(); 69 return; 70 } 71 72 // Connect to car service 73 mCar = Car.createCar(this); 74 mCarDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager( 75 Car.CAR_DRIVING_STATE_SERVICE); 76 showMore(); 77 } 78 79 @Override onStop()80 protected void onStop() { 81 super.onStop(); 82 finish(); 83 } 84 showMore()85 private void showMore() { 86 CarDrivingStateEvent state = mCarDrivingStateManager.getCurrentCarDrivingState(); 87 switch (state.eventValue) { 88 case DRIVING_STATE_PARKED: 89 showFactoryResetDialog(); 90 break; 91 default: 92 showFactoryResetToast(); 93 } 94 } 95 showFactoryResetDialog()96 private void showFactoryResetDialog() { 97 AlertDialog dialog = new AlertDialog.Builder(/* context= */ this, 98 com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert) 99 .setTitle(R.string.factory_reset_parked_title) 100 .setMessage(R.string.factory_reset_parked_text) 101 .setPositiveButton(R.string.factory_reset_later_button, 102 (d, which) -> factoryResetLater()) 103 .setNegativeButton(R.string.factory_reset_now_button, 104 (d, which) -> factoryResetNow()) 105 .setCancelable(false) 106 .setOnDismissListener((d) -> finish()) 107 .create(); 108 109 dialog.show(); 110 } 111 showFactoryResetToast()112 private void showFactoryResetToast() { 113 showToast(R.string.factory_reset_driving_text); 114 finish(); 115 } 116 factoryResetNow()117 private void factoryResetNow() { 118 LOG.i("Factory reset acknowledged; finishing it"); 119 120 try { 121 mCallback.send(/* resultCode= */ 0, /* resultData= */ null); 122 123 // Cancel pending intent and notification 124 getSystemService(NotificationManager.class).cancel(FACTORY_RESET_NOTIFICATION_ID); 125 PendingIntent.getActivity(this, FACTORY_RESET_NOTIFICATION_ID, getIntent(), 126 PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT).cancel(); 127 } catch (Exception e) { 128 LOG.e("error factory resetting or cancelling notification / intent", e); 129 return; 130 } finally { 131 finish(); 132 } 133 } 134 factoryResetLater()135 private void factoryResetLater() { 136 LOG.i("Delaying factory reset."); 137 showToast(R.string.factory_reset_later_text); 138 finish(); 139 } 140 showToast(int resId)141 private void showToast(int resId) { 142 Toast.makeText(this, resId, Toast.LENGTH_LONG).show(); 143 } 144 } 145