Merge "CEC: Add AIDL interface" am: 2a5c5fc11e am: 20b8f0aa23

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2106006

Change-Id: I26fe67aa020ce96791c1958159c838ef1a325652
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot 2022-10-19 04:00:04 +00:00 committed by Automerger Merge Worker
commit 5c24fd738c
49 changed files with 2565 additions and 0 deletions

View file

@ -668,6 +668,20 @@
<instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.tv.cec</name>
<interface>
<name>IHdmiCec</name>
<instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.tv.hdmi</name>
<interface>
<name>IHdmi</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.tv.input</name>
<version>1.0</version>

29
tv/cec/aidl/Android.bp Normal file
View file

@ -0,0 +1,29 @@
// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package {
default_applicable_licenses: ["hardware_interfaces_license"],
}
aidl_interface {
name: "android.hardware.tv.cec",
vendor_available: true,
srcs: ["android/hardware/tv/cec/*.aidl"],
stability: "vintf",
backend: {
java: {
sdk_version: "module_current",
},
},
}

2
tv/cec/aidl/OWNERS Normal file
View file

@ -0,0 +1,2 @@
# Bug component: 826094
include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@Backing(type="int") @VintfStability
enum AbortReason {
UNRECOGNIZED_MODE = 0,
NOT_IN_CORRECT_MODE = 1,
CANNOT_PROVIDE_SOURCE = 2,
INVALID_OPERAND = 3,
REFUSED = 4,
UNABLE_TO_DETERMINE = 5,
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@Backing(type="byte") @VintfStability
enum CecDeviceType {
INACTIVE = -1,
TV = 0,
RECORDER = 1,
TUNER = 3,
PLAYBACK = 4,
AUDIO_SYSTEM = 5,
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@Backing(type="byte") @VintfStability
enum CecLogicalAddress {
TV = 0,
RECORDER_1 = 1,
RECORDER_2 = 2,
TUNER_1 = 3,
PLAYBACK_1 = 4,
AUDIO_SYSTEM = 5,
TUNER_2 = 6,
TUNER_3 = 7,
PLAYBACK_2 = 8,
RECORDER_3 = 9,
TUNER_4 = 10,
PLAYBACK_3 = 11,
BACKUP_1 = 12,
BACKUP_2 = 13,
FREE_USE = 14,
BROADCAST = 15,
UNREGISTERED = 15,
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@VintfStability
parcelable CecMessage {
android.hardware.tv.cec.CecLogicalAddress initiator;
android.hardware.tv.cec.CecLogicalAddress destination;
byte[] body;
const int MAX_MESSAGE_BODY_LENGTH = 15;
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@Backing(type="int") @VintfStability
enum CecMessageType {
FEATURE_ABORT = 0,
IMAGE_VIEW_ON = 4,
TUNER_STEP_INCREMENT = 5,
TUNER_STEP_DECREMENT = 6,
TUNER_DEVICE_STATUS = 7,
GIVE_TUNER_DEVICE_STATUS = 8,
RECORD_ON = 9,
RECORD_STATUS = 10,
RECORD_OFF = 11,
TEXT_VIEW_ON = 13,
RECORD_TV_SCREEN = 15,
GIVE_DECK_STATUS = 26,
DECK_STATUS = 27,
SET_MENU_LANGUAGE = 50,
CLEAR_ANALOG_TIMER = 51,
SET_ANALOG_TIMER = 52,
TIMER_STATUS = 53,
STANDBY = 54,
PLAY = 65,
DECK_CONTROL = 66,
TIMER_CLEARED_STATUS = 67,
USER_CONTROL_PRESSED = 68,
USER_CONTROL_RELEASED = 69,
GIVE_OSD_NAME = 70,
SET_OSD_NAME = 71,
SET_OSD_STRING = 100,
SET_TIMER_PROGRAM_TITLE = 103,
SYSTEM_AUDIO_MODE_REQUEST = 112,
GIVE_AUDIO_STATUS = 113,
SET_SYSTEM_AUDIO_MODE = 114,
REPORT_AUDIO_STATUS = 122,
GIVE_SYSTEM_AUDIO_MODE_STATUS = 125,
SYSTEM_AUDIO_MODE_STATUS = 126,
ROUTING_CHANGE = 128,
ROUTING_INFORMATION = 129,
ACTIVE_SOURCE = 130,
GIVE_PHYSICAL_ADDRESS = 131,
REPORT_PHYSICAL_ADDRESS = 132,
REQUEST_ACTIVE_SOURCE = 133,
SET_STREAM_PATH = 134,
DEVICE_VENDOR_ID = 135,
VENDOR_COMMAND = 137,
VENDOR_REMOTE_BUTTON_DOWN = 138,
VENDOR_REMOTE_BUTTON_UP = 139,
GIVE_DEVICE_VENDOR_ID = 140,
MENU_REQUEST = 141,
MENU_STATUS = 142,
GIVE_DEVICE_POWER_STATUS = 143,
REPORT_POWER_STATUS = 144,
GET_MENU_LANGUAGE = 145,
SELECT_ANALOG_SERVICE = 146,
SELECT_DIGITAL_SERVICE = 147,
SET_DIGITAL_TIMER = 151,
CLEAR_DIGITAL_TIMER = 153,
SET_AUDIO_RATE = 154,
INACTIVE_SOURCE = 157,
CEC_VERSION = 158,
GET_CEC_VERSION = 159,
VENDOR_COMMAND_WITH_ID = 160,
CLEAR_EXTERNAL_TIMER = 161,
SET_EXTERNAL_TIMER = 162,
REPORT_SHORT_AUDIO_DESCRIPTOR = 163,
REQUEST_SHORT_AUDIO_DESCRIPTOR = 164,
INITIATE_ARC = 192,
REPORT_ARC_INITIATED = 193,
REPORT_ARC_TERMINATED = 194,
REQUEST_ARC_INITIATION = 195,
REQUEST_ARC_TERMINATION = 196,
TERMINATE_ARC = 197,
ABORT = 255,
GIVE_FEATURES = 165,
REPORT_FEATURES = 166,
REQUEST_CURRENT_LATENCY = 167,
REPORT_CURRENT_LATENCY = 168,
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@VintfStability
interface IHdmiCec {
android.hardware.tv.cec.Result addLogicalAddress(in android.hardware.tv.cec.CecLogicalAddress addr);
void clearLogicalAddress();
void enableAudioReturnChannel(in int portId, in boolean enable);
int getCecVersion();
int getPhysicalAddress();
int getVendorId();
android.hardware.tv.cec.SendMessageResult sendMessage(in android.hardware.tv.cec.CecMessage message);
void setCallback(in android.hardware.tv.cec.IHdmiCecCallback callback);
void setLanguage(in String language);
void enableWakeupByOtp(in boolean value);
void enableCec(in boolean value);
void enableSystemCecControl(in boolean value);
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@VintfStability
interface IHdmiCecCallback {
oneway void onCecMessage(in android.hardware.tv.cec.CecMessage message);
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@Backing(type="byte") @VintfStability
enum Result {
SUCCESS = 0,
FAILURE_UNKNOWN = 1,
FAILURE_INVALID_ARGS = 2,
FAILURE_INVALID_STATE = 3,
FAILURE_NOT_SUPPORTED = 4,
FAILURE_BUSY = 5,
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.cec;
@Backing(type="byte") @VintfStability
enum SendMessageResult {
SUCCESS = 0,
NACK = 1,
BUSY = 2,
FAIL = 3,
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
/**
* Operand description [Abort Reason]
*/
@VintfStability
@Backing(type="int")
enum AbortReason {
UNRECOGNIZED_MODE = 0,
NOT_IN_CORRECT_MODE = 1,
CANNOT_PROVIDE_SOURCE = 2,
INVALID_OPERAND = 3,
REFUSED = 4,
UNABLE_TO_DETERMINE = 5,
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
@VintfStability
@Backing(type="byte")
enum CecDeviceType {
INACTIVE = -1,
TV = 0,
RECORDER = 1,
TUNER = 3,
PLAYBACK = 4,
AUDIO_SYSTEM = 5,
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
@VintfStability
@Backing(type="byte")
enum CecLogicalAddress {
TV = 0,
RECORDER_1 = 1,
RECORDER_2 = 2,
TUNER_1 = 3,
PLAYBACK_1 = 4,
AUDIO_SYSTEM = 5,
TUNER_2 = 6,
TUNER_3 = 7,
PLAYBACK_2 = 8,
RECORDER_3 = 9,
TUNER_4 = 10,
PLAYBACK_3 = 11,
BACKUP_1 = 12,
BACKUP_2 = 13,
FREE_USE = 14,
BROADCAST = 15,
UNREGISTERED = 15,
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
import android.hardware.tv.cec.CecLogicalAddress;
@VintfStability
parcelable CecMessage {
/**
* Maximum length of the message body
*/
const int MAX_MESSAGE_BODY_LENGTH = 15;
/**
* logical address of the initiator
*/
CecLogicalAddress initiator;
/**
* logical address of destination
*/
CecLogicalAddress destination;
/**
* The maximum size of body is 15 (MAX_MESSAGE_BODY_LENGTH) as specified in
* the section 6 of the CEC Spec 1.4b. Overflowed data must be ignored.
*/
byte[] body;
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
@VintfStability
@Backing(type="int")
enum CecMessageType {
FEATURE_ABORT = 0x00,
IMAGE_VIEW_ON = 0x04,
TUNER_STEP_INCREMENT = 0x05,
TUNER_STEP_DECREMENT = 0x06,
TUNER_DEVICE_STATUS = 0x07,
GIVE_TUNER_DEVICE_STATUS = 0x08,
RECORD_ON = 0x09,
RECORD_STATUS = 0x0A,
RECORD_OFF = 0x0B,
TEXT_VIEW_ON = 0x0D,
RECORD_TV_SCREEN = 0x0F,
GIVE_DECK_STATUS = 0x1A,
DECK_STATUS = 0x1B,
SET_MENU_LANGUAGE = 0x32,
CLEAR_ANALOG_TIMER = 0x33,
SET_ANALOG_TIMER = 0x34,
TIMER_STATUS = 0x35,
STANDBY = 0x36,
PLAY = 0x41,
DECK_CONTROL = 0x42,
TIMER_CLEARED_STATUS = 0x43,
USER_CONTROL_PRESSED = 0x44,
USER_CONTROL_RELEASED = 0x45,
GIVE_OSD_NAME = 0x46,
SET_OSD_NAME = 0x47,
SET_OSD_STRING = 0x64,
SET_TIMER_PROGRAM_TITLE = 0x67,
SYSTEM_AUDIO_MODE_REQUEST = 0x70,
GIVE_AUDIO_STATUS = 0x71,
SET_SYSTEM_AUDIO_MODE = 0x72,
REPORT_AUDIO_STATUS = 0x7A,
GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D,
SYSTEM_AUDIO_MODE_STATUS = 0x7E,
ROUTING_CHANGE = 0x80,
ROUTING_INFORMATION = 0x81,
ACTIVE_SOURCE = 0x82,
GIVE_PHYSICAL_ADDRESS = 0x83,
REPORT_PHYSICAL_ADDRESS = 0x84,
REQUEST_ACTIVE_SOURCE = 0x85,
SET_STREAM_PATH = 0x86,
DEVICE_VENDOR_ID = 0x87,
VENDOR_COMMAND = 0x89,
VENDOR_REMOTE_BUTTON_DOWN = 0x8A,
VENDOR_REMOTE_BUTTON_UP = 0x8B,
GIVE_DEVICE_VENDOR_ID = 0x8C,
MENU_REQUEST = 0x8D,
MENU_STATUS = 0x8E,
GIVE_DEVICE_POWER_STATUS = 0x8F,
REPORT_POWER_STATUS = 0x90,
GET_MENU_LANGUAGE = 0x91,
SELECT_ANALOG_SERVICE = 0x92,
SELECT_DIGITAL_SERVICE = 0x93,
SET_DIGITAL_TIMER = 0x97,
CLEAR_DIGITAL_TIMER = 0x99,
SET_AUDIO_RATE = 0x9A,
INACTIVE_SOURCE = 0x9D,
CEC_VERSION = 0x9E,
GET_CEC_VERSION = 0x9F,
VENDOR_COMMAND_WITH_ID = 0xA0,
CLEAR_EXTERNAL_TIMER = 0xA1,
SET_EXTERNAL_TIMER = 0xA2,
REPORT_SHORT_AUDIO_DESCRIPTOR = 0xA3,
REQUEST_SHORT_AUDIO_DESCRIPTOR = 0xA4,
INITIATE_ARC = 0xC0,
REPORT_ARC_INITIATED = 0xC1,
REPORT_ARC_TERMINATED = 0xC2,
REQUEST_ARC_INITIATION = 0xC3,
REQUEST_ARC_TERMINATION = 0xC4,
TERMINATE_ARC = 0xC5,
ABORT = 0xFF,
GIVE_FEATURES = 0xA5,
REPORT_FEATURES = 0xA6,
REQUEST_CURRENT_LATENCY = 0xA7,
REPORT_CURRENT_LATENCY = 0xA8,
}

View file

@ -0,0 +1,156 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
import android.hardware.tv.cec.CecLogicalAddress;
import android.hardware.tv.cec.CecMessage;
import android.hardware.tv.cec.IHdmiCecCallback;
import android.hardware.tv.cec.Result;
import android.hardware.tv.cec.SendMessageResult;
/**
* HDMI-CEC HAL interface definition.
*/
@VintfStability
interface IHdmiCec {
/**
* Passes the logical address that must be used in this system.
*
* HAL must use it to configure the hardware so that the CEC commands
* addressed the given logical address can be filtered in. This method must
* be able to be called as many times as necessary in order to support
* multiple logical devices.
*
* @param addr Logical address that must be used in this system. It must be
* in the range of valid logical addresses for the call to succeed.
* @return Result status of the operation. SUCCESS if successful,
* FAILURE_INVALID_ARGS if the given logical address is invalid,
* FAILURE_BUSY if device or resource is busy
*/
Result addLogicalAddress(in CecLogicalAddress addr);
/**
* Clears all the logical addresses.
*
* It is used when the system doesn't need to process CEC command any more,
* hence to tell HAL to stop receiving commands from the CEC bus, and change
* the state back to the beginning.
*/
void clearLogicalAddress();
/**
* Configures ARC circuit in the hardware logic to start or stop the
* feature.
*
* @param portId Port id to be configured.
* @param enable Flag must be either true to start the feature or false to
* stop it.
*/
void enableAudioReturnChannel(in int portId, in boolean enable);
/**
* Returns the CEC version supported by underlying hardware.
*
* @return the CEC version supported by underlying hardware.
*/
int getCecVersion();
/**
* Gets the CEC physical address.
*
* The physical address depends on the topology of the network formed by
* connected HDMI devices. It is therefore likely to change if the cable is
* plugged off and on again. It is advised to call getPhysicalAddress to get
* the updated address when hot plug event takes place.
*
* @param out addr Physical address of this device.
*/
int getPhysicalAddress();
/**
* Gets the identifier of the vendor.
*
* @return Identifier of the vendor that is the 24-bit unique
* company ID obtained from the IEEE Registration Authority
* Committee (RAC). The upper 8 bits must be 0.
*/
int getVendorId();
/**
* Transmits HDMI-CEC message to other HDMI device.
*
* The method must be designed to return in a certain amount of time and not
* hanging forever which may happen if CEC signal line is pulled low for
* some reason.
*
* It must try retransmission at least once as specified in the section '7.1
* Frame Re-transmissions' of the CEC Spec 1.4b.
*
* @param message CEC message to be sent to other HDMI device.
* @return Result status of the operation. SUCCESS if successful,
* NACK if the sent message is not acknowledged,
* BUSY if the CEC bus is busy,
* FAIL if the message could not be sent.
*/
SendMessageResult sendMessage(in CecMessage message);
/**
* Sets a callback that HDMI-CEC HAL must later use for incoming CEC
* messages.
*
* @param callback Callback object to pass hdmi events to the system. The
* previously registered callback must be replaced with this one.
* setCallback(null) should deregister the callback.
*/
void setCallback(in IHdmiCecCallback callback);
/**
* Passes the updated language information of Android system. Contains
* three-letter code as defined in ISO/FDIS 639-2. Must be used for HAL to
* respond to <Get Menu Language> while in standby mode.
*
* @param language Three-letter code defined in ISO/FDIS 639-2. Must be
* lowercase letters. (e.g., eng for English)
*/
void setLanguage(in String language);
/**
* Determines whether a TV panel device in standby mode should wake up when
* it receives an OTP (One Touch Play) from a source device.
*
* @param value If true, the TV device will wake up when OTP is received
* and if false, the TV device will not wake up for an OTP.
*/
void enableWakeupByOtp(in boolean value);
/**
* Switch to enable or disable CEC on the device.
*
* @param value If true, the device will have all CEC functionalities
* and if false, the device will not perform any CEC functions.
*/
void enableCec(in boolean value);
/**
* Determines which module processes CEC messages - the Android framework or
* the HAL.
*
* @param value If true, the Android framework will actively process CEC
* messages and if false, only the HAL will process the CEC messages.
*/
void enableSystemCecControl(in boolean value);
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
import android.hardware.tv.cec.CecMessage;
/**
* Callbacks from the HAL implementation to notify the system of new events.
*/
@VintfStability
oneway interface IHdmiCecCallback {
/**
* The callback function that must be called by HAL implementation to notify
* the system of new CEC message arrival.
*/
void onCecMessage(in CecMessage message);
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
@VintfStability
@Backing(type="byte")
enum Result {
SUCCESS = 0,
FAILURE_UNKNOWN = 1,
FAILURE_INVALID_ARGS = 2,
FAILURE_INVALID_STATE = 3,
FAILURE_NOT_SUPPORTED = 4,
FAILURE_BUSY = 5,
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.cec;
/**
* error code used for send_message.
*/
@VintfStability
@Backing(type="byte")
enum SendMessageResult {
SUCCESS = 0,
NACK = 1,
BUSY = 2,
FAIL = 3,
}

View file

@ -0,0 +1,58 @@
// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package {
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_binary {
name: "android.hardware.tv.cec-service",
vintf_fragments: ["android.hardware.tv.cec-service.xml"],
relative_install_path: "hw",
vendor: true,
cflags: [
"-Wall",
"-Wextra",
],
init_rc: ["android.hardware.tv.cec-service.rc"],
srcs: [
"serviceMock.cpp",
"HdmiCecMock.cpp",
],
shared_libs: [
"libbinder_ndk",
"liblog",
"libbase",
"libutils",
"libhardware",
"libhidlbase",
"android.hardware.tv.cec-V1-ndk",
],
}
cc_fuzz {
name: "android.hardware.tv.cec-service_fuzzer",
defaults: ["service_fuzzer_defaults"],
static_libs: [
"android.hardware.tv.cec-V1-ndk",
"liblog",
],
srcs: [
"fuzzer.cpp",
"HdmiCecMock.cpp",
],
fuzz_config: {
componentid: 826094,
},
}

View file

@ -0,0 +1,266 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.tv.cec"
#include <android-base/logging.h>
#include <fcntl.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hardware/hdmi_cec.h>
#include "HdmiCecMock.h"
using ndk::ScopedAStatus;
namespace android {
namespace hardware {
namespace tv {
namespace cec {
namespace implementation {
void HdmiCecMock::serviceDied(void* cookie) {
ALOGE("HdmiCecMock died");
auto hdmiCecMock = static_cast<HdmiCecMock*>(cookie);
hdmiCecMock->mCecThreadRun = false;
}
ScopedAStatus HdmiCecMock::addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) {
// Have a list to maintain logical addresses
mLogicalAddresses.push_back(addr);
*_aidl_return = Result::SUCCESS;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::clearLogicalAddress() {
// Remove logical address from the list
mLogicalAddresses = {};
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::enableAudioReturnChannel(int32_t portId __unused, bool enable __unused) {
// Maintain ARC status
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::getCecVersion(int32_t* _aidl_return) {
// Maintain a cec version and return it
*_aidl_return = mCecVersion;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::getPhysicalAddress(int32_t* _aidl_return) {
// Maintain a physical address and return it
// Default 0xFFFF, update on hotplug event
*_aidl_return = mPhysicalAddress;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::getVendorId(int32_t* _aidl_return) {
*_aidl_return = mCecVendorId;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::sendMessage(const CecMessage& message, SendMessageResult* _aidl_return) {
if (message.body.size() == 0) {
*_aidl_return = SendMessageResult::NACK;
} else {
sendMessageToFifo(message);
*_aidl_return = SendMessageResult::SUCCESS;
}
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::setCallback(const std::shared_ptr<IHdmiCecCallback>& callback) {
// If callback is null, mCallback is also set to null so we do not call the old callback.
mCallback = callback;
if (callback != nullptr) {
AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
mOutputFile = open(CEC_MSG_OUT_FIFO, O_RDWR | O_CLOEXEC);
pthread_create(&mThreadId, NULL, __threadLoop, this);
pthread_setname_np(mThreadId, "hdmi_cec_loop");
}
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::setLanguage(const std::string& language) {
if (language.size() != 3) {
LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size()
<< ".";
return ScopedAStatus::ok();
}
// TODO Validate if language is a valid language code
const char* languageStr = language.c_str();
int convertedLanguage = ((languageStr[0] & 0xFF) << 16) | ((languageStr[1] & 0xFF) << 8) |
(languageStr[2] & 0xFF);
mOptionLanguage = convertedLanguage;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::enableWakeupByOtp(bool value) {
mOptionWakeUp = value;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::enableCec(bool value) {
mOptionEnableCec = value;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiCecMock::enableSystemCecControl(bool value) {
mOptionSystemCecControl = value;
return ScopedAStatus::ok();
}
void* HdmiCecMock::__threadLoop(void* user) {
HdmiCecMock* const self = static_cast<HdmiCecMock*>(user);
self->threadLoop();
return 0;
}
int HdmiCecMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
if (msgCount <= 0 || !buf) {
return 0;
}
int ret = -1;
// Maybe blocked at driver
ret = read(mInputFile, buf, msgCount);
if (ret < 0) {
ALOGE("[halimp_aidl] read :%s failed, ret:%d\n", CEC_MSG_IN_FIFO, ret);
return -1;
}
return ret;
}
int HdmiCecMock::sendMessageToFifo(const CecMessage& message) {
unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH + 1] = {0};
int ret = -1;
msgBuf[0] = ((static_cast<uint8_t>(message.initiator) & 0xf) << 4) |
(static_cast<uint8_t>(message.destination) & 0xf);
size_t length = std::min(static_cast<size_t>(message.body.size()),
static_cast<size_t>(CEC_MESSAGE_BODY_MAX_LENGTH));
for (size_t i = 0; i < length; ++i) {
msgBuf[i + 1] = static_cast<unsigned char>(message.body[i]);
}
// Open the output pipe for writing outgoing cec message
mOutputFile = open(CEC_MSG_OUT_FIFO, O_WRONLY | O_CLOEXEC);
if (mOutputFile < 0) {
ALOGD("[halimp_aidl] file open failed for writing");
return -1;
}
// Write message into the output pipe
ret = write(mOutputFile, msgBuf, length + 1);
close(mOutputFile);
if (ret < 0) {
ALOGE("[halimp_aidl] write :%s failed, ret:%d\n", CEC_MSG_OUT_FIFO, ret);
return -1;
}
return ret;
}
void HdmiCecMock::printCecMsgBuf(const char* msg_buf, int len) {
int i, size = 0;
const int bufSize = CEC_MESSAGE_BODY_MAX_LENGTH * 3;
// Use 2 characters for each byte in the message plus 1 space
char buf[bufSize] = {0};
// Messages longer than max length will be truncated.
for (i = 0; i < len && size < bufSize; i++) {
size += sprintf(buf + size, " %02x", msg_buf[i]);
}
ALOGD("[halimp_aidl] %s, msg:%.*s", __FUNCTION__, size, buf);
}
void HdmiCecMock::handleCecMessage(unsigned char* msgBuf, int msgSize) {
CecMessage message;
size_t length = std::min(static_cast<size_t>(msgSize - 1),
static_cast<size_t>(CEC_MESSAGE_BODY_MAX_LENGTH));
message.body.resize(length);
for (size_t i = 0; i < length; ++i) {
message.body[i] = static_cast<uint8_t>(msgBuf[i + 1]);
ALOGD("[halimp_aidl] msg body %x", message.body[i]);
}
message.initiator = static_cast<CecLogicalAddress>((msgBuf[0] >> 4) & 0xf);
ALOGD("[halimp_aidl] msg init %hhd", message.initiator);
message.destination = static_cast<CecLogicalAddress>((msgBuf[0] >> 0) & 0xf);
ALOGD("[halimp_aidl] msg dest %hhd", message.destination);
if (mCallback != nullptr) {
mCallback->onCecMessage(message);
}
}
void HdmiCecMock::threadLoop() {
ALOGD("[halimp_aidl] threadLoop start.");
unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH];
int r = -1;
// Open the input pipe
while (mInputFile < 0) {
usleep(1000 * 1000);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
}
ALOGD("[halimp_aidl] file open ok, fd = %d.", mInputFile);
while (mCecThreadRun) {
if (!mOptionSystemCecControl) {
usleep(1000 * 1000);
continue;
}
memset(msgBuf, 0, sizeof(msgBuf));
// Try to get a message from dev.
// echo -n -e '\x04\x83' >> /dev/cec
r = readMessageFromFifo(msgBuf, CEC_MESSAGE_BODY_MAX_LENGTH);
if (r <= 1) {
// Ignore received ping messages
continue;
}
printCecMsgBuf((const char*)msgBuf, r);
if (((msgBuf[0] >> 4) & 0xf) == 0xf) {
// The message is a hotplug event, handled by HDMI HAL.
continue;
}
handleCecMessage(msgBuf, r);
}
ALOGD("[halimp_aidl] thread end.");
}
HdmiCecMock::HdmiCecMock() {
ALOGE("[halimp_aidl] Opening a virtual CEC HAL for testing and virtual machine.");
mCallback = nullptr;
mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
}
} // namespace implementation
} // namespace cec
} // namespace tv
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <aidl/android/hardware/tv/cec/BnHdmiCec.h>
#include <algorithm>
#include <vector>
using namespace std;
namespace android {
namespace hardware {
namespace tv {
namespace cec {
namespace implementation {
using ::aidl::android::hardware::tv::cec::BnHdmiCec;
using ::aidl::android::hardware::tv::cec::CecLogicalAddress;
using ::aidl::android::hardware::tv::cec::CecMessage;
using ::aidl::android::hardware::tv::cec::IHdmiCec;
using ::aidl::android::hardware::tv::cec::IHdmiCecCallback;
using ::aidl::android::hardware::tv::cec::Result;
using ::aidl::android::hardware::tv::cec::SendMessageResult;
#define CEC_MSG_IN_FIFO "/dev/cec_aidl_in_pipe"
#define CEC_MSG_OUT_FIFO "/dev/cec_aidl_out_pipe"
struct HdmiCecMock : public BnHdmiCec {
HdmiCecMock();
::ndk::ScopedAStatus addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) override;
::ndk::ScopedAStatus clearLogicalAddress() override;
::ndk::ScopedAStatus enableAudioReturnChannel(int32_t portId, bool enable) override;
::ndk::ScopedAStatus getCecVersion(int32_t* _aidl_return) override;
::ndk::ScopedAStatus getPhysicalAddress(int32_t* _aidl_return) override;
::ndk::ScopedAStatus getVendorId(int32_t* _aidl_return) override;
::ndk::ScopedAStatus sendMessage(const CecMessage& message,
SendMessageResult* _aidl_return) override;
::ndk::ScopedAStatus setCallback(const std::shared_ptr<IHdmiCecCallback>& callback) override;
::ndk::ScopedAStatus setLanguage(const std::string& language) override;
::ndk::ScopedAStatus enableWakeupByOtp(bool value) override;
::ndk::ScopedAStatus enableCec(bool value) override;
::ndk::ScopedAStatus enableSystemCecControl(bool value) override;
void printCecMsgBuf(const char* msg_buf, int len);
private:
static void* __threadLoop(void* data);
void threadLoop();
int readMessageFromFifo(unsigned char* buf, int msgCount);
int sendMessageToFifo(const CecMessage& message);
void handleCecMessage(unsigned char* msgBuf, int length);
private:
static void serviceDied(void* cookie);
std::shared_ptr<IHdmiCecCallback> mCallback;
// Variables for the virtual cec hal impl
uint16_t mPhysicalAddress = 0xFFFF;
vector<CecLogicalAddress> mLogicalAddresses;
int32_t mCecVersion = 0x06;
uint32_t mCecVendorId = 0x01;
// CEC Option value
bool mOptionWakeUp = 0;
bool mOptionEnableCec = 0;
bool mOptionSystemCecControl = 0;
int mOptionLanguage;
// Testing variables
// Input file descriptor
int mInputFile;
// Output file descriptor
int mOutputFile;
bool mCecThreadRun = true;
pthread_t mThreadId = 0;
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
};
} // namespace implementation
} // namespace cec
} // namespace tv
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,5 @@
service vendor.cec-default /vendor/bin/hw/android.hardware.tv.cec-service
interface aidl android.hardware.tv.cec.IHdmiCec/default
class hal
user system
group system

View file

@ -0,0 +1,10 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.tv.cec</name>
<version>1</version>
<interface>
<name>IHdmiCec</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <HdmiCecMock.h>
#include <fuzzbinder/libbinder_ndk_driver.h>
#include <fuzzer/FuzzedDataProvider.h>
using android::fuzzService;
using android::hardware::tv::cec::implementation::HdmiCecMock;
using ndk::SharedRefBase;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
auto hdmiCecAidl = SharedRefBase::make<HdmiCecMock>();
fuzzService(hdmiCecAidl->asBinder().get(), FuzzedDataProvider(data, size));
return 0;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.tv.cec-service-shim"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <hidl/HidlTransportSupport.h>
#include <utils/Log.h>
#include "HdmiCecMock.h"
using android::hardware::tv::cec::implementation::HdmiCecMock;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
std::shared_ptr<HdmiCecMock> hdmiCecAidl = ndk::SharedRefBase::make<HdmiCecMock>();
const std::string instance = std::string() + HdmiCecMock::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(hdmiCecAidl->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return 0;
}

View file

@ -0,0 +1,38 @@
// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package {
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_test {
name: "VtsHalTvCecAidlTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
srcs: ["VtsHalTvCecAidlTargetTest.cpp"],
static_libs: [
"android.hardware.tv.cec-V1-ndk",
"android.hardware.tv.hdmi-V1-ndk",
],
shared_libs: [
"libbinder_ndk",
],
test_suites: [
"general-tests",
"vts",
],
disable_framework: true,
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "HdmiCec_hal_test"
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/tv/cec/BnHdmiCec.h>
#include <aidl/android/hardware/tv/cec/BnHdmiCecCallback.h>
#include <aidl/android/hardware/tv/cec/CecDeviceType.h>
#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <gtest/gtest.h>
#include <log/log.h>
#include <sstream>
#include <vector>
using ::aidl::android::hardware::tv::cec::BnHdmiCecCallback;
using ::aidl::android::hardware::tv::cec::CecDeviceType;
using ::aidl::android::hardware::tv::cec::CecLogicalAddress;
using ::aidl::android::hardware::tv::cec::CecMessage;
using ::aidl::android::hardware::tv::cec::IHdmiCec;
using ::aidl::android::hardware::tv::cec::IHdmiCecCallback;
using ::aidl::android::hardware::tv::cec::Result;
using ::aidl::android::hardware::tv::cec::SendMessageResult;
using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
using ::ndk::SpAIBinder;
#define CEC_VERSION 0x05
#define INCORRECT_VENDOR_ID 0x00
#define TV_PHYSICAL_ADDRESS 0x0000
// The main test class for TV CEC HAL.
class HdmiCecTest : public ::testing::TestWithParam<std::string> {
static void serviceDied(void* /* cookie */) { ALOGE("VtsHalTvCecAidlTargetTest died"); }
public:
void SetUp() override {
hdmiCec = IHdmiCec::fromBinder(
SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
ASSERT_NE(hdmiCec, nullptr);
ALOGI("%s: getService() for hdmiCec is %s", __func__,
hdmiCec->isRemote() ? "remote" : "local");
hdmiCecCallback = ::ndk::SharedRefBase::make<CecCallback>();
ASSERT_NE(hdmiCecCallback, nullptr);
hdmiCecDeathRecipient =
ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
ASSERT_EQ(AIBinder_linkToDeath(hdmiCec->asBinder().get(), hdmiCecDeathRecipient.get(), 0),
STATUS_OK);
}
std::vector<int> getDeviceTypes() {
std::vector<int> deviceTypes;
FILE* p = popen("getprop ro.hdmi.device_type", "re");
if (p) {
char* line = NULL;
size_t len = 0;
if (getline(&line, &len, p) > 0) {
std::istringstream stream(line);
std::string number{};
while (std::getline(stream, number, ',')) {
deviceTypes.push_back(stoi(number));
}
}
pclose(p);
}
return deviceTypes;
}
bool hasDeviceType(CecDeviceType type) {
std::vector<int> deviceTypes = getDeviceTypes();
return std::find(deviceTypes.begin(), deviceTypes.end(), (int)type) != deviceTypes.end();
}
class CecCallback : public BnHdmiCecCallback {
public:
::ndk::ScopedAStatus onCecMessage(const CecMessage& message __unused) {
return ::ndk::ScopedAStatus::ok();
};
};
std::shared_ptr<IHdmiCec> hdmiCec;
std::shared_ptr<IHdmiCecCallback> hdmiCecCallback;
::ndk::ScopedAIBinder_DeathRecipient hdmiCecDeathRecipient;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HdmiCecTest);
INSTANTIATE_TEST_SUITE_P(PerInstance, HdmiCecTest,
testing::ValuesIn(android::getAidlHalInstanceNames(IHdmiCec::descriptor)),
android::PrintInstanceNameToString);
TEST_P(HdmiCecTest, ClearAddLogicalAddress) {
Result addLaResult;
ASSERT_TRUE(hdmiCec->clearLogicalAddress().isOk());
ASSERT_TRUE(hdmiCec->addLogicalAddress(CecLogicalAddress::PLAYBACK_3, &addLaResult).isOk());
EXPECT_EQ(addLaResult, Result::SUCCESS);
}
TEST_P(HdmiCecTest, PhysicalAddress) {
int32_t addr;
ASSERT_TRUE(hdmiCec->getPhysicalAddress(&addr).isOk());
if (!hasDeviceType(CecDeviceType::TV)) {
EXPECT_NE(addr, TV_PHYSICAL_ADDRESS);
}
}
TEST_P(HdmiCecTest, SendMessage) {
CecMessage message;
message.initiator = CecLogicalAddress::PLAYBACK_1;
message.destination = CecLogicalAddress::BROADCAST;
message.body.resize(1);
message.body[0] = 131;
SendMessageResult result;
ASSERT_TRUE(hdmiCec->sendMessage(message, &result).isOk());
EXPECT_EQ(result, SendMessageResult::SUCCESS);
}
TEST_P(HdmiCecTest, CecVersion) {
int32_t version;
ASSERT_TRUE(hdmiCec->getCecVersion(&version).isOk());
EXPECT_GE(version, CEC_VERSION);
}
TEST_P(HdmiCecTest, SetCallback) {
ASSERT_TRUE(hdmiCec->setCallback(::ndk::SharedRefBase::make<CecCallback>()).isOk());
}
TEST_P(HdmiCecTest, VendorId) {
int32_t vendorId;
ASSERT_TRUE(hdmiCec->getVendorId(&vendorId).isOk());
EXPECT_NE(vendorId, INCORRECT_VENDOR_ID);
}
TEST_P(HdmiCecTest, EnableWakeupByOtp) {
ASSERT_TRUE(hdmiCec->enableWakeupByOtp(false).isOk());
// Restore option to its default value
ASSERT_TRUE(hdmiCec->enableWakeupByOtp(true).isOk());
}
TEST_P(HdmiCecTest, EnableCec) {
ASSERT_TRUE(hdmiCec->enableCec(false).isOk());
// Restore option to its default value
ASSERT_TRUE(hdmiCec->enableCec(true).isOk());
}
TEST_P(HdmiCecTest, EnableSystemCecControl) {
ASSERT_TRUE(hdmiCec->enableSystemCecControl(true).isOk());
// Restore option to its default value
ASSERT_TRUE(hdmiCec->enableSystemCecControl(false).isOk());
}
TEST_P(HdmiCecTest, SetLanguage) {
ASSERT_TRUE(hdmiCec->setLanguage("eng").isOk());
}

29
tv/hdmi/aidl/Android.bp Normal file
View file

@ -0,0 +1,29 @@
// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package {
default_applicable_licenses: ["hardware_interfaces_license"],
}
aidl_interface {
name: "android.hardware.tv.hdmi",
vendor_available: true,
srcs: ["android/hardware/tv/hdmi/*.aidl"],
stability: "vintf",
backend: {
java: {
sdk_version: "module_current",
},
},
}

2
tv/hdmi/aidl/OWNERS Normal file
View file

@ -0,0 +1,2 @@
# Bug component: 826094
include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.hdmi;
@VintfStability
parcelable HdmiPortInfo {
android.hardware.tv.hdmi.HdmiPortType type;
int portId;
boolean cecSupported;
boolean arcSupported;
int physicalAddress;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.hdmi;
@Backing(type="byte") @VintfStability
enum HdmiPortType {
INPUT = 0,
OUTPUT = 1,
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.hdmi;
@VintfStability
interface IHdmi {
android.hardware.tv.hdmi.HdmiPortInfo[] getPortInfo();
boolean isConnected(in int portId);
void setCallback(in android.hardware.tv.hdmi.IHdmiCallback callback);
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.hdmi;
@VintfStability
interface IHdmiCallback {
oneway void onHotplugEvent(in boolean connected, in int portId);
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.hdmi;
import android.hardware.tv.hdmi.HdmiPortType;
/**
* HDMI port descriptor
*/
@VintfStability
parcelable HdmiPortInfo {
HdmiPortType type;
int portId; // Should start from 1 which corresponds to HDMI "port 1".
boolean cecSupported;
boolean arcSupported;
// The physical address of the device connected to this port, valid range is 0x0000 to 0xFFFF
// (ref Sec 8.7.2 of HDMI 1.4b).
int physicalAddress;
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.hdmi;
/**
* HDMI port type.
*/
@VintfStability
@Backing(type="byte")
enum HdmiPortType {
INPUT = 0,
OUTPUT = 1,
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.hdmi;
import android.hardware.tv.hdmi.HdmiPortInfo;
import android.hardware.tv.hdmi.IHdmiCallback;
/**
* HDMI HAL interface definition.
*/
@VintfStability
interface IHdmi {
/**
* Gets the hdmi port information of underlying hardware.
*
* @return The list of HDMI port information
*/
HdmiPortInfo[] getPortInfo();
/**
* Gets the connection status of the specified port.
*
* @param portId Port id to be inspected for the connection status.
* @return True if a device is connected, otherwise false. The HAL
* must watch for +5V power signal to determine the status.
*/
boolean isConnected(in int portId);
/**
* Sets a callback that HDMI HAL must later use for internal HDMI events
*
* @param callback Callback object to pass hdmi events to the system. The
* previously registered callback must be replaced with this one.
* setCallback(null) should deregister the callback.
*/
void setCallback(in IHdmiCallback callback);
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.tv.hdmi;
/**
* Callbacks from the HDMI HAL implementation to notify the system of new events.
*/
@VintfStability
oneway interface IHdmiCallback {
/**
* The callback function that must be called by HAL implementation to notify
* the system of new hotplug event.
*/
void onHotplugEvent(in boolean connected, in int portId);
}

View file

@ -0,0 +1,58 @@
// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package {
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_binary {
name: "android.hardware.tv.hdmi-service",
vintf_fragments: ["android.hardware.tv.hdmi-service.xml"],
relative_install_path: "hw",
vendor: true,
cflags: [
"-Wall",
"-Wextra",
],
init_rc: ["android.hardware.tv.hdmi-service.rc"],
srcs: [
"serviceMock.cpp",
"HdmiMock.cpp",
],
shared_libs: [
"libbinder_ndk",
"liblog",
"libbase",
"libutils",
"libhardware",
"libhidlbase",
"android.hardware.tv.hdmi-V1-ndk",
],
}
cc_fuzz {
name: "android.hardware.tv.hdmi-service_fuzzer",
defaults: ["service_fuzzer_defaults"],
static_libs: [
"android.hardware.tv.hdmi-V1-ndk",
"liblog",
],
srcs: [
"fuzzer.cpp",
"HdmiMock.cpp",
],
fuzz_config: {
componentid: 826094,
},
}

View file

@ -0,0 +1,178 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.tv.hdmi"
#include <android-base/logging.h>
#include <fcntl.h>
#include <utils/Log.h>
#include "HdmiMock.h"
using ndk::ScopedAStatus;
namespace android {
namespace hardware {
namespace tv {
namespace hdmi {
namespace implementation {
void HdmiMock::serviceDied(void* cookie) {
ALOGE("HdmiMock died");
auto hdmi = static_cast<HdmiMock*>(cookie);
hdmi->mHdmiThreadRun = false;
}
ScopedAStatus HdmiMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
*_aidl_return = mPortInfos;
return ScopedAStatus::ok();
}
ScopedAStatus HdmiMock::isConnected(int32_t portId, bool* _aidl_return) {
// Maintain port connection status and update on hotplug event
if (portId <= mTotalPorts && portId >= 1) {
*_aidl_return = mPortConnectionStatus[portId];
} else {
*_aidl_return = false;
}
return ScopedAStatus::ok();
}
ScopedAStatus HdmiMock::setCallback(const std::shared_ptr<IHdmiCallback>& callback) {
if (mCallback != nullptr) {
mCallback = nullptr;
}
if (callback != nullptr) {
mCallback = callback;
AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
mInputFile = open(HDMI_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
pthread_create(&mThreadId, NULL, __threadLoop, this);
pthread_setname_np(mThreadId, "hdmi_loop");
}
return ScopedAStatus::ok();
}
void* HdmiMock::__threadLoop(void* user) {
HdmiMock* const self = static_cast<HdmiMock*>(user);
self->threadLoop();
return 0;
}
int HdmiMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
if (msgCount <= 0 || !buf) {
return 0;
}
int ret = -1;
// Maybe blocked at driver
ret = read(mInputFile, buf, msgCount);
if (ret < 0) {
ALOGE("[halimp_aidl] read :%s failed, ret:%d\n", HDMI_MSG_IN_FIFO, ret);
return -1;
}
return ret;
}
void HdmiMock::printEventBuf(const char* msg_buf, int len) {
int i, size = 0;
const int bufSize = MESSAGE_BODY_MAX_LENGTH * 3;
// Use 2 characters for each byte in the message plus 1 space
char buf[bufSize] = {0};
// Messages longer than max length will be truncated.
for (i = 0; i < len && size < bufSize; i++) {
size += sprintf(buf + size, " %02x", msg_buf[i]);
}
ALOGD("[halimp_aidl] %s, msg:%.*s", __FUNCTION__, size, buf);
}
void HdmiMock::handleHotplugMessage(unsigned char* msgBuf) {
bool connected = ((msgBuf[3]) & 0xf) > 0;
int32_t portId = static_cast<uint32_t>(msgBuf[0] & 0xf);
if (portId > static_cast<int32_t>(mPortInfos.size())) {
ALOGD("[halimp_aidl] ignore hot plug message, id %x does not exist", portId);
return;
}
ALOGD("[halimp_aidl] hot plug port id %x, is connected %x", (msgBuf[0] & 0xf),
(msgBuf[3] & 0xf));
mPortConnectionStatus[portId] = connected;
if (mPortInfos[portId].type == HdmiPortType::OUTPUT) {
mPhysicalAddress = (connected ? 0xffff : ((msgBuf[1] << 8) | (msgBuf[2])));
mPortInfos[portId].physicalAddress = mPhysicalAddress;
ALOGD("[halimp_aidl] hot plug physical address %x", mPhysicalAddress);
}
if (mCallback != nullptr) {
mCallback->onHotplugEvent(connected, portId);
}
}
void HdmiMock::threadLoop() {
ALOGD("[halimp_aidl] threadLoop start.");
unsigned char msgBuf[MESSAGE_BODY_MAX_LENGTH];
int r = -1;
// Open the input pipe
while (mInputFile < 0) {
usleep(1000 * 1000);
mInputFile = open(HDMI_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
}
ALOGD("[halimp_aidl] file open ok, fd = %d.", mInputFile);
while (mHdmiThreadRun) {
memset(msgBuf, 0, sizeof(msgBuf));
// Try to get a message from dev.
// echo -n -e '\x04\x83' >> /dev/cec
r = readMessageFromFifo(msgBuf, MESSAGE_BODY_MAX_LENGTH);
if (r <= 1) {
// Ignore received ping messages
continue;
}
printEventBuf((const char*)msgBuf, r);
if (((msgBuf[0] >> 4) & 0xf) == 0xf) {
handleHotplugMessage(msgBuf);
}
}
ALOGD("[halimp_aidl] thread end.");
}
HdmiMock::HdmiMock() {
ALOGE("[halimp_aidl] Opening a virtual HDMI HAL for testing and virtual machine.");
mCallback = nullptr;
mPortInfos.resize(mTotalPorts);
mPortConnectionStatus.resize(mTotalPorts);
mPortInfos[0] = {.type = HdmiPortType::OUTPUT,
.portId = static_cast<uint32_t>(1),
.cecSupported = true,
.arcSupported = false,
.physicalAddress = mPhysicalAddress};
mPortConnectionStatus[0] = false;
mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
}
} // namespace implementation
} // namespace hdmi
} // namespace tv
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
#include <algorithm>
#include <vector>
using namespace std;
namespace android {
namespace hardware {
namespace tv {
namespace hdmi {
namespace implementation {
using ::aidl::android::hardware::tv::hdmi::BnHdmi;
using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
using ::aidl::android::hardware::tv::hdmi::HdmiPortType;
using ::aidl::android::hardware::tv::hdmi::IHdmi;
using ::aidl::android::hardware::tv::hdmi::IHdmiCallback;
#define HDMI_MSG_IN_FIFO "/dev/hdmi_in_pipe"
#define MESSAGE_BODY_MAX_LENGTH 4
struct HdmiMock : public BnHdmi {
HdmiMock();
::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
::ndk::ScopedAStatus setCallback(const std::shared_ptr<IHdmiCallback>& callback) override;
void printEventBuf(const char* msg_buf, int len);
private:
static void* __threadLoop(void* data);
void threadLoop();
int readMessageFromFifo(unsigned char* buf, int msgCount);
void handleHotplugMessage(unsigned char* msgBuf);
private:
static void serviceDied(void* cookie);
std::shared_ptr<IHdmiCallback> mCallback;
// Variables for the virtual HDMI hal impl
std::vector<HdmiPortInfo> mPortInfos;
std::vector<bool> mPortConnectionStatus;
// Port configuration
uint16_t mPhysicalAddress = 0xFFFF;
int mTotalPorts = 1;
// Testing variables
// Input file descriptor
int mInputFile;
bool mHdmiThreadRun = true;
pthread_t mThreadId = 0;
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
};
} // namespace implementation
} // namespace hdmi
} // Namespace tv
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,5 @@
service vendor.hdmi-default /vendor/bin/hw/android.hardware.tv.hdmi-service
interface aidl android.hardware.tv.hdmi.IHdmi/default
class hal
user system
group system

View file

@ -0,0 +1,10 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.tv.hdmi</name>
<version>1</version>
<interface>
<name>IHdmi</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <HdmiMock.h>
#include <fuzzbinder/libbinder_ndk_driver.h>
#include <fuzzer/FuzzedDataProvider.h>
using android::fuzzService;
using android::hardware::tv::hdmi::implementation::HdmiMock;
using ndk::SharedRefBase;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
auto hdmiAidl = SharedRefBase::make<HdmiMock>();
fuzzService(hdmiAidl->asBinder().get(), FuzzedDataProvider(data, size));
return 0;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.tv.hdmi-service-shim"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <hidl/HidlTransportSupport.h>
#include <utils/Log.h>
#include "HdmiMock.h"
using android::hardware::tv::hdmi::implementation::HdmiMock;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
std::shared_ptr<HdmiMock> hdmiAidl = ndk::SharedRefBase::make<HdmiMock>();
const std::string instance = std::string() + HdmiMock::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(hdmiAidl->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return 0;
}

View file

@ -0,0 +1,37 @@
// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package {
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_test {
name: "VtsHalTvHdmiAidlTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
srcs: ["VtsHalTvHdmiAidlTargetTest.cpp"],
static_libs: [
"android.hardware.tv.hdmi-V1-ndk",
],
shared_libs: [
"libbinder_ndk",
],
test_suites: [
"general-tests",
"vts",
],
disable_framework: true,
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "Hdmi_hal_test"
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
#include <aidl/android/hardware/tv/hdmi/BnHdmiCallback.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <gtest/gtest.h>
#include <log/log.h>
#include <sstream>
#include <vector>
using ::aidl::android::hardware::tv::hdmi::BnHdmiCallback;
using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
using ::aidl::android::hardware::tv::hdmi::HdmiPortType;
using ::aidl::android::hardware::tv::hdmi::IHdmi;
using ::aidl::android::hardware::tv::hdmi::IHdmiCallback;
using ::ndk::SpAIBinder;
#define INCORRECT_VENDOR_ID 0x00
#define TV_PHYSICAL_ADDRESS 0x0000
// The main test class for TV HDMI HAL.
class HdmiTest : public ::testing::TestWithParam<std::string> {
static void serviceDied(void* /* cookie */) { ALOGE("VtsHalTvCecAidlTargetTest died"); }
public:
void SetUp() override {
hdmi = IHdmi::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
ASSERT_NE(hdmi, nullptr);
ALOGI("%s: getService() for hdmi is %s", __func__, hdmi->isRemote() ? "remote" : "local");
hdmiCallback = ::ndk::SharedRefBase::make<HdmiCallback>();
ASSERT_NE(hdmiCallback, nullptr);
hdmiDeathRecipient =
ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
ASSERT_EQ(AIBinder_linkToDeath(hdmi->asBinder().get(), hdmiDeathRecipient.get(), 0),
STATUS_OK);
}
class HdmiCallback : public BnHdmiCallback {
public:
::ndk::ScopedAStatus onHotplugEvent(bool connected __unused, int32_t portId __unused) {
return ::ndk::ScopedAStatus::ok();
};
};
std::shared_ptr<IHdmi> hdmi;
std::shared_ptr<IHdmiCallback> hdmiCallback;
::ndk::ScopedAIBinder_DeathRecipient hdmiDeathRecipient;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HdmiTest);
INSTANTIATE_TEST_SUITE_P(PerInstance, HdmiTest,
testing::ValuesIn(android::getAidlHalInstanceNames(IHdmi::descriptor)),
android::PrintInstanceNameToString);
TEST_P(HdmiTest, SetCallback) {
ASSERT_TRUE(hdmi->setCallback(::ndk::SharedRefBase::make<HdmiCallback>()).isOk());
}
TEST_P(HdmiTest, GetPortInfo) {
std::vector<HdmiPortInfo> ports;
ASSERT_TRUE(hdmi->getPortInfo(&ports).isOk());
bool cecSupportedOnDevice = false;
for (size_t i = 0; i < ports.size(); ++i) {
EXPECT_TRUE((ports[i].type == HdmiPortType::OUTPUT) ||
(ports[i].type == HdmiPortType::INPUT));
if (ports[i].portId == 0) {
ALOGW("%s: Port id should start from 1", __func__);
}
cecSupportedOnDevice = cecSupportedOnDevice | ports[i].cecSupported;
}
EXPECT_NE(cecSupportedOnDevice, false) << "At least one port should support CEC";
}
TEST_P(HdmiTest, IsConnected) {
std::vector<HdmiPortInfo> ports;
ASSERT_TRUE(hdmi->getPortInfo(&ports).isOk());
for (size_t i = 0; i < ports.size(); ++i) {
bool connected;
ASSERT_TRUE(hdmi->isConnected(ports[i].portId, &connected).isOk());
}
}