国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 互联网 > Android在关机界面添加重启功能

Android在关机界面添加重启功能

来源:程序员人生   发布时间:2014-11-09 10:53:31 阅读次数:5014次

Google原生的Android系统1般是没有“重启”这个选项的。有时候重启也是不可或缺的1个Feature,那末如何在源码环境下添加这个选项呢?


1. 在frameworksasecore es esvaluesstrings.xml
中添加标签:

<span style="font-size:14px;"><!--zms add start--> <!-- label for item that power reboot in phone options dialog --> <string name="zzzzz_global_action_power_reboot">Reboot</string> <!--zms add end--></span>

固然这只是英语语系的,需要添加其它语系的标示,把"Reboot" 替换成其它语言。


2. 在alpsframeworksasecore es esdrawable-hdpi 中添加图标:
zzzzz_ic_lock_power_reboot.png


3. 打开frameworkspoliciesasephonecomandroidinternalpolicyimplGlobalActions.java
大概在这个文件的261行有这样的代码:

mItems = Lists.newArrayList( // silent mode mSilentModeToggle, // next: airplane mode mAirplaneModeOn, // last: power off

在这里,我们添加power reboot 的新的item.
具体这个mItems 更新为以下:
mItems = Lists.newArrayList( // silent mode mSilentModeToggle, // next: airplane mode mAirplaneModeOn, // last: power off new SinglePressAction( com.android.internal.R.drawable.ic_lock_power_off, R.string.global_action_power_off) { public void onPress() { // shutdown by making sure radio and power are handled accordingly. ShutdownThread.shutdown(mContext, true); } public boolean showDuringKeyguard() { return true; } public boolean showBeforeProvisioning() { return true; } }//zms add start , new SinglePressAction( com.android.internal.R.drawable.zzzzz_ic_lock_power_reboot, R.string.zzzzz_global_action_power_reboot) { public void onPress() { // reboot by making sure radio and power are handled accordingly. ShutdownThread.reboot(mContext, null, true); } public boolean showDuringKeyguard() { return true; } public boolean showBeforeProvisioning() { return true; } } //zms add end. );


经过这样的添加/修改后,这项feature 便可运行。
注意如果测试的话,由于有修改framework 中的文件,最好new 1下全部工程。
另外还需要修改1下ShutdownThread.java 中的那个dialog 显示描写,不然将照旧看到“关机”的信息。

位置:frameworks/base/services/java/com/android/server/power/ShutdownThread.java

不同版本的代码位置可能有所差别,可以在根目录下find1下:

find -name ShutdownThread.java

参照以下文件便可:

package com.android.server.power; import android.app.ActivityManagerNative; import android.app.AlertDialog; import android.app.Dialog; import android.app.IActivityManager; import android.app.ProgressDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.IBluetoothManager; import android.nfc.NfcAdapter; import android.nfc.INfcAdapter; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.Vibrator; import android.os.SystemVibrator; import android.os.storage.IMountService; import android.os.storage.IMountShutdownObserver; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.view.Surface; import android.net.ConnectivityManager; import com.android.internal.telephony.ITelephony; import com.android.server.power.PowerManagerService; import android.util.Log; import android.view.WindowManager; import android.view.IWindowManager; // Wakelock import android.os.PowerManager.WakeLock; // For IPO import com.android.internal.app.ShutdownManager; import com.mediatek.common.featureoption.FeatureOption; import android.provider.Settings; import com.mediatek.common.bootanim.IBootAnimExt; import com.mediatek.common.MediatekClassFactory; import com.mediatek.common.hdmi.IHDMINative; // add for HDMI power control import dalvik.system.Zygote; public final class ShutdownThread extends Thread { // constants private static final String TAG = "ShutdownThread"; private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500; // maximum time we wait for the shutdown broadcast before going on. private static final int MAX_BROADCAST_TIME = 10*1000; private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000; private static final int MAX_RADIO_WAIT_TIME = 12*1000; // length of vibration before shutting down private static final int SHUTDOWN_VIBRATE_MS = 500; // state tracking private static Object sIsStartedGuard = new Object(); private static boolean sIsStarted = false; private static boolean mReboot; private static boolean mRebootSafeMode; private static String mRebootReason; // Provides shutdown assurance in case the system_server is killed public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested"; // Indicates whether we are rebooting into safe mode public static final String REBOOT_SAFEMODE_PROPERTY = "persist.sys.safemode"; // static instance of this thread private static final ShutdownThread sInstance = new ShutdownThread(); private final Object mActionDoneSync = new Object(); private boolean mActionDone; private Context mContext; private PowerManager mPowerManager; private PowerManager.WakeLock mCpuWakeLock; private PowerManager.WakeLock mScreenWakeLock; private Handler mHandler; private static AlertDialog sConfirmDialog = null; // IPO private static ProgressDialog pd = null; private static Object mShutdownThreadSync = new Object(); private ShutdownManager stMgr = new ShutdownManager(); // Shutdown Flow Settings private static final int NORMAL_SHUTDOWN_FLOW = 0x0; private static final int IPO_SHUTDOWN_FLOW = 0x1; private static int mShutdownFlow; // Shutdown Animation private static final int MIN_SHUTDOWN_ANIMATION_PLAY_TIME = 5*1000; // CU/CMCC operator require 3⑸s private static long beginAnimationTime = 0; private static long endAnimationTime = 0; private static boolean bConfirmForAnimation = true; private static boolean bPlayaudio = true; private static final Object mEnableAnimatingSync = new Object(); private static boolean mEnableAnimating = true; // length of waiting for memory dump if Modem Exception occurred private static final int MAX_MEMORY_DUMP_TIME = 60 * 1000; private static String command; //for bypass radioOff private static int screen_turn_off_time = 5 * 1000; //after 5sec the screen become OFF, you can change the time delay private static IHDMINative ImHDMI = null; // for MFR private static final boolean mSpew = true; //debug enable private static IBootAnimExt mIBootAnim = null; // for boot animation private ShutdownThread() { } public static boolean isPowerOffDialogShowing() { return (sConfirmDialog != null && sConfirmDialog.isShowing()); } public static void EnableAnimating(boolean enable) { synchronized (mEnableAnimatingSync) { mEnableAnimating = enable; } } /** * Request a clean shutdown, waiting for subsystems to clean up their * state etc. Must be called from a Looper thread in which its UI * is shown. * * @param context Context used to display the shutdown progress dialog. * @param confirm true if user confirmation is needed before shutting down. */ public static void shutdown(final Context context, boolean confirm) { mReboot = false; mRebootSafeMode = false; Log.d(TAG, "!!! Request to shutdown !!!"); ShutdownManager.startFtraceCapture(); if (mSpew) { StackTraceElement[] stack = new Throwable().getStackTrace(); for (StackTraceElement element : stack) { Log.d(TAG, " |----" + element.toString()); } } createPreShutdownApi(context); if (SystemProperties.getBoolean("ro.monkey", false)) { Log.d(TAG, "Cannot request to shutdown when Monkey is running, returning."); return; } shutdownInner(context, confirm); } static void shutdownInner(final Context context, boolean confirm) { // ensure that only one thread is trying to power down. // any additional calls are just returned synchronized (sIsStartedGuard) { if (sIsStarted) { Log.d(TAG, "Request to shutdown already running, returning."); return; } } Log.d(TAG, "Notifying thread to start radio shutdown"); bConfirmForAnimation = confirm; final int longPressBehavior = context.getResources().getInteger( com.android.internal.R.integer.config_longPressOnPowerBehavior); final int resourceId = (mReboot && !mRebootSafeMode) ? com.android.internal.R.string.reboot_confirm : (mRebootSafeMode ? com.android.internal.R.string.reboot_safemode_confirm : (longPressBehavior == 2 ? com.android.internal.R.string.shutdown_confirm_question : com.android.internal.R.string.shutdown_confirm)); Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior); if (confirm) { final CloseDialogReceiver closer = new CloseDialogReceiver(context); if (sConfirmDialog != null) { sConfirmDialog.dismiss(); } if (sConfirmDialog == null) { Log.d(TAG, "PowerOff dialog doesn't exist. Create it first"); sConfirmDialog = new AlertDialog.Builder(context) .setTitle((mReboot && !mRebootSafeMode) ? com.android.internal.R.string.reboot_title : (mRebootSafeMode ? com.android.internal.R.string.reboot_safemode_title : com.android.internal.R.string.power_off)) .setMessage(resourceId) .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { beginShutdownSequence(context); if (sConfirmDialog != null) { sConfirmDialog = null; } } }) .setNegativeButton(com.android.internal.R.string.no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { synchronized (sIsStartedGuard) { sIsStarted = false; } if (sConfirmDialog != null) { sConfirmDialog = null; } } }) .create(); sConfirmDialog.setCancelable(false);//blocking back key sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); /*if (!context.getResources().getBoolean( com.android.internal.R.bool.config_sf_slowBlur)) { sConfirmDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); }*/ /* To fix video+UI+blur flick issue */ sConfirmDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } closer.dialog = sConfirmDialog; sConfirmDialog.setOnDismissListener(closer); if (!sConfirmDialog.isShowing()) { sConfirmDialog.show(); } } else { beginShutdownSequence(context); } } private static class CloseDialogReceiver extends BroadcastReceiver implements DialogInterface.OnDismissListener { private Context mContext; public Dialog dialog; CloseDialogReceiver(Context context) { mContext = context; IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(this, filter); } @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "CloseDialogReceiver: onReceive"); dialog.cancel(); } public void onDismiss(DialogInterface unused) { mContext.unregisterReceiver(this); } } private static Runnable mDelayDim = new Runnable() { //use for animation, add by how.wang public void run() { Log.d(TAG, "setBacklightBrightness: Off"); if (sInstance.mScreenWakeLock != null && sInstance.mScreenWakeLock.isHeld()) { sInstance.mScreenWakeLock.release(); sInstance.mScreenWakeLock = null; } sInstance.mPowerManager.setBacklightBrightnessOff(true); } }; /** * Request a clean shutdown, waiting for subsystems to clean up their * state etc. Must be called from a Looper thread in which its UI * is shown. * * @param context Context used to display the shutdown progress dialog. * @param reason code to pass to the kernel (e.g. "recovery"), or null. * @param confirm true if user confirmation is needed before shutting down. */ public static void reboot(final Context context, String reason, boolean confirm) { mReboot = true; mRebootSafeMode = false; mRebootReason = reason; Log.d(TAG, "reboot"); if (mSpew) { StackTraceElement[] stack = new Throwable().getStackTrace(); for (StackTraceElement element : stack) { Log.d(TAG, " |----" + element.toString()); } } shutdownInner(context, confirm); } /** * Request a reboot into safe mode. Must be called from a Looper thread in which its UI * is shown. * * @param context Context used to display the shutdown progress dialog. * @param confirm true if user confirmation is needed before shutting down. */ public static void rebootSafeMode(final Context context, boolean confirm) { mReboot = true; mRebootSafeMode = true; mRebootReason = null; Log.d(TAG, "rebootSafeMode"); shutdownInner(context, confirm); } private static void beginShutdownSequence(Context context) { synchronized (sIsStartedGuard) { if (sIsStarted) { Log.d(TAG, "Shutdown sequence already running, returning."); return; } sIsStarted = true; } // start the thread that initiates shutdown sInstance.mContext = context; sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); sInstance.mHandler = new Handler() { }; bPlayaudio = true; if (!bConfirmForAnimation) { if (!sInstance.mPowerManager.isScreenOn()) { bPlayaudio = false; } } // throw up an indeterminate system dialog to indicate radio is // shutting down. beginAnimationTime = 0; boolean mShutOffAnimation = false; try { if (mIBootAnim == null) { mIBootAnim = MediatekClassFactory.createInstance(IBootAnimExt.class); } } catch (Exception e) { e.printStackTrace(); } int screenTurnOffTime = mIBootAnim.getScreenTurnOffTime(); mShutOffAnimation = mIBootAnim.isCustBootAnim(); Log.e(TAG, "mIBootAnim get screenTurnOffTime : " + screenTurnOffTime); String cust = SystemProperties.get("ro.operator.optr"); if (cust != null) { if (cust.equals("CUST")) { mShutOffAnimation = true; } } synchronized (mEnableAnimatingSync) { if(!mEnableAnimating) { //sInstance.mPowerManager.setBacklightBrightness(PowerManager.BRIGHTNESS_DIM); } else { if (mShutOffAnimation) { Log.e(TAG, "mIBootAnim.isCustBootAnim() is true"); bootanimCust(); } else { pd = new ProgressDialog(context); pd.setTitle(context.getText(com.android.internal.R.string.power_off)); pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress)); pd.setIndeterminate(true); pd.setCancelable(false); pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); /* To fix video+UI+blur flick issue */ pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); pd.show(); } sInstance.mHandler.postDelayed(mDelayDim, screenTurnOffTime); } } // make sure we never fall asleep again sInstance.mCpuWakeLock = null; try { sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu"); sInstance.mCpuWakeLock.setReferenceCounted(false); sInstance.mCpuWakeLock.acquire(); } catch (SecurityException e) { Log.w(TAG, "No permission to acquire wake lock", e); sInstance.mCpuWakeLock = null; } Log.d(TAG, "shutdown acquire partial WakeLock: cpu"); // also make sure the screen stays on for better user experience sInstance.mScreenWakeLock = null; if (sInstance.mPowerManager.isScreenOn()) { try { sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock( PowerManager.FULL_WAKE_LOCK, TAG + "-screen"); sInstance.mScreenWakeLock.setReferenceCounted(false); sInstance.mScreenWakeLock.acquire(); } catch (SecurityException e) { Log.w(TAG, "No permission to acquire wake lock", e); sInstance.mScreenWakeLock = null; } } // start the thread that initiates shutdown if (sInstance.getState() != Thread.State.NEW || sInstance.isAlive()) { if (mShutdownFlow == IPO_SHUTDOWN_FLOW) { Log.d(TAG, "ShutdownThread exists already"); checkShutdownFlow(); synchronized (mShutdownThreadSync) { mShutdownThreadSync.notify(); } } else { Log.e(TAG, "Thread state is not normal! froce to shutdown!"); delayForPlayAnimation(); //unmout data/cache partitions while performing shutdown //Power.shutdown(); SystemProperties.set("ctl.start", "shutdown"); } } else { sInstance.start(); } } private static void bootanimCust() { // [MTK] fix shutdown animation timing issue //================================================================== SystemProperties.set("service.shutanim.running","0"); Log.i(TAG, "set service.shutanim.running to 0"); //================================================================== boolean isRotaionEnabled = false; try { isRotaionEnabled = Settings.System.getInt(sInstance.mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 1) != 0; if (isRotaionEnabled) { final IWindowManager wm = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); wm.freezeRotation(Surface.ROTATION_0); Settings.System.putInt(sInstance.mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0); Settings.System.putInt(sInstance.mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION_RESTORE, 1); } } catch (NullPointerException ex) { Log.e(TAG, "check Rotation: sInstance.mContext object is null when get Rotation"); } catch (RemoteException e) { } beginAnimationTime = SystemClock.elapsedRealtime() + MIN_SHUTDOWN_ANIMATION_PLAY_TIME; // +MediaTek 2012-02⑵5 Disable key dispatch try { final IWindowManager wm = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); wm.setEventDispatching(false); } catch (RemoteException e) {} // -MediaTek 2012-02⑵5 Disable key dispatch startBootAnimation(); } private static void startBootAnimation() { try { SystemProperties.set("service.bootanim.exit","0"); Log.d(TAG, "Set 'service.bootanim.exit' = 0)."); } catch (Exception ex) { Log.e(TAG, "Failed to set 'service.bootanim.exit' = 0)."); } if (bPlayaudio) { SystemProperties.set("ctl.start","bootanim:shut mp3"); Log.d(TAG, "bootanim:shut mp3" ); } else { SystemProperties.set("ctl.start","bootanim:shut nomp3"); Log.d(TAG, "bootanim:shut nomp3" ); } } void actionDone() { synchronized (mActionDoneSync) { mActionDone = true; mActionDoneSync.notifyAll(); } } private static void delayForPlayAnimation() { if (beginAnimationTime <= 0) { return; } endAnimationTime = beginAnimationTime - SystemClock.elapsedRealtime(); if (endAnimationTime > 0) { try { Thread.currentThread().sleep(endAnimationTime); } catch ( Exception e) { Log.e(TAG, "Shutdown stop bootanimation Thread.currentThread().sleep exception!"); } } } /* * Please make sure that context object is already instantiated already before calling this method. * However, we'll still catch null pointer exception here in case. */ private static void checkShutdownFlow() { Log.d(TAG, "checkShutdownFlow: IPO_Support=" + FeatureOption.MTK_IPO_SUPPORT + " mReboot=" + mReboot); if (FeatureOption.MTK_IPO_SUPPORT == false || mReboot == true || Zygote.systemInSafeMode == true) { mShutdownFlow = NORMAL_SHUTDOWN_FLOW; return; } boolean isIPOEnabled; try { isIPOEnabled = Settings.System.getInt(sInstance.mContext.getContentResolver(), Settings.System.IPO_SETTING, 1) == 1; } catch (NullPointerException ex) { Log.e(TAG, "checkShutdownFlow: sInstance.mContext object is null when get IPO enable/disable Option"); mShutdownFlow = NORMAL_SHUTDOWN_FLOW; return; } if (isIPOEnabled == true) { if ("1".equals(SystemProperties.get("sys.ipo.battlow"))) mShutdownFlow = NORMAL_SHUTDOWN_FLOW; else mShutdownFlow = IPO_SHUTDOWN_FLOW; } else { mShutdownFlow = NORMAL_SHUTDOWN_FLOW; } // power off auto test, don't modify Log.d(TAG, "checkShutdownFlow: isIPOEnabled=" + isIPOEnabled + " mShutdownFlow=" + mShutdownFlow); return; } /** * Makes sure we handle the shutdown gracefully. * Shuts off power regardless of radio and bluetooth state if the alloted time has passed. */ public void run() { checkShutdownFlow(); while (mShutdownFlow == IPO_SHUTDOWN_FLOW) { stMgr.saveStates(mContext); stMgr.enterShutdown(mContext); running(); } if (mShutdownFlow != IPO_SHUTDOWN_FLOW) { stMgr.enterShutdown(mContext); running(); } } public void running() { if(sPreShutdownApi != null){ try { sPreShutdownApi.onPowerOff(); } catch (RemoteException e) { Log.e(TAG, "onPowerOff exception" + e.getMessage()); } }else{ Log.w(TAG, "sPreShutdownApi is null"); } command = SystemProperties.get("sys.ipo.pwrdncap"); BroadcastReceiver br = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // We don't allow apps to cancel this, so ignore the result. actionDone(); } }; /* * Write a system property in case the system_server reboots before we * get to the actual hardware restart. If that happens, we'll retry at * the beginning of the SystemServer startup. */ { String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : ""); SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason); } /* * If we are rebooting into safe mode, write a system property * indicating so. */ if (mRebootSafeMode) { SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1"); } Log.i(TAG, "Sending shutdown broadcast..."); // First send the high-level shut down broadcast. mActionDone = false; /// M: 2012-05⑵0 ALPS00286063 @{ mContext.sendBroadcast(new Intent("android.intent.action.ACTION_PRE_SHUTDOWN")); /// @} 2012-05⑵0 mContext.sendOrderedBroadcastAsUser((new Intent()).setAction(Intent.ACTION_SHUTDOWN).putExtra("_mode", mShutdownFlow), UserHandle.ALL, null, br, mHandler, 0, null, null); final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME; synchronized (mActionDoneSync) { while (!mActionDone) { long delay = endTime - SystemClock.elapsedRealtime(); if (delay <= 0) { Log.w(TAG, "Shutdown broadcast ACTION_SHUTDOWN timed out"); if (mShutdownFlow == IPO_SHUTDOWN_FLOW) { Log.d(TAG, "change shutdown flow from ipo to normal: ACTION_SHUTDOWN timeout"); mShutdownFlow = NORMAL_SHUTDOWN_FLOW; } break; } try { mActionDoneSync.wait(delay); } catch (InterruptedException e) { } } } // Also send ACTION_SHUTDOWN_IPO in IPO shut down flow if (mShutdownFlow == IPO_SHUTDOWN_FLOW) { mActionDone = false; mContext.sendOrderedBroadcast(new Intent("android.intent.action.ACTION_SHUTDOWN_IPO"), null, br, mHandler, 0, null, null); final long endTimeIPO = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME; synchronized (mActionDoneSync) { while (!mActionDone) { long delay = endTimeIPO - SystemClock.elapsedRealtime(); if (delay <= 0) { Log.w(TAG, "Shutdown broadcast ACTION_SHUTDOWN_IPO timed out"); if (mShutdownFlow == IPO_SHUTDOWN_FLOW) { Log.d(TAG, "change shutdown flow from ipo to normal: ACTION_SHUTDOWN_IPO timeout"); mShutdownFlow = NORMAL_SHUTDOWN_FLOW; } break; } try { mActionDoneSync.wait(delay); } catch (InterruptedException e) { } } } } if (mShutdownFlow != IPO_SHUTDOWN_FLOW) { // power off auto test, don't modify Log.i(TAG, "Shutting down activity manager..."); final IActivityManager am = ActivityManagerNative.asInterface(ServiceManager.checkService("activity")); if (am != null) { try { am.shutdown(MAX_BROADCAST_TIME); } catch (RemoteException e) { } } } // power off auto test, don't modify // Shutdown radios. Log.i(TAG, "Shutting down radios..."); shutdownRadios(MAX_RADIO_WAIT_TIME); // power off auto test, don't modify Log.i(TAG, "Shutting down MountService..."); if ( (mShutdownFlow == IPO_SHUTDOWN_FLOW) && (command.equals("1")||command.equals("3")) ) { Log.i(TAG, "bypass MountService!"); } else { // Shutdown MountService to ensure media is in a safe state IMountShutdownObserver observer = new IMountShutdownObserver.Stub() { public void onShutDownComplete(int statusCode) throws RemoteException { Log.w(TAG, "Result code " + statusCode + " from MountService.shutdown"); if (statusCode < 0) { mShutdownFlow = NORMAL_SHUTDOWN_FLOW; } actionDone(); } }; // Set initial variables and time out time. mActionDone = false; final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME; synchronized (mActionDoneSync) { try { final IMountService mount = IMountService.Stub.asInterface( ServiceManager.checkService("mount")); if (mount != null) { mount.shutdown(observer); } else { Log.w(TAG, "MountService unavailable for shutdown"); } } catch (Exception e) { Log.e(TAG, "Exception during MountService shutdown", e); } while (!mActionDone) { long delay = endShutTime - SystemClock.elapsedRealtime(); if (delay <= 0) { Log.w(TAG, "Shutdown wait timed out"); if (mShutdownFlow == IPO_SHUTDOWN_FLOW) { Log.d(TAG, "change shutdown flow from ipo to normal: MountService"); mShutdownFlow = NORMAL_SHUTDOWN_FLOW; } break; } try { mActionDoneSync.wait(delay); } catch (InterruptedException e) { } } } } // power off auto test, don't modify //mountSerivce Log.i(TAG, "MountService shut done.
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生