Android 4.4 系统关机流程

代码路径:
frameworks/base/services/java/com/android/server/power/PowerManagerService.java
frameworks/base/services/java/com/android/server/power/ShutdownThread.java
日志关键TAG:ShutdownThread、PowerManagerService
在应用层调用shutdown()方法进行关机

private void shutdown() {
   log("shutdown()");
   try {
      IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
            if (power != null) {
                power.shutdown(false, false);
            }
       } catch (RemoteException doe) {
           log("shutdown() RemoteException:"+doe.getMessage());
        }
}

在/PowerManagerService.java文件中shutdown()方法进行关机

/**
 * Shuts down the device.
 *
 * @param confirm If true, shows a shutdown confirmation dialog.
 * @param wait If true, this call waits for the shutdown to complete and does not return.
 */
@Override // Binder call
public void shutdown(boolean confirm, boolean wait) {
    mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

    final long ident = Binder.clearCallingIdentity();
    try {
        shutdownOrRebootInternal(true, confirm, null, wait);
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}

在/PowerManagerService.java文件中shutdownOrRebootInternal()方法中处理关机和重启

private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
        final String reason, boolean wait) {
    if (mHandler == null || !mSystemReady) {
        throw new IllegalStateException("Too early to call shutdown() or reboot()");
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                if (shutdown) {
                    ShutdownThread.shutdown(mContext, confirm);
                } else {
                    ShutdownThread.reboot(mContext, reason, confirm);
                }
            }
        }
    };

    // ShutdownThread must run on a looper capable of displaying the UI.
    Message msg = Message.obtain(mHandler, runnable);
    msg.setAsynchronous(true);
    mHandler.sendMessage(msg);

    // PowerManager.reboot() is documented not to return so just wait for the inevitable.
    if (wait) {
        synchronized (runnable) {
            while (true) {
                try {
                    runnable.wait();
                } catch (InterruptedException e) {
                }
            }
        }
    }
}

在ShutdownThread.java文件中最终调用shutdownInner函数进行关机

public static void shutdown(final Context context, boolean confirm) {
    mReboot = false;
    mRebootSafeMode = false;
    // SPRD: add log for debug @{
    Slog.i(TAG, "shutdown goto shutdownInner");
    // @}
    shutdownInner(context, confirm);
    
}

在ShutdownThread.java文件中shutdownInner方法中,如果confirm变量为true,则会弹出关机对话框,如果为false就不弹出,就执行beginShutdownSequence()方法

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;
        }
    }

    final int longPressBehavior = context.getResources().getInteger(
                    com.android.internal.R.integer.config_longPressOnPowerBehavior);
    final int resourceId = 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);

    final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    if (confirm) {
        final CloseDialogReceiver closer = new CloseDialogReceiver(context);
        if (sConfirmDialog != null) {
            sConfirmDialog.dismiss();
        }
        sConfirmDialog = new AlertDialog.Builder(context)
                .setTitle(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) {
                        /* SPRD: add for apct functions @{ */
                        if (APCTOption.self().isApctPowerOffSupport())
                        {
                            if (!mRebootSafeMode) {
                                shutdownBeginTime = System.currentTimeMillis();
                            }
                        }

                                final Runnable shutDownRun = new Runnable() {
                                    @Override
                                    public void run() {
                                        Slog.i(TAG, "shutdownInner goto beginShutdownSequence");
                                        beginShutdownSequence(context);
                                    }
                                };
                                final Handler handler = new Handler();
                                if (tm.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
                                    final PhoneStateListener listener = new PhoneStateListener(){
                                        @Override
                                        public void onCallStateChanged(int state,String incomingNumber) {
                                            if(tm.getCallState() == TelephonyManager.CALL_STATE_IDLE){
                                                try {
                                                    Thread.currentThread().sleep(1500);
                                                } catch (InterruptedException e) {
                                                    e.printStackTrace();
                                                }
                                                //now the system is shutdown, we may not listen to none.
                                                handler.removeCallbacks(shutDownRun);
                                                shutDownRun.run();
                                            }
                                        }
                                    };
                                    tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
                                    tm.endCall();
                                    handler.postDelayed(shutDownRun, 3500);
                                    return;
                                }
                        /* @} */
                        // SPRD: add log for debug @{
                        Slog.i(TAG, "shutdownInner goto beginShutdownSequence");
                        // @}
                        beginShutdownSequence(context);
                    }
                })
                .setNegativeButton(com.android.internal.R.string.no, null)
                .create();
        closer.dialog = sConfirmDialog;
        sConfirmDialog.setOnDismissListener(closer);
        sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        sConfirmDialog.show();
    } else {
        beginShutdownSequence(context);
    }
}

在ShutdownThread.java文件中beginShutdownSequence方法中通过Runtime类中exec方法输入shutdown命令进行关机

private static void beginShutdownSequence(Context context) {
      synchronized (sIsStartedGuard) {
          if (sIsStarted) {
              Log.d(TAG, "Shutdown sequence already running, returning.");
              return;
          }
          sIsStarted = true;
      }


      ProgressDialog 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);
      // SPRD: remove origin code
      // pd.show();
      shutdownTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_TIME;

      for(int i = 0;i<boardname.length;i++){
if(SystemProperties.get("ro.product.board").equals(boardname[i])){
   isLteBoard = true;
   break;
}
      }
     
      {
          IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
          try {
              wm.setForceOrientation(0);
          } catch (RemoteException e) {
              Log.e(TAG, "stop orientation failed!", e);
          }
          // @}

          String[] bootcmd = {"bootanimation", "shutdown"} ;
          try {
              Log.i(TAG, "exec the bootanimation ");
              SystemProperties.set("service.bootanim.exit", "0");
              Runtime.getRuntime().exec(bootcmd);
          } catch (Exception e){
              Log.e(TAG,"bootanimation command exe err!");
          }
      }
      /* @} */
      sInstance.mContext = context;
      sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);

      // SPRD: call scheduleButtonTimeout(long now).
      sInstance.mPowerManager.scheduleButtonLightTimeout(SystemClock.uptimeMillis());
      // 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;
      }

      // 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;
          }
      }
      disableAcc();

      // start the thread that initiates shutdown
      sInstance.mHandler = new Handler() {
      };
      sInstance.start();
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值