155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn/* 255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * Copyright (C) 2008 The Android Open Source Project 355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * 455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * you may not use this file except in compliance with the License. 655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * You may obtain a copy of the License at 755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * 855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * 1055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * See the License for the specific language governing permissions and 1455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * limitations under the License. 1555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn */ 1655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 1755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 184f8ecd80296508a1dc69d3f3a23fd91e962c2784Jeff Brownpackage com.android.server.power; 1955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 2055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.app.ActivityManagerNative; 21d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onoratoimport android.app.AlertDialog; 22d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onoratoimport android.app.Dialog; 2355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.app.IActivityManager; 2455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.app.ProgressDialog; 25bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport android.bluetooth.BluetoothAdapter; 260f42037eb7b5118015c2caca635538324ccf0ccffredcimport android.bluetooth.IBluetoothManager; 277b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlockimport android.media.AudioAttributes; 283bba8d0457408421a6468f03bbb36e9ff32b81cfSunil Jogiimport android.nfc.NfcAdapter; 293bba8d0457408421a6468f03bbb36e9ff32b81cfSunil Jogiimport android.nfc.INfcAdapter; 3055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.content.BroadcastReceiver; 3155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.content.Context; 3255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.content.DialogInterface; 3355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.content.Intent; 34d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onoratoimport android.content.IntentFilter; 3555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.os.Handler; 36f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackbornimport android.os.PowerManager; 3755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.os.RemoteException; 3855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.os.ServiceManager; 3955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.os.SystemClock; 40f547d679c058ed00de78a32146d04b75254df7ecKenny Rootimport android.os.SystemProperties; 415ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle; 42a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwoodimport android.os.Vibrator; 43c2346134bb519a54d50655cbef940fc3fdec60a9Jeff Brownimport android.os.SystemVibrator; 44b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.IMountService; 456ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapuimport android.os.storage.IMountShutdownObserver; 46568cae571a3d74d1992176a21722e07b44e9a3c4Dianne Hackborn 4755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport com.android.internal.telephony.ITelephony; 48ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstromimport com.android.server.pm.PackageManagerService; 497304c343821309dd15f769b18f1de2fa43751573Jeff Brown 5055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.util.Log; 5155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornimport android.view.WindowManager; 5255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 5355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackbornpublic final class ShutdownThread extends Thread { 5455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // constants 5555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private static final String TAG = "ShutdownThread"; 5655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500; 5755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // maximum time we wait for the shutdown broadcast before going on. 5855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private static final int MAX_BROADCAST_TIME = 10*1000; 596ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000; 60b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown private static final int MAX_RADIO_WAIT_TIME = 12*1000; 61a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood 62a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood // length of vibration before shutting down 63a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood private static final int SHUTDOWN_VIBRATE_MS = 500; 6455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 6555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // state tracking 6655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private static Object sIsStartedGuard = new Object(); 6755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private static boolean sIsStarted = false; 6855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 696ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu private static boolean mReboot; 7019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn private static boolean mRebootSafeMode; 716ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu private static String mRebootReason; 726ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu 73f547d679c058ed00de78a32146d04b75254df7ecKenny Root // Provides shutdown assurance in case the system_server is killed 74f547d679c058ed00de78a32146d04b75254df7ecKenny Root public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested"; 75f547d679c058ed00de78a32146d04b75254df7ecKenny Root 7619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn // Indicates whether we are rebooting into safe mode 7719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn public static final String REBOOT_SAFEMODE_PROPERTY = "persist.sys.safemode"; 7819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn 7955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // static instance of this thread 8055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private static final ShutdownThread sInstance = new ShutdownThread(); 817b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock 827b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() 837b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 847b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 857b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock .build(); 867b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock 876ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu private final Object mActionDoneSync = new Object(); 886ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu private boolean mActionDone; 8955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private Context mContext; 90f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn private PowerManager mPowerManager; 91cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson private PowerManager.WakeLock mCpuWakeLock; 92cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson private PowerManager.WakeLock mScreenWakeLock; 9355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private Handler mHandler; 948b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson 958b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson private static AlertDialog sConfirmDialog; 9655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 9755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private ShutdownThread() { 9855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 9955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 1006ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu /** 10155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * Request a clean shutdown, waiting for subsystems to clean up their 10255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * state etc. Must be called from a Looper thread in which its UI 10355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * is shown. 1046ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * 10555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * @param context Context used to display the shutdown progress dialog. 1066ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * @param confirm true if user confirmation is needed before shutting down. 10755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn */ 10855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn public static void shutdown(final Context context, boolean confirm) { 10919caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn mReboot = false; 11019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn mRebootSafeMode = false; 11119caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn shutdownInner(context, confirm); 11219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn } 11319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn 11419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn static void shutdownInner(final Context context, boolean confirm) { 11555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // ensure that only one thread is trying to power down. 11655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // any additional calls are just returned 117d67b236497d87223e8373d96c274c97cfbcab0cbMike Lockwood synchronized (sIsStartedGuard) { 11855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn if (sIsStarted) { 11955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn Log.d(TAG, "Request to shutdown already running, returning."); 12055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn return; 12155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 12255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 12355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 124d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato final int longPressBehavior = context.getResources().getInteger( 125d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato com.android.internal.R.integer.config_longPressOnPowerBehavior); 12619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn final int resourceId = mRebootSafeMode 12719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn ? com.android.internal.R.string.reboot_safemode_confirm 12819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn : (longPressBehavior == 2 12919caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn ? com.android.internal.R.string.shutdown_confirm_question 13019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn : com.android.internal.R.string.shutdown_confirm); 131d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato 132d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior); 13355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 13455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn if (confirm) { 135d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato final CloseDialogReceiver closer = new CloseDialogReceiver(context); 1368b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson if (sConfirmDialog != null) { 1378b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson sConfirmDialog.dismiss(); 1388b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson } 1398b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson sConfirmDialog = new AlertDialog.Builder(context) 14019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn .setTitle(mRebootSafeMode 14119caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn ? com.android.internal.R.string.reboot_safemode_title 14219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn : com.android.internal.R.string.power_off) 143d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato .setMessage(resourceId) 14455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() { 14555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn public void onClick(DialogInterface dialog, int which) { 14655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn beginShutdownSequence(context); 14755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 14855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn }) 14955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn .setNegativeButton(com.android.internal.R.string.no, null) 15055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn .create(); 1518b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson closer.dialog = sConfirmDialog; 1528b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson sConfirmDialog.setOnDismissListener(closer); 1538b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); 1548b4b63403a06e07dfc595aca45c778023bfec79bMattias Petersson sConfirmDialog.show(); 15555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } else { 15655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn beginShutdownSequence(context); 15755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 15855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 15955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 160d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato private static class CloseDialogReceiver extends BroadcastReceiver 161d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato implements DialogInterface.OnDismissListener { 162d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato private Context mContext; 163d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato public Dialog dialog; 164d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato 165d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato CloseDialogReceiver(Context context) { 166d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato mContext = context; 167d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 168d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato context.registerReceiver(this, filter); 169d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato } 170d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato 171d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato @Override 172d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato public void onReceive(Context context, Intent intent) { 173d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato dialog.cancel(); 174d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato } 175d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato 176d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato public void onDismiss(DialogInterface unused) { 177d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato mContext.unregisterReceiver(this); 178d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato } 179d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato } 180d208e709267f8af77690cb38dba2ae8e30ab5241Joe Onorato 1816ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu /** 1826ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * Request a clean shutdown, waiting for subsystems to clean up their 1836ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * state etc. Must be called from a Looper thread in which its UI 1846ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * is shown. 1856ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * 1866ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * @param context Context used to display the shutdown progress dialog. 1876ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * @param reason code to pass to the kernel (e.g. "recovery"), or null. 1886ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu * @param confirm true if user confirmation is needed before shutting down. 1896ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu */ 1906ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu public static void reboot(final Context context, String reason, boolean confirm) { 1916ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mReboot = true; 19219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn mRebootSafeMode = false; 1936ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mRebootReason = reason; 19419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn shutdownInner(context, confirm); 19519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn } 19619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn 19719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn /** 19819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn * Request a reboot into safe mode. Must be called from a Looper thread in which its UI 19919caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn * is shown. 20019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn * 20119caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn * @param context Context used to display the shutdown progress dialog. 20219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn * @param confirm true if user confirmation is needed before shutting down. 20319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn */ 20419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn public static void rebootSafeMode(final Context context, boolean confirm) { 20519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn mReboot = true; 20619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn mRebootSafeMode = true; 20719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn mRebootReason = null; 20819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn shutdownInner(context, confirm); 2096ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 2106ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu 21155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private static void beginShutdownSequence(Context context) { 21255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn synchronized (sIsStartedGuard) { 213d67b236497d87223e8373d96c274c97cfbcab0cbMike Lockwood if (sIsStarted) { 2148534a8e438ff35511051cf74f8f73d52c8b3b1f4Mathias Jeppsson Log.d(TAG, "Shutdown sequence already running, returning."); 215d67b236497d87223e8373d96c274c97cfbcab0cbMike Lockwood return; 216d67b236497d87223e8373d96c274c97cfbcab0cbMike Lockwood } 21755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn sIsStarted = true; 21855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 21955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 22055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // throw up an indeterminate system dialog to indicate radio is 22155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // shutting down. 22255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn ProgressDialog pd = new ProgressDialog(context); 22355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn pd.setTitle(context.getText(com.android.internal.R.string.power_off)); 22455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress)); 22555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn pd.setIndeterminate(true); 22655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn pd.setCancelable(false); 22755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); 22855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 22955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn pd.show(); 23055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 23155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn sInstance.mContext = context; 232f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 233cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson 234cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson // make sure we never fall asleep again 235cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mCpuWakeLock = null; 236cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson try { 237cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock( 238cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu"); 239cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mCpuWakeLock.setReferenceCounted(false); 240cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mCpuWakeLock.acquire(); 241cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson } catch (SecurityException e) { 242cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson Log.w(TAG, "No permission to acquire wake lock", e); 243cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mCpuWakeLock = null; 244cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson } 245cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson 246cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson // also make sure the screen stays on for better user experience 247cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mScreenWakeLock = null; 248f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn if (sInstance.mPowerManager.isScreenOn()) { 249f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn try { 250cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock( 251cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson PowerManager.FULL_WAKE_LOCK, TAG + "-screen"); 252cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mScreenWakeLock.setReferenceCounted(false); 253cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mScreenWakeLock.acquire(); 254f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn } catch (SecurityException e) { 255f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn Log.w(TAG, "No permission to acquire wake lock", e); 256cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson sInstance.mScreenWakeLock = null; 257f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn } 258f99ae76533119f9fef111abef17a3a8fcb8f12a5Dianne Hackborn } 259cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson 260cd4e4279804288a941c308b88df8bafa4f3f7458Mattias Larsson // start the thread that initiates shutdown 26155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn sInstance.mHandler = new Handler() { 26255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn }; 26355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn sInstance.start(); 26455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 26555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 2666ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu void actionDone() { 2676ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu synchronized (mActionDoneSync) { 2686ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mActionDone = true; 2696ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mActionDoneSync.notifyAll(); 27055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 27155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 2726ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu 27355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn /** 27455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * Makes sure we handle the shutdown gracefully. 27555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn * Shuts off power regardless of radio and bluetooth state if the alloted time has passed. 27655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn */ 27755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn public void run() { 27855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn BroadcastReceiver br = new BroadcastReceiver() { 27955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn @Override public void onReceive(Context context, Intent intent) { 28055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // We don't allow apps to cancel this, so ignore the result. 2816ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu actionDone(); 28255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 28355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn }; 284f547d679c058ed00de78a32146d04b75254df7ecKenny Root 285f547d679c058ed00de78a32146d04b75254df7ecKenny Root /* 286f547d679c058ed00de78a32146d04b75254df7ecKenny Root * Write a system property in case the system_server reboots before we 287f547d679c058ed00de78a32146d04b75254df7ecKenny Root * get to the actual hardware restart. If that happens, we'll retry at 288f547d679c058ed00de78a32146d04b75254df7ecKenny Root * the beginning of the SystemServer startup. 289f547d679c058ed00de78a32146d04b75254df7ecKenny Root */ 290f547d679c058ed00de78a32146d04b75254df7ecKenny Root { 291f547d679c058ed00de78a32146d04b75254df7ecKenny Root String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : ""); 292f547d679c058ed00de78a32146d04b75254df7ecKenny Root SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason); 293f547d679c058ed00de78a32146d04b75254df7ecKenny Root } 294f547d679c058ed00de78a32146d04b75254df7ecKenny Root 29519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn /* 29619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn * If we are rebooting into safe mode, write a system property 29719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn * indicating so. 29819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn */ 29919caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn if (mRebootSafeMode) { 30019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1"); 30119caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn } 30219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn 30355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn Log.i(TAG, "Sending shutdown broadcast..."); 30455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 30555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // First send the high-level shut down broadcast. 3066ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mActionDone = false; 307a81d7dace6e729a1f4f5dd3afc3d53c536e1996cMartin Wallgren Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 308a81d7dace6e729a1f4f5dd3afc3d53c536e1996cMartin Wallgren intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 309a81d7dace6e729a1f4f5dd3afc3d53c536e1996cMartin Wallgren mContext.sendOrderedBroadcastAsUser(intent, 3105ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn UserHandle.ALL, null, br, mHandler, 0, null, null); 31155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 312098e58da93f304d7d7791f193c6237870b94989dMike Lockwood final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME; 3136ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu synchronized (mActionDoneSync) { 3146ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu while (!mActionDone) { 315098e58da93f304d7d7791f193c6237870b94989dMike Lockwood long delay = endTime - SystemClock.elapsedRealtime(); 31655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn if (delay <= 0) { 31755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn Log.w(TAG, "Shutdown broadcast timed out"); 31855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn break; 31955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 32055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn try { 3216ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mActionDoneSync.wait(delay); 32255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } catch (InterruptedException e) { 32355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 32455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 32555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 32655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 32755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn Log.i(TAG, "Shutting down activity manager..."); 32855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 32955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn final IActivityManager am = 33055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn ActivityManagerNative.asInterface(ServiceManager.checkService("activity")); 33155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn if (am != null) { 33255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn try { 33355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn am.shutdown(MAX_BROADCAST_TIME); 33455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } catch (RemoteException e) { 33555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 33655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 33755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 338ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom Log.i(TAG, "Shutting down package manager..."); 339ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom 340ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom final PackageManagerService pm = (PackageManagerService) 341ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom ServiceManager.getService("package"); 342ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom if (pm != null) { 343ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom pm.shutdown(); 344ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom } 345ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom 3469631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie // Shutdown radios. 3479631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie shutdownRadios(MAX_RADIO_WAIT_TIME); 3489631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie 3499f7f7cad0b1fd7b096d65faf4b2352204403257eSan Mehat // Shutdown MountService to ensure media is in a safe state 3506ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu IMountShutdownObserver observer = new IMountShutdownObserver.Stub() { 3516ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu public void onShutDownComplete(int statusCode) throws RemoteException { 3526ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu Log.w(TAG, "Result code " + statusCode + " from MountService.shutdown"); 3536ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu actionDone(); 3546ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 3556ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu }; 3566ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu 3576ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu Log.i(TAG, "Shutting down MountService"); 358b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 3596ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu // Set initial variables and time out time. 3606ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mActionDone = false; 361098e58da93f304d7d7791f193c6237870b94989dMike Lockwood final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME; 3626ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu synchronized (mActionDoneSync) { 3636ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu try { 364b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown final IMountService mount = IMountService.Stub.asInterface( 365b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown ServiceManager.checkService("mount")); 3666ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu if (mount != null) { 3676ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mount.shutdown(observer); 3686ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } else { 3696ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu Log.w(TAG, "MountService unavailable for shutdown"); 3706ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 3716ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } catch (Exception e) { 3726ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu Log.e(TAG, "Exception during MountService shutdown", e); 3736ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 3746ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu while (!mActionDone) { 375098e58da93f304d7d7791f193c6237870b94989dMike Lockwood long delay = endShutTime - SystemClock.elapsedRealtime(); 3766ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu if (delay <= 0) { 3776ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu Log.w(TAG, "Shutdown wait timed out"); 3786ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu break; 3796ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 3806ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu try { 3816ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu mActionDoneSync.wait(delay); 3826ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } catch (InterruptedException e) { 3836ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 3846ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 3856ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu } 3866ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu 387f547d679c058ed00de78a32146d04b75254df7ecKenny Root rebootOrShutdown(mReboot, mRebootReason); 388f547d679c058ed00de78a32146d04b75254df7ecKenny Root } 389f547d679c058ed00de78a32146d04b75254df7ecKenny Root 390b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown private void shutdownRadios(int timeout) { 391b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown // If a radio is wedged, disabling it may hang so we do this work in another thread, 392b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown // just in case. 393b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown final long endTime = SystemClock.elapsedRealtime() + timeout; 394b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown final boolean[] done = new boolean[1]; 395b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Thread t = new Thread() { 396b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown public void run() { 397b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown boolean nfcOff; 398b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown boolean bluetoothOff; 399b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown boolean radioOff; 400b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 401b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown final INfcAdapter nfc = 402b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc")); 403b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown final ITelephony phone = 404b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown ITelephony.Stub.asInterface(ServiceManager.checkService("phone")); 4059631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie final IBluetoothManager bluetooth = 4069631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie IBluetoothManager.Stub.asInterface(ServiceManager.checkService( 4079631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE)); 408b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 409b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown try { 410b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown nfcOff = nfc == null || 411b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown nfc.getState() == NfcAdapter.STATE_OFF; 412b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (!nfcOff) { 413b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.w(TAG, "Turning off NFC..."); 414b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown nfc.disable(false); // Don't persist new state 415b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 416b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } catch (RemoteException ex) { 417b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.e(TAG, "RemoteException during NFC shutdown", ex); 418b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown nfcOff = true; 419b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 420b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 421b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown try { 4229631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie bluetoothOff = bluetooth == null || !bluetooth.isEnabled(); 423b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (!bluetoothOff) { 424b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.w(TAG, "Disabling Bluetooth..."); 425b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown bluetooth.disable(false); // disable but don't persist new state 426b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 427b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } catch (RemoteException ex) { 428b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.e(TAG, "RemoteException during bluetooth shutdown", ex); 429b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown bluetoothOff = true; 430b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 431b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 432b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown try { 433bd7723637b14d1895c043c2257f1cd9560322d4eNaveen Kalla radioOff = phone == null || !phone.needMobileRadioShutdown(); 434b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (!radioOff) { 435bd7723637b14d1895c043c2257f1cd9560322d4eNaveen Kalla Log.w(TAG, "Turning off cellular radios..."); 436bd7723637b14d1895c043c2257f1cd9560322d4eNaveen Kalla phone.shutdownMobileRadios(); 437b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 438b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } catch (RemoteException ex) { 439b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.e(TAG, "RemoteException during radio shutdown", ex); 440b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown radioOff = true; 441b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 442b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 443b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.i(TAG, "Waiting for NFC, Bluetooth and Radio..."); 444b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 445b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown while (SystemClock.elapsedRealtime() < endTime) { 446b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (!bluetoothOff) { 447b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown try { 4489631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie bluetoothOff = !bluetooth.isEnabled(); 449b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } catch (RemoteException ex) { 450b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.e(TAG, "RemoteException during bluetooth shutdown", ex); 451b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown bluetoothOff = true; 452b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 453b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (bluetoothOff) { 454b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.i(TAG, "Bluetooth turned off."); 455b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 456b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 457b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (!radioOff) { 458b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown try { 459bd7723637b14d1895c043c2257f1cd9560322d4eNaveen Kalla radioOff = !phone.needMobileRadioShutdown(); 460b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } catch (RemoteException ex) { 461b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.e(TAG, "RemoteException during radio shutdown", ex); 462b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown radioOff = true; 463b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 464b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (radioOff) { 465b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.i(TAG, "Radio turned off."); 466b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 467b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 468b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (!nfcOff) { 469b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown try { 470b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown nfcOff = nfc.getState() == NfcAdapter.STATE_OFF; 471b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } catch (RemoteException ex) { 472b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.e(TAG, "RemoteException during NFC shutdown", ex); 473b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown nfcOff = true; 474b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 475bd7723637b14d1895c043c2257f1cd9560322d4eNaveen Kalla if (nfcOff) { 476b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.i(TAG, "NFC turned off."); 477b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 478b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 479b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 480b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (radioOff && bluetoothOff && nfcOff) { 481b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete."); 482b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown done[0] = true; 483b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown break; 484b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 485b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC); 486b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 487b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 488b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown }; 489b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 490b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown t.start(); 491b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown try { 492b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown t.join(timeout); 493b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } catch (InterruptedException ex) { 494b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 495b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown if (!done[0]) { 496b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown Log.w(TAG, "Timed out waiting for NFC, Radio and Bluetooth shutdown."); 497b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 498b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown } 499b8203719bd037b39d12413f54d546e9ecc9e4872Jeff Brown 500f547d679c058ed00de78a32146d04b75254df7ecKenny Root /** 501f547d679c058ed00de78a32146d04b75254df7ecKenny Root * Do not call this directly. Use {@link #reboot(Context, String, boolean)} 502f547d679c058ed00de78a32146d04b75254df7ecKenny Root * or {@link #shutdown(Context, boolean)} instead. 503f547d679c058ed00de78a32146d04b75254df7ecKenny Root * 504f547d679c058ed00de78a32146d04b75254df7ecKenny Root * @param reboot true to reboot or false to shutdown 505f547d679c058ed00de78a32146d04b75254df7ecKenny Root * @param reason reason for reboot 506f547d679c058ed00de78a32146d04b75254df7ecKenny Root */ 507f547d679c058ed00de78a32146d04b75254df7ecKenny Root public static void rebootOrShutdown(boolean reboot, String reason) { 508f547d679c058ed00de78a32146d04b75254df7ecKenny Root if (reboot) { 509f547d679c058ed00de78a32146d04b75254df7ecKenny Root Log.i(TAG, "Rebooting, reason: " + reason); 510dbcf2d7482562eff45ac727cea799b37a260e399Nick Kralevich PowerManagerService.lowLevelReboot(reason); 511dbcf2d7482562eff45ac727cea799b37a260e399Nick Kralevich Log.e(TAG, "Reboot failed, will attempt shutdown instead"); 512a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood } else if (SHUTDOWN_VIBRATE_MS > 0) { 513a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood // vibrate before shutting down 514c2346134bb519a54d50655cbef940fc3fdec60a9Jeff Brown Vibrator vibrator = new SystemVibrator(); 51526e9cf38b229b738b4e56c3e08be82a9c0f11e64Brad Fitzpatrick try { 5167b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES); 51726e9cf38b229b738b4e56c3e08be82a9c0f11e64Brad Fitzpatrick } catch (Exception e) { 51826e9cf38b229b738b4e56c3e08be82a9c0f11e64Brad Fitzpatrick // Failure to vibrate shouldn't interrupt shutdown. Just log it. 51926e9cf38b229b738b4e56c3e08be82a9c0f11e64Brad Fitzpatrick Log.w(TAG, "Failed to vibrate during shutdown.", e); 52026e9cf38b229b738b4e56c3e08be82a9c0f11e64Brad Fitzpatrick } 52126e9cf38b229b738b4e56c3e08be82a9c0f11e64Brad Fitzpatrick 522a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood // vibrator is asynchronous so we need to wait to avoid shutting down too soon. 523a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood try { 524a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood Thread.sleep(SHUTDOWN_VIBRATE_MS); 525e331644cb570e74a8739cb21ffcc5875663ffa58Brad Fitzpatrick } catch (InterruptedException unused) { 526a717f64ddcdce44379b24616333a58a6df2fcca5Mike Lockwood } 5279f7f7cad0b1fd7b096d65faf4b2352204403257eSan Mehat } 5289f7f7cad0b1fd7b096d65faf4b2352204403257eSan Mehat 5296ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapu // Shutdown power 53055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn Log.i(TAG, "Performing low-level shutdown..."); 5317304c343821309dd15f769b18f1de2fa43751573Jeff Brown PowerManagerService.lowLevelShutdown(); 53255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 53355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn} 534