private void performPendingShutdown() {
    final String shutdownAction = SystemProperties.get(ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
    if (shutdownAction != null && shutdownAction.length() > 0) {
      boolean reboot = (shutdownAction.charAt(0) == '1');

      final String reason;
      if (shutdownAction.length() > 1) {
        reason = shutdownAction.substring(1, shutdownAction.length());
      } else {
        reason = null;
      }

      ShutdownThread.rebootOrShutdown(null, reboot, reason);
    }
  }
예제 #2
0
  /**
   * 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() {
    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;
    mContext.sendOrderedBroadcastAsUser(
        new Intent(Intent.ACTION_SHUTDOWN), 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 timed out");
          break;
        }
        try {
          mActionDoneSync.wait(delay);
        } catch (InterruptedException e) {
        }
      }
    }

    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) {
      }
    }

    // Shutdown radios.
    shutdownRadios(MAX_RADIO_WAIT_TIME);

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

    Log.i(TAG, "Shutting down MountService");

    // 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");
          break;
        }
        try {
          mActionDoneSync.wait(delay);
        } catch (InterruptedException e) {
        }
      }
    }

    rebootOrShutdown(mReboot, mRebootReason);
  }