Ejemplo n.º 1
0
  /**
   * Turn on or off the mobile radio. No connectivity will be possible while the radio is off. The
   * operation is a no-op if the radio is already in the desired state.
   *
   * @param turnOn {@code true} if the radio should be turned on, {@code false} if
   */
  public boolean setRadio(boolean turnOn) {
    getPhoneService(false);
    /*
     * If the phone process has crashed in the past, we'll get a
     * RemoteException and need to re-reference the service.
     */
    for (int retry = 0; retry < 2; retry++) {
      if (mPhoneService == null) {
        loge("Ignoring mobile radio request because could not acquire PhoneService");
        break;
      }

      try {
        return mPhoneService.setRadio(turnOn);
      } catch (RemoteException e) {
        if (retry == 0) getPhoneService(true);
      }
    }

    loge("Could not set radio power to " + (turnOn ? "on" : "off"));
    return false;
  }
  /**
   * 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() {
    boolean bluetoothOff;
    boolean radioOff;

    BroadcastReceiver br =
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            // We don't allow apps to cancel this, so ignore the result.
            broadcastDone();
          }
        };

    Log.i(TAG, "Sending shutdown broadcast...");

    // First send the high-level shut down broadcast.
    mBroadcastDone = false;
    mContext.sendOrderedBroadcast(
        new Intent(Intent.ACTION_SHUTDOWN), null, br, mHandler, 0, null, null);

    final long endTime = System.currentTimeMillis() + MAX_BROADCAST_TIME;
    synchronized (mBroadcastDoneSync) {
      while (!mBroadcastDone) {
        long delay = endTime - System.currentTimeMillis();
        if (delay <= 0) {
          Log.w(TAG, "Shutdown broadcast timed out");
          break;
        }
        try {
          mBroadcastDoneSync.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) {
      }
    }

    final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
    final IBluetooth bluetooth =
        IBluetooth.Stub.asInterface(
            ServiceManager.checkService(BluetoothAdapter.BLUETOOTH_SERVICE));

    final IMountService mount =
        IMountService.Stub.asInterface(ServiceManager.checkService("mount"));

    try {
      bluetoothOff =
          bluetooth == null || bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
      if (!bluetoothOff) {
        Log.w(TAG, "Disabling Bluetooth...");
        bluetooth.disable(false); // disable but don't persist new state
      }
    } catch (RemoteException ex) {
      Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
      bluetoothOff = true;
    }

    try {
      radioOff = phone == null || !phone.isRadioOn();
      if (!radioOff) {
        Log.w(TAG, "Turning off radio...");
        phone.setRadio(false);
      }
    } catch (RemoteException ex) {
      Log.e(TAG, "RemoteException during radio shutdown", ex);
      radioOff = true;
    }

    Log.i(TAG, "Waiting for Bluetooth and Radio...");

    // Wait a max of 32 seconds for clean shutdown
    for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
      if (!bluetoothOff) {
        try {
          bluetoothOff = bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
        } catch (RemoteException ex) {
          Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
          bluetoothOff = true;
        }
      }
      if (!radioOff) {
        try {
          radioOff = !phone.isRadioOn();
        } catch (RemoteException ex) {
          Log.e(TAG, "RemoteException during radio shutdown", ex);
          radioOff = true;
        }
      }
      if (radioOff && bluetoothOff) {
        Log.i(TAG, "Radio and Bluetooth shutdown complete.");
        break;
      }
      SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
    }

    // Shutdown MountService to ensure media is in a safe state
    try {
      if (mount != null) {
        mount.shutdown();
      } else {
        Log.w(TAG, "MountService unavailable for shutdown");
      }
    } catch (Exception e) {
      Log.e(TAG, "Exception during MountService shutdown", e);
    }

    // shutdown power
    Log.i(TAG, "Performing low-level shutdown...");
    Power.shutdown();
  }