diff options
| author | 2015-01-10 21:59:37 +0000 | |
|---|---|---|
| committer | 2015-01-10 21:59:40 +0000 | |
| commit | f94d5d26f2d122cbb41327d8e34d8655514f9b0c (patch) | |
| tree | c98915eb3e136584570af0f8aab4100b4b85d1e7 | |
| parent | 2a9abb34d8be77b1dbacb5282480e39deae5d9a1 (diff) | |
| parent | e26d833c4a00bc7c1c23083f28ef891703e7e385 (diff) | |
Merge "CEC: Keep Playback device awake while it is the active source" into lmp-mr1-dev
4 files changed, 68 insertions, 23 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index 1b478885e9cb..d17e9b32bd4f 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -202,6 +202,14 @@ abstract class HdmiCecLocalDevice {      }      /** +     * Returns true if the local device allows the system to be put to standby. +     * The default implementation returns true. +     */ +    protected boolean canGoToStandby() { +        return true; +    } + +    /**       * Dispatch incoming message.       *       * @param message incoming message diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index 85a1a152b9ca..a8f6954405c3 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -19,6 +19,8 @@ package com.android.server.hdmi;  import android.hardware.hdmi.HdmiControlManager;  import android.hardware.hdmi.HdmiDeviceInfo;  import android.hardware.hdmi.IHdmiControlCallback; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock;  import android.os.RemoteException;  import android.os.SystemProperties;  import android.util.Slog; @@ -34,17 +36,17 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {      private boolean mIsActiveSource = false; +    // Used to keep the device awake while it is the active source. For devices that +    // cannot wake up via CEC commands, this address the inconvenience of having to +    // turn them on. +    // Lazily initialized - should call getWakeLock() to get the instance. +    private WakeLock mWakeLock; +      HdmiCecLocalDevicePlayback(HdmiControlService service) {          super(service, HdmiDeviceInfo.DEVICE_PLAYBACK);      }      @Override -    void init() { -        super.init(); -        mIsActiveSource = false; -    } - -    @Override      @ServiceThreadOnly      protected void onAddressAllocated(int logicalAddress, int reason) {          assertRunOnServiceThread(); @@ -129,12 +131,37 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {          if (connected && mService.isPowerStandbyOrTransient()) {              mService.wakeUp();          } +        if (!connected) { +            getWakeLock().release(); +        }      }      @ServiceThreadOnly -    void markActiveSource() { +    void setActiveSource(boolean on) {          assertRunOnServiceThread(); -        mIsActiveSource = true; +        mIsActiveSource = on; +        if (on) { +            getWakeLock().acquire(); +            HdmiLogger.debug("active source: %b. Wake lock acquired", mIsActiveSource); +        } else { +            getWakeLock().release(); +            HdmiLogger.debug("Wake lock released"); +        } +    } + +    @ServiceThreadOnly +    private WakeLock getWakeLock() { +        assertRunOnServiceThread(); +        if (mWakeLock == null) { +            mWakeLock = mService.getPowerManager().newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); +            mWakeLock.setReferenceCounted(false); +        } +        return mWakeLock; +    } + +    @Override +    protected boolean canGoToStandby() { +        return !getWakeLock().isHeld();      }      @Override @@ -148,7 +175,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {      private void mayResetActiveSource(int physicalAddress) {          if (physicalAddress != mService.getPhysicalAddress()) { -            mIsActiveSource = false; +            setActiveSource(false);          }      } @@ -163,9 +190,9 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {          return true;  // Broadcast message.      } -    // Samsung model, we tested, sends <RoutingChange> and <RequestActiveSource> consecutively, -    // Then if there is no <ActiveSource> response, it will change the input to -    // the internal source.  To handle this, we'll set ActiveSource aggressively. +    // Samsung model we tested sends <Routing Change> and <Request Active Source> +    // in a row, and then changes the input to the internal source if there is no +    // <Active Source> in response. To handle this, we'll set ActiveSource aggressively.      @Override      @ServiceThreadOnly      protected boolean handleRoutingChange(HdmiCecMessage message) { @@ -185,11 +212,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {      }      private void maySetActiveSource(int physicalAddress) { -        if (physicalAddress == mService.getPhysicalAddress()) { -            mIsActiveSource = true; -        } else { -            mIsActiveSource = false; -        } +        setActiveSource(physicalAddress == mService.getPhysicalAddress());      }      private void wakeUpIfActiveSource() { @@ -226,7 +249,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {              mService.sendCecCommand(HdmiCecMessageBuilder.buildInactiveSource(                      mAddress, mService.getPhysicalAddress()));          } -        mIsActiveSource = false; +        setActiveSource(false);          checkIfPendingActionsCleared();      } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index e8cb7204e5f6..2593e2b522ce 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -277,6 +277,9 @@ public final class HdmiControlService extends SystemService {      @Nullable      private TvInputManager mTvInputManager; +    @Nullable +    private PowerManager mPowerManager; +      // Last input port before switching to the MHL port. Should switch back to this port      // when the mobile device sends the request one touch play with off.      // Gets invalidated if we go to other port/input. @@ -353,6 +356,7 @@ public final class HdmiControlService extends SystemService {          if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {              mTvInputManager = (TvInputManager) getContext().getSystemService(                      Context.TV_INPUT_SERVICE); +            mPowerManager = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);          }      } @@ -370,6 +374,10 @@ public final class HdmiControlService extends SystemService {          mTvInputManager.unregisterCallback(callback);      } +    PowerManager getPowerManager() { +        return mPowerManager; +    } +      /**       * Called when the initialization of local devices is complete.       */ @@ -1859,8 +1867,7 @@ public final class HdmiControlService extends SystemService {      void wakeUp() {          assertRunOnServiceThread();          mWakeUpMessageReceived = true; -        PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); -        pm.wakeUp(SystemClock.uptimeMillis()); +        mPowerManager.wakeUp(SystemClock.uptimeMillis());          // PowerManger will send the broadcast Intent.ACTION_SCREEN_ON and after this gets          // the intent, the sequence will continue at onWakeUp().      } @@ -1869,8 +1876,7 @@ public final class HdmiControlService extends SystemService {      void standby() {          assertRunOnServiceThread();          mStandbyMessageReceived = true; -        PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); -        pm.goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_HDMI, 0); +        mPowerManager.goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_HDMI, 0);          // PowerManger will send the broadcast Intent.ACTION_SCREEN_OFF and after this gets          // the intent, the sequence will continue at onStandby().      } @@ -1896,6 +1902,7 @@ public final class HdmiControlService extends SystemService {      @ServiceThreadOnly      private void onStandby() {          assertRunOnServiceThread(); +        if (!canGoToStandby()) return;          mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY;          invokeVendorCommandListenersOnControlStateChanged(false,                  HdmiControlManager.CONTROL_STATE_CHANGED_REASON_STANDBY); @@ -1916,6 +1923,13 @@ public final class HdmiControlService extends SystemService {          });      } +    private boolean canGoToStandby() { +        for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) { +            if (!device.canGoToStandby()) return false; +        } +        return true; +    } +      @ServiceThreadOnly      private void onLanguageChanged(String language) {          assertRunOnServiceThread(); diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java index e764a1c85c79..a711102f84fd 100644 --- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java +++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java @@ -82,7 +82,7 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {      private void broadcastActiveSource() {          sendCommand(HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(), getSourcePath()));          // Because only playback device can create this action, it's safe to cast. -        playback().markActiveSource(); +        playback().setActiveSource(true);      }      private void queryDevicePowerStatus() {  |