本文介绍Android 5.1和Android6.0平台下,框架层实现盒子与支持CEC的电视控制和交互逻辑:
(1)盒子待机,控制电视待机
(2)电视待机,控制盒子待机
(3)盒子唤醒,控制电视唤醒
(4)获取盒子,电视的电源状态
其中(2)Android框架层已经实现
关于HDMI-CEC的介绍,请移步https://source.android.com/devices/tv/hdmi-cec
HDMI-CEC框架层控制部分别在两个部分:
frameworks/base/core/java/android/hardware/hdmi
frameworks/base/services/core/java/com/android/server/hdmi
1.修改盒子名称在电视显示的名字
- diff --git a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
- index 48ea9a6..a921ebb 100644
- --- a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
- +++ b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
- @@ -19,6 +19,7 @@ package android.hardware.hdmi;
- import android.annotation.SystemApi;
- import android.os.Parcel;
- import android.os.Parcelable;
- +import android.os.SystemProperties;
- /**
- * A class to encapsulate device information for HDMI devices including CEC and MHL. In terms of
- @@ -407,7 +408,10 @@ public class HdmiDeviceInfo implements Parcelable {
- * Returns display (OSD) name of the device.
- */
- public String getDisplayName() {
- - return mDisplayName;
- +
- + mDisplayName = SystemProperties.get("persist.sys.exdevicename", "box");
- + return mDisplayName;
- }
2.在HdmiControlManager.java添加广播动作,主要用于发送广播获取电视,盒子的待机状态,第三方应用可以通过接受广播获取盒子和电视的待机状态
- diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
- old mode 100644
- new mode 100755
- index 308a219..4043e2e
- --- a/core/java/android/hardware/hdmi/HdmiControlManager.java
- +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
- @@ -254,6 +254,16 @@ public final class HdmiControlManager {
- // True if we have a logical device of type TV hosted in the system.
- private final boolean mHasTvDevice;
- + //Broadcast action for power status changed
- + public static final String POWER_STATUS_CHANGED = "com.rockchip.hdmicec.power_status_changed";
- + //The key for box power status
- + public static final String HDMI_CEC_POWER_STATUS = "hdmi_cec_power_status";
- + //The key for hdmi cec device type
- + public static final String HDMI_CEC_DEVICE_TYPE = "hdmi_cec_device_type";
- + //box type
- + public static final int TYPE_HDMI_CEC_BOX = 0;
- + //tv type
- + public static final int TYPE_HDMI_CEC_TV= 1;
3.IHdmiControlService.aidl添加发送CEC命令,获取电视或盒子的逻辑地址,获取盒子电源状态等接口,这些接口在service端的HdmiControlService.java文件实现,第三方应用可以通过Binder机制去发送CEC控制命令,获取盒子电源状态等
- diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
- old mode 100644
- new mode 100755
- index c1e924e..62dea8a
- --- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
- +++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
- @@ -71,4 +71,10 @@ interface IHdmiControlService {
- void clearTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource);
- void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data);
- void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener);
- + //send cec command
- + void sendControlCommand(int src, int targetAddress, int opCode, in byte[] params);
- + //get local address for specific type
- + int getLocalAddress(int type);
- + //get power status
- + int getPowerStatus();
- }
4.在HdmiCecLocalDevice.java广播电视的待机状态,激活盒子作为输入源,控制盒子待机
- diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
- old mode 100644
- new mode 100755
- index 7999321..e66d0d1
- --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
- +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
- @@ -22,7 +22,9 @@ import android.os.Handler;
- import android.os.Looper;
- import android.os.Message;
- import android.os.SystemClock;
- +import android.os.SystemProperties;
- import android.util.Slog;
- +import android.util.Log;
- import android.view.InputDevice;
- import android.view.KeyCharacterMap;
- import android.view.KeyEvent;
- @@ -35,7 +37,8 @@ import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Iterator;
- import java.util.List;
- -
- +import android.util.Log;
- +import android.hardware.hdmi.HdmiControlManager;
- /**
- * Class that models a logical CEC device hosted in this system. Handles initialization,
- * CEC commands that call for actions customized per device type.
- @@ -222,10 +225,12 @@ abstract class HdmiCecLocalDevice {
- @ServiceThreadOnly
- boolean dispatchMessage(HdmiCecMessage message) {
- assertRunOnServiceThread();
- + Log.i(TAG, "dispatchMessage->message:" + message);
- int dest = message.getDestination();
- if (dest != mAddress && dest != Constants.ADDR_BROADCAST) {
- return false;
- }
- +
- // Cache incoming message. Note that it caches only white-listed one.
- mCecMessageCache.cacheMessage(message);
- return onMessage(message);
- @@ -234,7 +239,11 @@ abstract class HdmiCecLocalDevice {
- @ServiceThreadOnly
- protected final boolean onMessage(HdmiCecMessage message) {
- assertRunOnServiceThread();
- + if(message.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS && message.getSource() == 0){
- + mService.sendPowerStatusChanged(HdmiControlManager.TYPE_HDMI_CEC_TV, (int)(message.getParams()[0]));
- + }
- if (dispatchMessageToAction(message)) {
- + Log.i(TAG, "onMessage->dispatchMessageToAction->message:" + message);
- return true;
- }
- switch (message.getOpcode()) {
- @@ -314,6 +323,7 @@ abstract class HdmiCecLocalDevice {
- @ServiceThreadOnly
- private boolean dispatchMessageToAction(HdmiCecMessage message) {
- assertRunOnServiceThread();
- + Log.i(TAG, "dispatchMessageToAction->message:" + message);
- boolean processed = false;
- // Use copied action list in that processCommand may remove itself.
- for (HdmiCecFeatureAction action : new ArrayList<>(mActions)) {
- @@ -367,7 +377,20 @@ abstract class HdmiCecLocalDevice {
- @ServiceThreadOnly
- protected boolean handleRequestActiveSource(HdmiCecMessage message) {
- - return false;
- + assertRunOnServiceThread();
- + // Note that since this method is called after physical address allocation is done,
- + // mDeviceInfo should not be null.
- + HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildActiveSource(
- + mAddress, mDeviceInfo.getPhysicalAddress());
- + if (cecMessage != null) {
- + Log.i(TAG, "handleRequestActiveSource->cecMessage:" + message);
- + mService.sendCecCommand(cecMessage);
- + } else {
- + Log.i(TAG, "Failed to build <Request Active Source>:" + mDeviceInfo.getPhysicalAddress());
- + //Slog.w(TAG, "Failed to build <Request Active Source>:" + mDeviceInfo.getPhysicalAddress());
- + }
- + return true;
- +
- }
5.HdmiControlService.java实现IHdmiControlService.aidl添加的三个接口方法,监听HDMI的插拔事件,激活输入源,实现控制电视待机,唤醒的方法
- diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
- old mode 100644
- new mode 100755
- index cfc5f7d..23a9698
- --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
- +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
- @@ -28,7 +28,7 @@ import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
- import static com.android.server.hdmi.Constants.OPTION_MHL_INPUT_SWITCHING;
- import static com.android.server.hdmi.Constants.OPTION_MHL_POWER_CHARGE;
- import static com.android.server.hdmi.Constants.OPTION_MHL_SERVICE_CONTROL;
- import android.annotation.Nullable;
- import android.content.BroadcastReceiver;
- import android.content.ContentResolver;
- @@ -49,6 +49,8 @@ import android.hardware.hdmi.IHdmiMhlVendorCommandListener;
- import android.hardware.hdmi.IHdmiRecordListener;
- import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
- import android.hardware.hdmi.IHdmiVendorCommandListener;
- +import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
- +import android.hardware.hdmi.HdmiPlaybackClient;
- import android.media.AudioManager;
- import android.media.tv.TvInputManager;
- import android.media.tv.TvInputManager.TvInputCallback;
- @@ -69,7 +71,7 @@ import android.util.ArraySet;
- import android.util.Slog;
- import android.util.SparseArray;
- import android.util.SparseIntArray;
- +import android.hardware.display.DisplayManager;
- import com.android.internal.annotations.GuardedBy;
- import com.android.internal.util.IndentingPrintWriter;
- import com.android.server.SystemService;
- @@ -77,9 +79,8 @@ import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
- import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
- import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
- import com.android.server.hdmi.HdmiCecLocalDevice.PendingActionClearedCallback;
- +import android.view.Display;
- import libcore.util.EmptyArray;
- import java.io.FileDescriptor;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- @@ -87,7 +88,14 @@ import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- import java.util.Locale;
- +import android.util.Log;
- +import android.view.KeyEvent;
- +import android.view.InputEvent;
- +import android.view.InputChannel;
- +import android.view.InputDevice;
- +import android.hardware.input.InputManager;
- +import android.hardware.input.InputManager.InputDeviceListener;
- /**
- * Provides a service for sending and processing HDMI control messages,
- * HDMI-CEC and MHL control command, and providing the information on both standard.
- @@ -146,15 +154,21 @@ public final class HdmiControlService extends SystemService {
- @Override
- public void onReceive(Context context, Intent intent) {
- assertRunOnServiceThread();
- switch (intent.getAction()) {
- case Intent.ACTION_SCREEN_OFF:
- if (isPowerOnOrTransient()) {
- onStandby(STANDBY_SCREEN_OFF);
- }
- break;
- case Intent.ACTION_SCREEN_ON:
- if (isPowerStandbyOrTransient()) {
- onWakeUp();
- + touchTv();
- }
- break;
- case Intent.ACTION_CONFIGURATION_CHANGED:
- @@ -292,7 +306,14 @@ public final class HdmiControlService extends SystemService {
- @Nullable
- private PowerManager mPowerManager;
- -
- +
- + private DisplayManager mDisplayManager;
- +
- + private HDMIListener mHdmiListener = new HDMIListener();
- +
- + private InputManager mInputManager;
- +
- // 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.
- @@ -422,10 +451,25 @@ public final class HdmiControlService extends SystemService {
- registerContentObserver();
- }
- mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, ENABLED);
- +
- + mDisplayManager = (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
- +
- + if(mDisplayManager != null){
- + mDisplayManager.registerDisplayListener(mHdmiListener, null);
- + }
- +
- }
- @@ -455,8 +503,10 @@ public final class HdmiControlService extends SystemService {
- * Called when the initialization of local devices is complete.
- */
- private void onInitializeCecComplete(int initiatedBy) {
- + Log.i(TAG, "HdmiControlService8");
- if (mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) {
- mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
- + sendPowerStatusChanged(HdmiControlManager.TYPE_HDMI_CEC_BOX, mPowerStatus);
- }
- mWakeUpMessageReceived = false;
- @@ -814,12 +890,15 @@ public final class HdmiControlService extends SystemService {
- * @param command CEC command to send out
- * @param callback interface used to the result of send command
- */
- - @ServiceThreadOnly
- + //@ServiceThreadOnly
- void sendCecCommand(HdmiCecMessage command, @Nullable SendMessageCallback callback) {
- - assertRunOnServiceThread();
- + //assertRunOnServiceThread();
- + Log.i(TAG, "sendCecCommand->HdmiControlService35");
- if (mMessageValidator.isValid(command) == HdmiCecMessageValidator.OK) {
- + Log.i(TAG, "sendCecCommand->valid message type");
- mCecController.sendCommand(command, callback);
- } else {
- + Log.i(TAG, "sendCecCommand->Invalid message type:" + command);
- HdmiLogger.error("Invalid message type:" + command);
- if (callback != null) {
- callback.onSendCompleted(Constants.SEND_RESULT_FAILURE);
- @@ -827,9 +906,10 @@ public final class HdmiControlService extends SystemService {
- }
- }
- - @ServiceThreadOnly
- + //@ServiceThreadOnly
- void sendCecCommand(HdmiCecMessage command) {
- - assertRunOnServiceThread();
- + //assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService36");
- sendCecCommand(command, null);
- }
- @@ -842,13 +922,17 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- void maySendFeatureAbortCommand(HdmiCecMessage command, int reason) {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService37");
- mCecController.maySendFeatureAbortCommand(command, reason);
- }
- @ServiceThreadOnly
- boolean handleCecCommand(HdmiCecMessage message) {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService38");
- + Log.i(TAG, "handleCecCommand:" + message);
- if (!mAddressAllocated) {
- + Log.i(TAG, "handleCecCommand->mAddressAllocated is not allocate");
- mCecMessageBuffer.bufferMessage(message);
- return true;
- }
- @@ -1656,11 +1756,31 @@ public final class HdmiControlService extends SystemService {
- pw.decreaseIndent();
- pw.println("mPowerStatus: " + mPowerStatus);
- }
- +
- + @Override
- + public void sendControlCommand(int src, int targetAddress, int opCode, byte[] params){
- + HdmiCecMessage cecMessage = new HdmiCecMessage(src, targetAddress, opCode, params);
- + sendCecCommand(cecMessage);
- + }
- +
- + @Override
- + public int getLocalAddress(int type){
- + HdmiCecLocalDevice device = mCecController.getLocalDevice(type);
- + if(device != null)
- + return device.getLogicAddress();
- + return -1;
- + }
- +
- + @Override
- + public int getPowerStatus(){
- + return HdmiControlService.this.getPowerStatus();
- + }
- }
- @ServiceThreadOnly
- private void oneTouchPlay(final IHdmiControlCallback callback) {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService54");
- HdmiCecLocalDevicePlayback source = playback();
- if (source == null) {
- Slog.w(TAG, "Local playback device not available");
- @@ -1986,7 +2136,9 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- private void onWakeUp() {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService85");
- mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
- + sendPowerStatusChanged(HdmiControlManager.TYPE_HDMI_CEC_BOX, mPowerStatus);
- if (mCecController != null) {
- if (mHdmiControlEnabled) {
- int startReason = INITIATED_BY_SCREEN_ON;
- @@ -2004,8 +2156,12 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- private void onStandby(final int standbyAction) {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService86");
- + Log.i(TAG, "onStandby:" + 0);
- if (!canGoToStandby()) return;
- + Log.i(TAG, "onStandby:" + 1);
- mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY;
- + sendPowerStatusChanged(HdmiControlManager.TYPE_HDMI_CEC_BOX, mPowerStatus);
- invokeVendorCommandListenersOnControlStateChanged(false,
- HdmiControlManager.CONTROL_STATE_CHANGED_REASON_STANDBY);
- @@ -2026,6 +2182,7 @@ public final class HdmiControlService extends SystemService {
- }
- private boolean canGoToStandby() {
- + Log.i(TAG, "HdmiControlService87");
- for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
- if (!device.canGoToStandby()) return false;
- }
- @@ -2035,6 +2192,7 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- private void onLanguageChanged(String language) {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService88");
- mLanguage = language;
- if (isTvDeviceEnabled()) {
- @@ -2046,10 +2204,12 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- String getLanguage() {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService89");
- return mLanguage;
- }
- private void disableDevices(PendingActionClearedCallback callback) {
- + Log.i(TAG, "HdmiControlService90");
- if (mCecController != null) {
- for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
- device.disableDevice(mStandbyMessageReceived, callback);
- @@ -2062,6 +2222,7 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- private void clearLocalDevices() {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService91");
- if (mCecController == null) {
- return;
- }
- @@ -2072,12 +2233,14 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- private void onStandbyCompleted(int standbyAction) {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService92");
- Slog.v(TAG, "onStandbyCompleted");
- if (mPowerStatus != HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY) {
- return;
- }
- mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
- + sendPowerStatusChanged(HdmiControlManager.TYPE_HDMI_CEC_BOX, mPowerStatus);
- for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
- device.onStandby(mStandbyMessageReceived, standbyAction);
- }
- @@ -2317,10 +2496,136 @@ public final class HdmiControlService extends SystemService {
- @ServiceThreadOnly
- void displayOsd(int messageId, int extra) {
- assertRunOnServiceThread();
- + Log.i(TAG, "HdmiControlService111");
- Intent intent = new Intent(HdmiControlManager.ACTION_OSD_MESSAGE);
- intent.putExtra(HdmiControlManager.EXTRA_MESSAGE_ID, messageId);
- intent.putExtra(HdmiControlManager.EXTRA_MESSAGE_EXTRA_PARAM1, extra);
- getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
- HdmiControlService.PERMISSION);
- }
- +
- +
- + public void standbyTv(){
- + if(mCecController != null){
- + HdmiCecLocalDevice playBackDevice = mCecController.getLocalDevice(HdmiDeviceInfo.DEVICE_PLAYBACK);
- + int playBackAddrss = playBackDevice.getLogicAddress();
- + byte[] cecParam = new byte[0];
- + final HdmiCecMessage cecMessage = new HdmiCecMessage(playBackAddrss, 0, 0x36, cecParam);
- + sendCecCommand(cecMessage, new SendMessageCallback(){
- + public void onSendCompleted(int error){
- + if(error == Constants.SEND_RESULT_SUCCESS){
- + sendPowerStatusChanged(HdmiControlManager.TYPE_HDMI_CEC_TV, HdmiControlManager.POWER_STATUS_STANDBY);
- + Log.i(TAG, "standbyTv->sendCecCommand success");
- + }
- + else
- + Log.i(TAG, "standbyTv->sendCecCommand failed");
- + }
- + });
- + }
- + }
- +
- +
- + public void touchTv(){
- + Log.i(TAG, "touchTv-1");
- + HdmiControlManager controlManager = (HdmiControlManager)getContext().getSystemService(Context.HDMI_CONTROL_SERVICE);
- + if(controlManager == null)
- + return;
- + Log.i(TAG, "touchTv-2");
- + HdmiPlaybackClient playbackClient = controlManager.getPlaybackClient();
- + if(playbackClient == null)
- + return;
- + Log.i(TAG, "touchTv-3");
- + playbackClient.oneTouchPlay(new OneTouchPlayCallback() {
- + @Override
- + public void onComplete(int result) {
- + if (result != HdmiControlManager.RESULT_SUCCESS) {
- + Log.i(TAG, "One touch play failed: " + result);
- + } else {
- + Log.i(TAG, "One touch play succeed: " + result);
- +
- + }
- + }
- + });
- + }
- +
- + public void sendActiveSource(){
- + if(mCecController != null){
- + HdmiCecLocalDevice playBackDevice = mCecController.getLocalDevice(HdmiDeviceInfo.DEVICE_PLAYBACK);
- + int playBackAddrss = playBackDevice.getLogicAddress();
- + byte[] cecParam = new byte[0];
- + HdmiCecMessage cecMessageToTv = new HdmiCecMessage(playBackAddrss, 0, 0x85, cecParam);
- + HdmiCecMessage cecMessageToPlayBack = new HdmiCecMessage(0, playBackAddrss, 0x85, cecParam);
- + sendCecCommand(cecMessageToTv, new SendMessageCallback(){
- + public void onSendCompleted(int error){
- + if(error == Constants.SEND_RESULT_SUCCESS)
- + Log.i(TAG, "sendActiveSource->sendCecCommand to tv success");
- + else
- + Log.i(TAG, "sendActiveSource->sendCecCommand to tv failed");
- + }
- + });
- +
- + sendCecCommand(cecMessageToPlayBack, new SendMessageCallback(){
- + public void onSendCompleted(int error){
- + if(error == Constants.SEND_RESULT_SUCCESS)
- + Log.i(TAG, "sendActiveSource->sendCecCommand to playback success");
- + else
- + Log.i(TAG, "sendActiveSource->sendCecCommand to playback failed");
- + }
- + });
- + }
- +
- + }
- +
- + public void sendPowerStatusChanged(int deviceType, int powerStatus){
- + Log.i(TAG, "sendPowerStatusChanged");
- + Intent intent = new Intent(HdmiControlManager.POWER_STATUS_CHANGED);
- + intent.putExtra(HdmiControlManager.HDMI_CEC_POWER_STATUS, powerStatus);
- + intent.putExtra(HdmiControlManager.HDMI_CEC_DEVICE_TYPE, deviceType);
- + intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- + getContext().sendBroadcast(intent);
- + }
- +
- + class HDMIListener implements DisplayManager.DisplayListener {
- +
- + @Override
- + public void onDisplayAdded(int displayId) {
- + Display display = mDisplayManager.getDisplay(displayId);
- + Log.i(TAG, "HDMI Add:" + display);
- + sendActiveSource();
- + touchTv();
- + }
- +
- + @Override
- + public void onDisplayRemoved(int displayId) {
- + Display display = mDisplayManager.getDisplay(displayId);
- + Log.i(TAG, "HDMI removed:" + display);
- + }
- +
- + @Override
- + public void onDisplayChanged(int displayId) {
- +
- + }
- +
- + }
- }
6.PowerManagerService.java在盒子待机的时候,也让电视待机
- diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
- index 9a20aa2..d5bf708 100755
- --- a/services/core/java/com/android/server/power/PowerManagerService.java
- +++ b/services/core/java/com/android/server/power/PowerManagerService.java
- @@ -89,6 +89,9 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
- import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
- import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
- import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
- +//FOR CEC
- +import android.hardware.hdmi.*;
- +import android.os.ServiceManager;
- /**
- * The power manager service is responsible for coordinating power management
- @@ -1166,6 +1169,17 @@ public final class PowerManagerService extends SystemService
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
- + //FOR CEC standbyTv
- + IBinder playBinder = ServiceManager.getService(Context.HDMI_CONTROL_SERVICE);
- + IHdmiControlService mControlService = IHdmiControlService.Stub.asInterface(playBinder);
- + try {
- + Slog.i(TAG, "send cec standby command to TV");
- + mControlService.sendControlCommand(mControlService.getLocalAddress(HdmiDeviceInfo.DEVICE_PLAYBACK), 0 , 0x36, new byte[]{});
- + } catch (Exception e) {
- + Slog.i(TAG, "发送待机指令出错" + e);
- + }
- +
- +
- try {
- switch (reason) {
- case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
至此,HDMI-CEC基本的功能(待机,唤醒,获取电源状态)已经实现