tv.cec: Update framework code to call Treble HAL
Bug: 32073236 Test: Checked CEC features works on fugu after applying Treble HAL Change-Id: I26df037594e2505bd8f2d2bb6222cba5ddca2906
This commit is contained in:
@@ -19,8 +19,9 @@ LOCAL_AIDL_INCLUDES += \
|
||||
LOCAL_JAVA_LIBRARIES := \
|
||||
services.net \
|
||||
telephony-common \
|
||||
android.hardware.light@2.0-java \
|
||||
android.hardware.power@1.0-java \
|
||||
android.hardware.light@2.0-java
|
||||
android.hardware.tv.cec@1.0-java
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
|
||||
|
||||
|
||||
@@ -188,12 +188,6 @@ final class Constants {
|
||||
static final int INVALID_PHYSICAL_ADDRESS = HdmiDeviceInfo.PATH_INVALID;
|
||||
static final int PATH_INTERNAL = HdmiDeviceInfo.PATH_INTERNAL;
|
||||
|
||||
// Send result codes. It should be consistent with hdmi_cec.h's send_message error code.
|
||||
static final int SEND_RESULT_SUCCESS = 0;
|
||||
static final int SEND_RESULT_NAK = 1;
|
||||
static final int SEND_RESULT_BUSY = 2;
|
||||
static final int SEND_RESULT_FAILURE = 3;
|
||||
|
||||
// Strategy for device polling.
|
||||
// Should use "OR(|) operation of POLL_STRATEGY_XXX and POLL_ITERATION_XXX.
|
||||
static final int POLL_STRATEGY_MASK = 0x3; // first and second bit.
|
||||
@@ -231,26 +225,7 @@ final class Constants {
|
||||
static final int RECORDING_TYPE_OWN_SOURCE = 4;
|
||||
|
||||
// Definitions used for setOption(). These should be in sync with the definition
|
||||
// in hardware/libhardware/include/hardware/{hdmi_cec.h,mhl.h}.
|
||||
|
||||
// TV gets turned on by incoming <Text/Image View On>. enabled by default.
|
||||
// If set to disabled, TV won't turn on automatically.
|
||||
static final int OPTION_CEC_AUTO_WAKEUP = 1;
|
||||
|
||||
// If set to disabled, all CEC commands are discarded.
|
||||
static final int OPTION_CEC_ENABLE = 2;
|
||||
|
||||
// If set to disabled, system service yields control of CEC to sub-microcontroller.
|
||||
// If enabled, it takes the control back.
|
||||
static final int OPTION_CEC_SERVICE_CONTROL = 3;
|
||||
|
||||
// Put other devices to standby when TV goes to standby. enabled by default.
|
||||
// If set to disabled, TV doesn't send <Standby> to other devices.
|
||||
static final int OPTION_CEC_AUTO_DEVICE_OFF = 4;
|
||||
|
||||
// Passes the language used in the system when updated. The value to use is the 3 byte
|
||||
// code as defined in ISO/FDIS 639-2.
|
||||
static final int OPTION_CEC_SET_LANGUAGE = 5;
|
||||
// in hardware/libhardware/include/hardware/mhl.h.
|
||||
|
||||
// If set to disabled, TV does not switch ports when mobile device is connected.
|
||||
static final int OPTION_MHL_INPUT_SWITCHING = 101;
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.HdmiTvClient;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
|
||||
|
||||
/**
|
||||
@@ -95,7 +95,7 @@ final class DeviceSelectAction extends HdmiCecFeatureAction {
|
||||
sendCommand(mGivePowerStatus, new SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
invokeCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
|
||||
finish();
|
||||
return;
|
||||
|
||||
@@ -17,23 +17,23 @@
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiPortInfo;
|
||||
import android.hardware.tv.cec.V1_0.Result;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.Predicate;
|
||||
import com.android.server.hdmi.HdmiAnnotations.IoThreadOnly;
|
||||
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
|
||||
import com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
|
||||
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import libcore.util.EmptyArray;
|
||||
import sun.util.locale.LanguageTag;
|
||||
|
||||
/**
|
||||
* Manages HDMI-CEC command and behaviors. It converts user's command into CEC command
|
||||
@@ -256,7 +256,7 @@ final class HdmiCecController {
|
||||
if (HdmiUtils.isValidAddress(newLogicalAddress)) {
|
||||
return nativeAddLogicalAddress(mNativePtr, newLogicalAddress);
|
||||
} else {
|
||||
return -1;
|
||||
return Result.FAILURE_INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,13 +320,27 @@ final class HdmiCecController {
|
||||
* Set an option to CEC HAL.
|
||||
*
|
||||
* @param flag key of option
|
||||
* @param value value of option
|
||||
* @param enabled whether to enable/disable the given option.
|
||||
*/
|
||||
@ServiceThreadOnly
|
||||
void setOption(int flag, int value) {
|
||||
void setOption(int flag, boolean enabled) {
|
||||
assertRunOnServiceThread();
|
||||
HdmiLogger.debug("setOption: [flag:%d, value:%d]", flag, value);
|
||||
nativeSetOption(mNativePtr, flag, value);
|
||||
HdmiLogger.debug("setOption: [flag:%d, enabled:%b]", flag, enabled);
|
||||
nativeSetOption(mNativePtr, flag, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs CEC HAL about the current system language.
|
||||
*
|
||||
* @param language Three-letter code defined in ISO/FDIS 639-2. Must be lowercase letters.
|
||||
*/
|
||||
@ServiceThreadOnly
|
||||
void setLanguage(String language) {
|
||||
assertRunOnServiceThread();
|
||||
if (!LanguageTag.isLanguage(language)) {
|
||||
return;
|
||||
}
|
||||
nativeSetLanguage(mNativePtr, language);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,9 +350,9 @@ final class HdmiCecController {
|
||||
* @param enabled whether to enable/disable ARC
|
||||
*/
|
||||
@ServiceThreadOnly
|
||||
void setAudioReturnChannel(int port, boolean enabled) {
|
||||
void enableAudioReturnChannel(int port, boolean enabled) {
|
||||
assertRunOnServiceThread();
|
||||
nativeSetAudioReturnChannel(mNativePtr, port, enabled);
|
||||
nativeEnableAudioReturnChannel(mNativePtr, port, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -472,9 +486,9 @@ final class HdmiCecController {
|
||||
// <Polling Message> is a message which has empty body.
|
||||
int ret =
|
||||
nativeSendCecCommand(mNativePtr, sourceAddress, destinationAddress, EMPTY_BODY);
|
||||
if (ret == Constants.SEND_RESULT_SUCCESS) {
|
||||
if (ret == SendMessageResult.SUCCESS) {
|
||||
return true;
|
||||
} else if (ret != Constants.SEND_RESULT_NAK) {
|
||||
} else if (ret != SendMessageResult.NACK) {
|
||||
// Unusual failure
|
||||
HdmiLogger.warning("Failed to send a polling message(%d->%d) with return code %d",
|
||||
sourceAddress, destinationAddress, ret);
|
||||
@@ -572,17 +586,17 @@ final class HdmiCecController {
|
||||
HdmiLogger.debug("[S]:" + cecMessage);
|
||||
byte[] body = buildBody(cecMessage.getOpcode(), cecMessage.getParams());
|
||||
int i = 0;
|
||||
int errorCode = Constants.SEND_RESULT_SUCCESS;
|
||||
int errorCode = SendMessageResult.SUCCESS;
|
||||
do {
|
||||
errorCode = nativeSendCecCommand(mNativePtr, cecMessage.getSource(),
|
||||
cecMessage.getDestination(), body);
|
||||
if (errorCode == Constants.SEND_RESULT_SUCCESS) {
|
||||
if (errorCode == SendMessageResult.SUCCESS) {
|
||||
break;
|
||||
}
|
||||
} while (i++ < HdmiConfig.RETRANSMISSION_COUNT);
|
||||
|
||||
final int finalError = errorCode;
|
||||
if (finalError != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (finalError != SendMessageResult.SUCCESS) {
|
||||
Slog.w(TAG, "Failed to send " + cecMessage);
|
||||
}
|
||||
if (callback != null) {
|
||||
@@ -636,7 +650,8 @@ final class HdmiCecController {
|
||||
private static native int nativeGetVersion(long controllerPtr);
|
||||
private static native int nativeGetVendorId(long controllerPtr);
|
||||
private static native HdmiPortInfo[] nativeGetPortInfos(long controllerPtr);
|
||||
private static native void nativeSetOption(long controllerPtr, int flag, int value);
|
||||
private static native void nativeSetAudioReturnChannel(long controllerPtr, int port, boolean flag);
|
||||
private static native void nativeSetOption(long controllerPtr, int flag, boolean enabled);
|
||||
private static native void nativeSetLanguage(long controllerPtr, String language);
|
||||
private static native void nativeEnableAudioReturnChannel(long controllerPtr, int port, boolean flag);
|
||||
private static native boolean nativeIsConnected(long controllerPtr, int port);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.hardware.hdmi.HdmiPortInfo;
|
||||
import android.hardware.hdmi.HdmiRecordSources;
|
||||
import android.hardware.hdmi.HdmiTimerRecordSources;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.tv.TvInputInfo;
|
||||
@@ -46,7 +47,6 @@ import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback;
|
||||
@@ -57,9 +57,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Represent a logical device of type TV residing in Android system.
|
||||
@@ -910,7 +910,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
HdmiLogger.debug("Set Arc Status[old:%b new:%b]", mArcEstablished, enabled);
|
||||
boolean oldStatus = mArcEstablished;
|
||||
// 1. Enable/disable ARC circuit.
|
||||
setAudioReturnChannel(enabled);
|
||||
enableAudioReturnChannel(enabled);
|
||||
// 2. Notify arc status to audio service.
|
||||
notifyArcStatusToAudioService(enabled);
|
||||
// 3. Update arc status;
|
||||
@@ -922,11 +922,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
* Switch hardware ARC circuit in the system.
|
||||
*/
|
||||
@ServiceThreadOnly
|
||||
void setAudioReturnChannel(boolean enabled) {
|
||||
void enableAudioReturnChannel(boolean enabled) {
|
||||
assertRunOnServiceThread();
|
||||
HdmiDeviceInfo avr = getAvrDeviceInfo();
|
||||
if (avr != null) {
|
||||
mService.setAudioReturnChannel(avr.getPortId(), enabled);
|
||||
mService.enableAudioReturnChannel(avr.getPortId(), enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1870,7 +1870,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
mService.sendCecCommand(message, new SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
announceClearTimerRecordingResult(recorderAddress,
|
||||
CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
|
||||
}
|
||||
|
||||
@@ -20,10 +20,6 @@ import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
|
||||
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
|
||||
import static com.android.server.hdmi.Constants.DISABLED;
|
||||
import static com.android.server.hdmi.Constants.ENABLED;
|
||||
import static com.android.server.hdmi.Constants.OPTION_CEC_AUTO_WAKEUP;
|
||||
import static com.android.server.hdmi.Constants.OPTION_CEC_ENABLE;
|
||||
import static com.android.server.hdmi.Constants.OPTION_CEC_SERVICE_CONTROL;
|
||||
import static com.android.server.hdmi.Constants.OPTION_CEC_SET_LANGUAGE;
|
||||
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;
|
||||
@@ -49,6 +45,8 @@ import android.hardware.hdmi.IHdmiMhlVendorCommandListener;
|
||||
import android.hardware.hdmi.IHdmiRecordListener;
|
||||
import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
|
||||
import android.hardware.hdmi.IHdmiVendorCommandListener;
|
||||
import android.hardware.tv.cec.V1_0.OptionKey;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.media.AudioManager;
|
||||
import android.media.tv.TvInputManager;
|
||||
import android.media.tv.TvInputManager.TvInputCallback;
|
||||
@@ -69,7 +67,6 @@ import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.server.SystemService;
|
||||
@@ -77,11 +74,6 @@ 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 com.android.server.hdmi.SelectRequestBuffer.DeviceSelectRequest;
|
||||
import com.android.server.hdmi.SelectRequestBuffer.PortSelectRequest;
|
||||
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -89,6 +81,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
/**
|
||||
* Provides a service for sending and processing HDMI control messages,
|
||||
@@ -123,9 +116,10 @@ public final class HdmiControlService extends SystemService {
|
||||
*
|
||||
* @param error result of send request.
|
||||
* <ul>
|
||||
* <li>{@link Constants#SEND_RESULT_SUCCESS}
|
||||
* <li>{@link Constants#SEND_RESULT_NAK}
|
||||
* <li>{@link Constants#SEND_RESULT_FAILURE}
|
||||
* <li>{@link SendMessageResult#SUCCESS}
|
||||
* <li>{@link SendMessageResult#NACK}
|
||||
* <li>{@link SendMessageResult#BUSY}
|
||||
* <li>{@link SendMessageResult#FAIL}
|
||||
* </ul>
|
||||
*/
|
||||
void onSendCompleted(int error);
|
||||
@@ -466,7 +460,7 @@ public final class HdmiControlService extends SystemService {
|
||||
mWakeUpMessageReceived = false;
|
||||
|
||||
if (isTvDeviceEnabled()) {
|
||||
mCecController.setOption(OPTION_CEC_AUTO_WAKEUP, toInt(tv().getAutoWakeup()));
|
||||
mCecController.setOption(OptionKey.WAKEUP, tv().getAutoWakeup());
|
||||
}
|
||||
int reason = -1;
|
||||
switch (initiatedBy) {
|
||||
@@ -519,7 +513,7 @@ public final class HdmiControlService extends SystemService {
|
||||
if (isTvDeviceEnabled()) {
|
||||
tv().setAutoWakeup(enabled);
|
||||
}
|
||||
setCecOption(OPTION_CEC_AUTO_WAKEUP, toInt(enabled));
|
||||
setCecOption(OptionKey.WAKEUP, enabled);
|
||||
break;
|
||||
case Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED:
|
||||
for (int type : mLocalDevices) {
|
||||
@@ -556,8 +550,8 @@ public final class HdmiControlService extends SystemService {
|
||||
|
||||
private void initializeCec(int initiatedBy) {
|
||||
mAddressAllocated = false;
|
||||
mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, ENABLED);
|
||||
mCecController.setOption(OPTION_CEC_SET_LANGUAGE, HdmiUtils.languageToInt(mLanguage));
|
||||
mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true);
|
||||
mCecController.setLanguage(mLanguage);
|
||||
initializeLocalDevices(initiatedBy);
|
||||
}
|
||||
|
||||
@@ -842,7 +836,7 @@ public final class HdmiControlService extends SystemService {
|
||||
} else {
|
||||
HdmiLogger.error("Invalid message type:" + command);
|
||||
if (callback != null) {
|
||||
callback.onSendCompleted(Constants.SEND_RESULT_FAILURE);
|
||||
callback.onSendCompleted(SendMessageResult.FAIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -884,8 +878,8 @@ public final class HdmiControlService extends SystemService {
|
||||
return dispatchMessageToLocalDevice(message);
|
||||
}
|
||||
|
||||
void setAudioReturnChannel(int portId, boolean enabled) {
|
||||
mCecController.setAudioReturnChannel(portId, enabled);
|
||||
void enableAudioReturnChannel(int portId, boolean enabled) {
|
||||
mCecController.enableAudioReturnChannel(portId, enabled);
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@@ -2079,7 +2073,7 @@ public final class HdmiControlService extends SystemService {
|
||||
|
||||
if (isTvDeviceEnabled()) {
|
||||
tv().broadcastMenuLanguage(language);
|
||||
mCecController.setOption(OPTION_CEC_SET_LANGUAGE, HdmiUtils.languageToInt(language));
|
||||
mCecController.setLanguage(language);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2123,7 +2117,7 @@ public final class HdmiControlService extends SystemService {
|
||||
}
|
||||
mStandbyMessageReceived = false;
|
||||
mAddressAllocated = false;
|
||||
mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, DISABLED);
|
||||
mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, false);
|
||||
mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, DISABLED);
|
||||
}
|
||||
|
||||
@@ -2216,7 +2210,7 @@ public final class HdmiControlService extends SystemService {
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
void setCecOption(int key, int value) {
|
||||
void setCecOption(int key, boolean value) {
|
||||
assertRunOnServiceThread();
|
||||
mCecController.setOption(key, value);
|
||||
}
|
||||
@@ -2249,7 +2243,7 @@ public final class HdmiControlService extends SystemService {
|
||||
|
||||
@ServiceThreadOnly
|
||||
private void enableHdmiControlService() {
|
||||
mCecController.setOption(OPTION_CEC_ENABLE, ENABLED);
|
||||
mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true);
|
||||
mMhlController.setOption(OPTION_MHL_ENABLE, ENABLED);
|
||||
|
||||
initializeCec(INITIATED_BY_ENABLE_CEC);
|
||||
@@ -2264,7 +2258,7 @@ public final class HdmiControlService extends SystemService {
|
||||
mCecController.flush(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCecController.setOption(OPTION_CEC_ENABLE, DISABLED);
|
||||
mCecController.setOption(OptionKey.ENABLE_CEC, false);
|
||||
mMhlController.setOption(OPTION_MHL_ENABLE, DISABLED);
|
||||
clearLocalDevices();
|
||||
}
|
||||
|
||||
@@ -291,18 +291,4 @@ final class HdmiUtils {
|
||||
info.getPhysicalAddress(), info.getPortId(), info.getDeviceType(),
|
||||
info.getVendorId(), info.getDisplayName(), newPowerStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert 3 byte-long language code in string to integer representation.
|
||||
* English(eng), for example, is converted to 0x656e67.
|
||||
*
|
||||
* @param language language code in string
|
||||
* @return language code in integer representation
|
||||
*/
|
||||
static int languageToInt(String language) {
|
||||
String normalized = language.toLowerCase();
|
||||
return ((normalized.charAt(0) & 0xFF) << 16)
|
||||
| ((normalized.charAt(1) & 0xFF) << 8)
|
||||
| (normalized.charAt(2) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ final class HotplugDetectionAction extends HdmiCecFeatureAction {
|
||||
// Turn off system audio mode and update settings.
|
||||
tv().setSystemAudioMode(false, true);
|
||||
if (tv().isArcEstablished()) {
|
||||
tv().setAudioReturnChannel(false);
|
||||
tv().enableAudioReturnChannel(false);
|
||||
addAndStartAction(new RequestArcTerminationAction(localDevice(), address));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_RECORDIN
|
||||
import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_RECORDING_DIGITAL_SERVICE;
|
||||
import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_RECORDING_EXTERNAL_INPUT;
|
||||
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ public class OneTouchRecordAction extends HdmiCecFeatureAction {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
// if failed to send <Record On>, display error message and finish action.
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
tv().announceOneTouchRecordResult(
|
||||
mRecorderAddress,
|
||||
ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
|
||||
|
||||
@@ -18,10 +18,9 @@ package com.android.server.hdmi;
|
||||
import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_UNKNOWN;
|
||||
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -123,7 +122,7 @@ public class PowerStatusMonitorAction extends HdmiCecFeatureAction {
|
||||
public void onSendCompleted(int error) {
|
||||
// If fails to send <Give Device Power Status>,
|
||||
// update power status into UNKNOWN.
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
updatePowerStatus(logicalAddress, POWER_STATUS_UNKNOWN, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
|
||||
/**
|
||||
* Feature action that handles ARC action initiated by TV devices.
|
||||
*
|
||||
@@ -44,7 +46,7 @@ final class RequestArcInitiationAction extends RequestArcAction {
|
||||
sendCommand(command, new HdmiControlService.SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
// Turn off ARC status if <Request ARC Initiation> fails.
|
||||
tv().setArcStatus(false);
|
||||
finish();
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
|
||||
/**
|
||||
* Feature action to handle <Request ARC Termination>.
|
||||
*
|
||||
@@ -43,7 +45,7 @@ final class RequestArcTerminationAction extends RequestArcAction {
|
||||
sendCommand(command, new HdmiControlService.SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
// If failed to send <Request ARC Termination>, start "Disabled" ARC
|
||||
// transmission action.
|
||||
disableArcTransmission();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.util.Slog;
|
||||
|
||||
/**
|
||||
@@ -81,14 +82,14 @@ final class SetArcTransmissionStateAction extends HdmiCecFeatureAction {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
switch (error) {
|
||||
case Constants.SEND_RESULT_SUCCESS:
|
||||
case Constants.SEND_RESULT_BUSY:
|
||||
case Constants.SEND_RESULT_FAILURE:
|
||||
case SendMessageResult.SUCCESS:
|
||||
case SendMessageResult.BUSY:
|
||||
case SendMessageResult.FAIL:
|
||||
// The result of the command transmission, unless it is an obvious
|
||||
// failure indicated by the target device (or lack thereof), should
|
||||
// not affect the ARC status. Ignores it silently.
|
||||
break;
|
||||
case Constants.SEND_RESULT_NAK:
|
||||
case SendMessageResult.NACK:
|
||||
// If <Report ARC Initiated> is negatively ack'ed, disable ARC and
|
||||
// send <Report ARC Terminated> directly.
|
||||
setArcStatus(false);
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -96,7 +96,7 @@ abstract class SystemAudioAction extends HdmiCecFeatureAction {
|
||||
sendCommand(command, new HdmiControlService.SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
HdmiLogger.debug("Failed to send <System Audio Mode Request>:" + error);
|
||||
setSystemAudioMode(false);
|
||||
finishWithCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
|
||||
|
||||
/**
|
||||
@@ -48,7 +49,7 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
|
||||
mAvrAddress), new SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
tv().setSystemAudioMode(false, true);
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package com.android.server.hdmi;
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ final class SystemAudioStatusAction extends HdmiCecFeatureAction {
|
||||
new SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
handleSendGiveAudioStatusFailure();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,9 @@ import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_ANAL
|
||||
import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_DIGITAL;
|
||||
import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_EXTERNAL;
|
||||
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -82,7 +81,7 @@ public class TimerRecordingAction extends HdmiCecFeatureAction {
|
||||
sendCommand(message, new SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
if (error != Constants.SEND_RESULT_SUCCESS) {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
tv().announceTimerRecordingResult(mRecorderAddress,
|
||||
TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
|
||||
finish();
|
||||
|
||||
@@ -67,10 +67,11 @@ LOCAL_SHARED_LIBRARIES += \
|
||||
libhidl \
|
||||
libhwbinder \
|
||||
libutils \
|
||||
android.hardware.power@1.0 \
|
||||
android.hardware.vibrator@1.0 \
|
||||
android.hardware.light@2.0 \
|
||||
android.hardware.vr@1.0 \
|
||||
android.hardware.audio.common@2.0 \
|
||||
android.hardware.tv.input@1.0 \
|
||||
android.hardware.light@2.0 \
|
||||
android.hardware.power@1.0 \
|
||||
android.hardware.thermal@1.0 \
|
||||
android.hardware.tv.cec@1.0 \
|
||||
android.hardware.tv.input@1.0 \
|
||||
android.hardware.vibrator@1.0 \
|
||||
android.hardware.vr@1.0 \
|
||||
|
||||
@@ -21,16 +21,32 @@
|
||||
#include <JNIHelp.h>
|
||||
#include <ScopedPrimitiveArray.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <android/hardware/tv/cec/1.0/IHdmiCec.h>
|
||||
#include <android/hardware/tv/cec/1.0/IHdmiCecCallback.h>
|
||||
#include <android/hardware/tv/cec/1.0/types.h>
|
||||
#include <android_os_MessageQueue.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <android_runtime/Log.h>
|
||||
#include <hardware/hdmi_cec.h>
|
||||
#include <sys/param.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Looper.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
using ::android::hardware::tv::cec::V1_0::CecLogicalAddress;
|
||||
using ::android::hardware::tv::cec::V1_0::CecMessage;
|
||||
using ::android::hardware::tv::cec::V1_0::HdmiPortInfo;
|
||||
using ::android::hardware::tv::cec::V1_0::HotplugEvent;
|
||||
using ::android::hardware::tv::cec::V1_0::IHdmiCec;
|
||||
using ::android::hardware::tv::cec::V1_0::IHdmiCecCallback;
|
||||
using ::android::hardware::tv::cec::V1_0::MaxLength;
|
||||
using ::android::hardware::tv::cec::V1_0::OptionKey;
|
||||
using ::android::hardware::tv::cec::V1_0::Result;
|
||||
using ::android::hardware::tv::cec::V1_0::SendMessageResult;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
|
||||
namespace android {
|
||||
|
||||
static struct {
|
||||
@@ -40,15 +56,13 @@ static struct {
|
||||
|
||||
class HdmiCecController {
|
||||
public:
|
||||
HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj,
|
||||
const sp<Looper>& looper);
|
||||
|
||||
void init();
|
||||
HdmiCecController(sp<IHdmiCec> hdmiCec, jobject callbacksObj, const sp<Looper>& looper);
|
||||
~HdmiCecController();
|
||||
|
||||
// Send message to other device. Note that it runs in IO thread.
|
||||
int sendMessage(const cec_message_t& message);
|
||||
int sendMessage(const CecMessage& message);
|
||||
// Add a logical address to device.
|
||||
int addLogicalAddress(cec_logical_address_t address);
|
||||
int addLogicalAddress(CecLogicalAddress address);
|
||||
// Clear all logical address registered to the device.
|
||||
void clearLogicaladdress();
|
||||
// Get physical address of device.
|
||||
@@ -59,10 +73,12 @@ public:
|
||||
uint32_t getVendorId();
|
||||
// Get Port information on all the HDMI ports.
|
||||
jobjectArray getPortInfos();
|
||||
// Set a flag and its value.
|
||||
void setOption(int flag, int value);
|
||||
// Set audio return channel status.
|
||||
void setAudioReturnChannel(int port, bool flag);
|
||||
// Set an option to CEC HAL.
|
||||
void setOption(OptionKey key, bool enabled);
|
||||
// Informs CEC HAL about the current system language.
|
||||
void setLanguage(hidl_string language);
|
||||
// Enable audio return channel.
|
||||
void enableAudioReturnChannel(int port, bool flag);
|
||||
// Whether to hdmi device is connected to the given port.
|
||||
bool isConnected(int port);
|
||||
|
||||
@@ -71,69 +87,48 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
class HdmiCecCallback : public IHdmiCecCallback {
|
||||
public:
|
||||
HdmiCecCallback(HdmiCecController* controller) : mController(controller) {};
|
||||
Return<void> onCecMessage(const CecMessage& event) override;
|
||||
Return<void> onHotplugEvent(const HotplugEvent& event) override;
|
||||
private:
|
||||
HdmiCecController* mController;
|
||||
};
|
||||
|
||||
static const int INVALID_PHYSICAL_ADDRESS = 0xFFFF;
|
||||
static void onReceived(const hdmi_event_t* event, void* arg);
|
||||
|
||||
hdmi_cec_device_t* mDevice;
|
||||
sp<IHdmiCec> mHdmiCec;
|
||||
jobject mCallbacksObj;
|
||||
sp<IHdmiCecCallback> mHdmiCecCallback;
|
||||
sp<Looper> mLooper;
|
||||
};
|
||||
|
||||
// RefBase wrapper for hdmi_event_t. As hdmi_event_t coming from HAL
|
||||
// may keep its own lifetime, we need to copy it in order to delegate
|
||||
// it to service thread.
|
||||
class CecEventWrapper : public LightRefBase<CecEventWrapper> {
|
||||
public:
|
||||
explicit CecEventWrapper(const hdmi_event_t& event) {
|
||||
// Copy message.
|
||||
switch (event.type) {
|
||||
case HDMI_EVENT_CEC_MESSAGE:
|
||||
mEvent.cec.initiator = event.cec.initiator;
|
||||
mEvent.cec.destination = event.cec.destination;
|
||||
mEvent.cec.length = event.cec.length;
|
||||
std::memcpy(mEvent.cec.body, event.cec.body, event.cec.length);
|
||||
break;
|
||||
case HDMI_EVENT_HOT_PLUG:
|
||||
mEvent.hotplug.connected = event.hotplug.connected;
|
||||
mEvent.hotplug.port_id = event.hotplug.port_id;
|
||||
break;
|
||||
default:
|
||||
// TODO: add more type whenever new type is introduced.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const cec_message_t& cec() const {
|
||||
return mEvent.cec;
|
||||
}
|
||||
|
||||
const hotplug_event_t& hotplug() const {
|
||||
return mEvent.hotplug;
|
||||
}
|
||||
|
||||
virtual ~CecEventWrapper() {}
|
||||
|
||||
private:
|
||||
hdmi_event_t mEvent;
|
||||
};
|
||||
|
||||
// Handler class to delegate incoming message to service thread.
|
||||
class HdmiCecEventHandler : public MessageHandler {
|
||||
public:
|
||||
HdmiCecEventHandler(HdmiCecController* controller, const sp<CecEventWrapper>& event)
|
||||
: mController(controller),
|
||||
mEventWrapper(event) {
|
||||
}
|
||||
enum EventType {
|
||||
CEC_MESSAGE,
|
||||
HOT_PLUG
|
||||
};
|
||||
|
||||
HdmiCecEventHandler(HdmiCecController* controller, const CecMessage& cecMessage)
|
||||
: mController(controller),
|
||||
mCecMessage(cecMessage) {}
|
||||
|
||||
HdmiCecEventHandler(HdmiCecController* controller, const HotplugEvent& hotplugEvent)
|
||||
: mController(controller),
|
||||
mHotplugEvent(hotplugEvent) {}
|
||||
|
||||
virtual ~HdmiCecEventHandler() {}
|
||||
|
||||
void handleMessage(const Message& message) {
|
||||
switch (message.what) {
|
||||
case HDMI_EVENT_CEC_MESSAGE:
|
||||
propagateCecCommand(mEventWrapper->cec());
|
||||
case EventType::CEC_MESSAGE:
|
||||
propagateCecCommand(mCecMessage);
|
||||
break;
|
||||
case HDMI_EVENT_HOT_PLUG:
|
||||
propagateHotplugEvent(mEventWrapper->hotplug());
|
||||
case EventType::HOT_PLUG:
|
||||
propagateHotplugEvent(mHotplugEvent);
|
||||
break;
|
||||
default:
|
||||
// TODO: add more type whenever new type is introduced.
|
||||
@@ -143,14 +138,13 @@ public:
|
||||
|
||||
private:
|
||||
// Propagate the message up to Java layer.
|
||||
void propagateCecCommand(const cec_message_t& message) {
|
||||
jint srcAddr = message.initiator;
|
||||
jint dstAddr = message.destination;
|
||||
void propagateCecCommand(const CecMessage& message) {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
jbyteArray body = env->NewByteArray(message.length);
|
||||
const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body);
|
||||
env->SetByteArrayRegion(body, 0, message.length, bodyPtr);
|
||||
|
||||
jint srcAddr = static_cast<jint>(message.initiator);
|
||||
jint dstAddr = static_cast<jint>(message.destination);
|
||||
jbyteArray body = env->NewByteArray(message.body.size());
|
||||
const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body.data());
|
||||
env->SetByteArrayRegion(body, 0, message.body.size(), bodyPtr);
|
||||
env->CallVoidMethod(mController->getCallbacksObj(),
|
||||
gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr,
|
||||
dstAddr, body);
|
||||
@@ -159,10 +153,10 @@ private:
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
}
|
||||
|
||||
void propagateHotplugEvent(const hotplug_event_t& event) {
|
||||
void propagateHotplugEvent(const HotplugEvent& event) {
|
||||
// Note that this method should be called in service thread.
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
jint port = event.port_id;
|
||||
jint port = static_cast<jint>(event.portId);
|
||||
jboolean connected = (jboolean) event.connected;
|
||||
env->CallVoidMethod(mController->getCallbacksObj(),
|
||||
gHdmiCecControllerClassInfo.handleHotplug, port, connected);
|
||||
@@ -180,51 +174,83 @@ private:
|
||||
}
|
||||
|
||||
HdmiCecController* mController;
|
||||
sp<CecEventWrapper> mEventWrapper;
|
||||
CecMessage mCecMessage;
|
||||
HotplugEvent mHotplugEvent;
|
||||
};
|
||||
|
||||
HdmiCecController::HdmiCecController(hdmi_cec_device_t* device,
|
||||
jobject callbacksObj, const sp<Looper>& looper) :
|
||||
mDevice(device),
|
||||
mCallbacksObj(callbacksObj),
|
||||
mLooper(looper) {
|
||||
HdmiCecController::HdmiCecController(sp<IHdmiCec> hdmiCec,
|
||||
jobject callbacksObj, const sp<Looper>& looper)
|
||||
: mHdmiCec(hdmiCec),
|
||||
mCallbacksObj(callbacksObj),
|
||||
mLooper(looper) {
|
||||
mHdmiCecCallback = new HdmiCecCallback(this);
|
||||
Return<void> ret = mHdmiCec->setCallback(mHdmiCecCallback);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to set a cec callback.");
|
||||
}
|
||||
}
|
||||
|
||||
void HdmiCecController::init() {
|
||||
mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this);
|
||||
HdmiCecController::~HdmiCecController() {
|
||||
Return<void> ret = mHdmiCec->setCallback(nullptr);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to set a cec callback.");
|
||||
}
|
||||
}
|
||||
|
||||
int HdmiCecController::sendMessage(const cec_message_t& message) {
|
||||
int HdmiCecController::sendMessage(const CecMessage& message) {
|
||||
// TODO: propagate send_message's return value.
|
||||
return mDevice->send_message(mDevice, &message);
|
||||
Return<SendMessageResult> ret = mHdmiCec->sendMessage(message);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to send CEC message.");
|
||||
return static_cast<int>(SendMessageResult::FAIL);
|
||||
}
|
||||
return static_cast<int>((SendMessageResult) ret);
|
||||
}
|
||||
|
||||
int HdmiCecController::addLogicalAddress(cec_logical_address_t address) {
|
||||
return mDevice->add_logical_address(mDevice, address);
|
||||
int HdmiCecController::addLogicalAddress(CecLogicalAddress address) {
|
||||
Return<Result> ret = mHdmiCec->addLogicalAddress(address);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to add a logical address.");
|
||||
return static_cast<int>(Result::FAILURE_UNKNOWN);
|
||||
}
|
||||
return static_cast<int>((Result) ret);
|
||||
}
|
||||
|
||||
void HdmiCecController::clearLogicaladdress() {
|
||||
mDevice->clear_logical_address(mDevice);
|
||||
Return<void> ret = mHdmiCec->clearLogicalAddress();
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to clear logical address.");
|
||||
}
|
||||
}
|
||||
|
||||
int HdmiCecController::getPhysicalAddress() {
|
||||
Result result;
|
||||
uint16_t addr;
|
||||
if (!mDevice->get_physical_address(mDevice, &addr)) {
|
||||
return addr;
|
||||
Return<void> ret = mHdmiCec->getPhysicalAddress([&result, &addr](Result res, uint16_t paddr) {
|
||||
result = res;
|
||||
addr = paddr;
|
||||
});
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to get physical address.");
|
||||
return INVALID_PHYSICAL_ADDRESS;
|
||||
}
|
||||
return INVALID_PHYSICAL_ADDRESS;
|
||||
return result == Result::SUCCESS ? addr : INVALID_PHYSICAL_ADDRESS;
|
||||
}
|
||||
|
||||
int HdmiCecController::getVersion() {
|
||||
int version = 0;
|
||||
mDevice->get_version(mDevice, &version);
|
||||
return version;
|
||||
Return<int32_t> ret = mHdmiCec->getCecVersion();
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to get cec version.");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t HdmiCecController::getVendorId() {
|
||||
uint32_t vendorId = 0;
|
||||
mDevice->get_vendor_id(mDevice, &vendorId);
|
||||
return vendorId;
|
||||
Return<uint32_t> ret = mHdmiCec->getVendorId();
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to get vendor id.");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
jobjectArray HdmiCecController::getPortInfos() {
|
||||
@@ -237,48 +263,69 @@ jobjectArray HdmiCecController::getPortInfos() {
|
||||
if (ctor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
hdmi_port_info* ports;
|
||||
int numPorts;
|
||||
mDevice->get_port_info(mDevice, &ports, &numPorts);
|
||||
jobjectArray res = env->NewObjectArray(numPorts, hdmiPortInfo, NULL);
|
||||
hidl_vec<HdmiPortInfo> ports;
|
||||
Return<void> ret = mHdmiCec->getPortInfo([&ports](hidl_vec<HdmiPortInfo> list) {
|
||||
ports = list;
|
||||
});
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to get port information.");
|
||||
return NULL;
|
||||
}
|
||||
jobjectArray res = env->NewObjectArray(ports.size(), hdmiPortInfo, NULL);
|
||||
|
||||
// MHL support field will be obtained from MHL HAL. Leave it to false.
|
||||
jboolean mhlSupported = (jboolean) 0;
|
||||
for (int i = 0; i < numPorts; ++i) {
|
||||
hdmi_port_info* info = &ports[i];
|
||||
jboolean cecSupported = (jboolean) info->cec_supported;
|
||||
jboolean arcSupported = (jboolean) info->arc_supported;
|
||||
jobject infoObj = env->NewObject(hdmiPortInfo, ctor, info->port_id, info->type,
|
||||
info->physical_address, cecSupported, mhlSupported, arcSupported);
|
||||
for (size_t i = 0; i < ports.size(); ++i) {
|
||||
jboolean cecSupported = (jboolean) ports[i].cecSupported;
|
||||
jboolean arcSupported = (jboolean) ports[i].arcSupported;
|
||||
jobject infoObj = env->NewObject(hdmiPortInfo, ctor, ports[i].portId, ports[i].type,
|
||||
ports[i].physicalAddress, cecSupported, mhlSupported, arcSupported);
|
||||
env->SetObjectArrayElement(res, i, infoObj);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void HdmiCecController::setOption(int flag, int value) {
|
||||
mDevice->set_option(mDevice, flag, value);
|
||||
void HdmiCecController::setOption(OptionKey key, bool enabled) {
|
||||
Return<void> ret = mHdmiCec->setOption(key, enabled);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to set option.");
|
||||
}
|
||||
}
|
||||
|
||||
// Set audio return channel status.
|
||||
void HdmiCecController::setAudioReturnChannel(int port, bool enabled) {
|
||||
mDevice->set_audio_return_channel(mDevice, port, enabled ? 1 : 0);
|
||||
void HdmiCecController::setLanguage(hidl_string language) {
|
||||
Return<void> ret = mHdmiCec->setLanguage(language);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to set language.");
|
||||
}
|
||||
}
|
||||
|
||||
// Enable audio return channel.
|
||||
void HdmiCecController::enableAudioReturnChannel(int port, bool enabled) {
|
||||
Return<void> ret = mHdmiCec->enableAudioReturnChannel(port, enabled);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to enable/disable ARC.");
|
||||
}
|
||||
}
|
||||
|
||||
// Whether to hdmi device is connected to the given port.
|
||||
bool HdmiCecController::isConnected(int port) {
|
||||
return mDevice->is_connected(mDevice, port) == HDMI_CONNECTED;
|
||||
Return<bool> ret = mHdmiCec->isConnected(port);
|
||||
if (!ret.getStatus().isOk()) {
|
||||
ALOGE("Failed to get connection info.");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) {
|
||||
HdmiCecController* controller = static_cast<HdmiCecController*>(arg);
|
||||
if (controller == NULL) {
|
||||
return;
|
||||
}
|
||||
Return<void> HdmiCecController::HdmiCecCallback::onCecMessage(const CecMessage& message) {
|
||||
sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, message));
|
||||
mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::CEC_MESSAGE);
|
||||
return Void();
|
||||
}
|
||||
|
||||
sp<CecEventWrapper> spEvent(new CecEventWrapper(*event));
|
||||
sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(controller, spEvent));
|
||||
controller->mLooper->sendMessage(handler, event->type);
|
||||
Return<void> HdmiCecController::HdmiCecCallback::onHotplugEvent(const HotplugEvent& event) {
|
||||
sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, event));
|
||||
mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::HOT_PLUG);
|
||||
return Void();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -288,30 +335,19 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) {
|
||||
|
||||
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj,
|
||||
jobject messageQueueObj) {
|
||||
int err;
|
||||
hw_module_t* module;
|
||||
err = hw_get_module(HDMI_CEC_HARDWARE_MODULE_ID,
|
||||
const_cast<const hw_module_t **>(&module));
|
||||
if (err != 0) {
|
||||
ALOGE("Error acquiring hardware module: %d", err);
|
||||
// TODO(b/31632518)
|
||||
sp<IHdmiCec> hdmiCec = IHdmiCec::getService("tv.cec");
|
||||
if (hdmiCec == nullptr) {
|
||||
ALOGE("Couldn't get tv.cec service.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hw_device_t* device;
|
||||
err = module->methods->open(module, HDMI_CEC_HARDWARE_INTERFACE, &device);
|
||||
if (err != 0) {
|
||||
ALOGE("Error opening hardware module: %d", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sp<MessageQueue> messageQueue =
|
||||
android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
|
||||
|
||||
HdmiCecController* controller = new HdmiCecController(
|
||||
reinterpret_cast<hdmi_cec_device*>(device),
|
||||
hdmiCec,
|
||||
env->NewGlobalRef(callbacksObj),
|
||||
messageQueue->getLooper());
|
||||
controller->init();
|
||||
|
||||
GET_METHOD_ID(gHdmiCecControllerClassInfo.handleIncomingCecCommand, clazz,
|
||||
"handleIncomingCecCommand", "(II[B)V");
|
||||
@@ -323,14 +359,18 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj,
|
||||
|
||||
static jint nativeSendCecCommand(JNIEnv* env, jclass clazz, jlong controllerPtr,
|
||||
jint srcAddr, jint dstAddr, jbyteArray body) {
|
||||
cec_message_t message;
|
||||
message.initiator = static_cast<cec_logical_address_t>(srcAddr);
|
||||
message.destination = static_cast<cec_logical_address_t>(dstAddr);
|
||||
CecMessage message;
|
||||
message.initiator = static_cast<CecLogicalAddress>(srcAddr);
|
||||
message.destination = static_cast<CecLogicalAddress>(dstAddr);
|
||||
|
||||
jsize len = env->GetArrayLength(body);
|
||||
message.length = MIN(len, CEC_MESSAGE_BODY_MAX_LENGTH);
|
||||
ScopedByteArrayRO bodyPtr(env, body);
|
||||
std::memcpy(message.body, bodyPtr.get(), message.length);
|
||||
size_t bodyLength = MIN(static_cast<size_t>(len),
|
||||
static_cast<size_t>(MaxLength::MESSAGE_BODY));
|
||||
message.body.resize(bodyLength);
|
||||
for (size_t i = 0; i < bodyLength; ++i) {
|
||||
message.body[i] = static_cast<uint8_t>(bodyPtr[i]);
|
||||
}
|
||||
|
||||
HdmiCecController* controller =
|
||||
reinterpret_cast<HdmiCecController*>(controllerPtr);
|
||||
@@ -340,7 +380,7 @@ static jint nativeSendCecCommand(JNIEnv* env, jclass clazz, jlong controllerPtr,
|
||||
static jint nativeAddLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr,
|
||||
jint logicalAddress) {
|
||||
HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr);
|
||||
return controller->addLogicalAddress(static_cast<cec_logical_address_t>(logicalAddress));
|
||||
return controller->addLogicalAddress(static_cast<CecLogicalAddress>(logicalAddress));
|
||||
}
|
||||
|
||||
static void nativeClearLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr) {
|
||||
@@ -370,13 +410,20 @@ static jobjectArray nativeGetPortInfos(JNIEnv* env, jclass clazz, jlong controll
|
||||
|
||||
static void nativeSetOption(JNIEnv* env, jclass clazz, jlong controllerPtr, jint flag, jint value) {
|
||||
HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr);
|
||||
controller->setOption(flag, value);
|
||||
controller->setOption(static_cast<OptionKey>(flag), value > 0 ? true : false);
|
||||
}
|
||||
|
||||
static void nativeSetAudioReturnChannel(JNIEnv* env, jclass clazz, jlong controllerPtr,
|
||||
static void nativeSetLanguage(JNIEnv* env, jclass clazz, jlong controllerPtr, jstring language) {
|
||||
HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr);
|
||||
const char *languageStr = env->GetStringUTFChars(language, NULL);
|
||||
controller->setLanguage(languageStr);
|
||||
env->ReleaseStringUTFChars(language, languageStr);
|
||||
}
|
||||
|
||||
static void nativeEnableAudioReturnChannel(JNIEnv* env, jclass clazz, jlong controllerPtr,
|
||||
jint port, jboolean enabled) {
|
||||
HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr);
|
||||
controller->setAudioReturnChannel(port, enabled == JNI_TRUE);
|
||||
controller->enableAudioReturnChannel(port, enabled == JNI_TRUE);
|
||||
}
|
||||
|
||||
static jboolean nativeIsConnected(JNIEnv* env, jclass clazz, jlong controllerPtr, jint port) {
|
||||
@@ -398,8 +445,9 @@ static const JNINativeMethod sMethods[] = {
|
||||
{ "nativeGetPortInfos",
|
||||
"(J)[Landroid/hardware/hdmi/HdmiPortInfo;",
|
||||
(void *) nativeGetPortInfos },
|
||||
{ "nativeSetOption", "(JII)V", (void *) nativeSetOption },
|
||||
{ "nativeSetAudioReturnChannel", "(JIZ)V", (void *) nativeSetAudioReturnChannel },
|
||||
{ "nativeSetOption", "(JIZ)V", (void *) nativeSetOption },
|
||||
{ "nativeSetLanguage", "(JLjava/lang/String;)V", (void *) nativeSetLanguage },
|
||||
{ "nativeEnableAudioReturnChannel", "(JIZ)V", (void *) nativeEnableAudioReturnChannel },
|
||||
{ "nativeIsConnected", "(JI)Z", (void *) nativeIsConnected },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user