diff options
author | Jinsuk Kim <jinsukkim@google.com> | 2014-03-21 16:25:13 +0900 |
---|---|---|
committer | Jinsuk Kim <jinsukkim@google.com> | 2014-03-24 08:19:39 +0900 |
commit | fbcd503645d9527fd7c700b3e4e8f170c46a7eba (patch) | |
tree | a29ad0d386c9c703d1fbdba8d778defe9767f770 | |
parent | d73e66cce12f13faec44b12d9e6f33c2f28a2d5a (diff) | |
download | frameworks_base-fbcd503645d9527fd7c700b3e4e8f170c46a7eba.zip frameworks_base-fbcd503645d9527fd7c700b3e4e8f170c46a7eba.tar.gz frameworks_base-fbcd503645d9527fd7c700b3e4e8f170c46a7eba.tar.bz2 |
Add HdmiCecManager
Introduces HdmiCecManager/HdmiCecClient to provide apps/system components
with the way to access HdmiCecService via Context.getSystemService(HDMI_CEC_SERVICE).
Change-Id: I39da071a328074a4b7b049947943688bd7779c26
-rw-r--r-- | api/current.txt | 82 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 9 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 12 | ||||
-rw-r--r-- | core/java/android/hardware/hdmi/HdmiCec.java | 63 | ||||
-rw-r--r-- | core/java/android/hardware/hdmi/HdmiCecClient.java | 125 | ||||
-rw-r--r-- | core/java/android/hardware/hdmi/HdmiCecManager.java | 73 | ||||
-rw-r--r-- | services/core/java/com/android/server/hdmi/HdmiCecService.java | 7 |
7 files changed, 364 insertions, 7 deletions
diff --git a/api/current.txt b/api/current.txt index 1b0cb3f..6378946 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5994,6 +5994,7 @@ package android.content { field public static final java.lang.String DISPLAY_SERVICE = "display"; field public static final java.lang.String DOWNLOAD_SERVICE = "download"; field public static final java.lang.String DROPBOX_SERVICE = "dropbox"; + field public static final java.lang.String HDMI_CEC_SERVICE = "hdmi_cec"; field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; field public static final java.lang.String INPUT_SERVICE = "input"; field public static final java.lang.String KEYGUARD_SERVICE = "keyguard"; @@ -10940,7 +10941,86 @@ package android.hardware.hdmi { field public static final int DEVICE_RESERVED = 2; // 0x2 field public static final int DEVICE_TUNER = 3; // 0x3 field public static final int DEVICE_TV = 0; // 0x0 - field public static final int MESSAGE_ACTIVE_SOURCE = 157; // 0x9d + field public static final int MESSAGE_ABORT = 255; // 0xff + field public static final int MESSAGE_ACTIVE_SOURCE = 130; // 0x82 + field public static final int MESSAGE_CEC_VERSION = 158; // 0x9e + field public static final int MESSAGE_CLEAR_ANALOG_TIMER = 51; // 0x33 + field public static final int MESSAGE_CLEAR_DIGITAL_TIMER = 153; // 0x99 + field public static final int MESSAGE_CLEAR_EXTERNAL_TIMER = 161; // 0xa1 + field public static final int MESSAGE_DECK_CONTROL = 66; // 0x42 + field public static final int MESSAGE_DECK_STATUS = 27; // 0x1b + field public static final int MESSAGE_DEVICE_VENDOR_ID = 135; // 0x87 + field public static final int MESSAGE_FEATURE_ABORT = 0; // 0x0 + field public static final int MESSAGE_GET_CEC_VERSION = 159; // 0x9f + field public static final int MESSAGE_GET_MENU_LANGUAGE = 145; // 0x91 + field public static final int MESSAGE_GET_OSD_NAME = 70; // 0x46 + field public static final int MESSAGE_GIVE_AUDIO_STATUS = 113; // 0x71 + field public static final int MESSAGE_GIVE_DECK_STATUS = 26; // 0x1a + field public static final int MESSAGE_GIVE_DEVICE_POWER_STATUS = 143; // 0x8f + field public static final int MESSAGE_GIVE_DEVICE_VENDOR_ID = 140; // 0x8c + field public static final int MESSAGE_GIVE_PHYSICAL_ADDRESS = 131; // 0x83 + field public static final int MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 125; // 0x7d + field public static final int MESSAGE_GIVE_TUNER_DEVICE_STATUS = 8; // 0x8 + field public static final int MESSAGE_IMAGE_VIEW_ON = 4; // 0x4 + field public static final int MESSAGE_INACTIVE_SOURCE = 157; // 0x9d + field public static final int MESSAGE_MENU_REQUEST = 141; // 0x8d + field public static final int MESSAGE_MENU_STATUS = 142; // 0x8e + field public static final int MESSAGE_PLAY = 65; // 0x41 + field public static final int MESSAGE_RECORD_OFF = 11; // 0xb + field public static final int MESSAGE_RECORD_ON = 9; // 0x9 + field public static final int MESSAGE_RECORD_STATUS = 10; // 0xa + field public static final int MESSAGE_RECORD_TV_SCREEN = 15; // 0xf + field public static final int MESSAGE_REPORT_AUDIO_STATUS = 122; // 0x7a + field public static final int MESSAGE_REPORT_PHYSICAL_ADDRESS = 132; // 0x84 + field public static final int MESSAGE_REPORT_POWER_STATUS = 144; // 0x90 + field public static final int MESSAGE_REQUEST_ACTIVE_SOURCE = 133; // 0x85 + field public static final int MESSAGE_ROUTING_CHANGE = 128; // 0x80 + field public static final int MESSAGE_ROUTING_INFORMATION = 129; // 0x81 + field public static final int MESSAGE_SELECT_ANALOG_SERVICE = 146; // 0x92 + field public static final int MESSAGE_SELECT_DIGITAL_SERVICE = 147; // 0x93 + field public static final int MESSAGE_SET_ANALOG_TIMER = 52; // 0x34 + field public static final int MESSAGE_SET_AUDIO_RATE = 154; // 0x9a + field public static final int MESSAGE_SET_DIGITAL_TIMER = 151; // 0x97 + field public static final int MESSAGE_SET_EXTERNAL_TIMER = 162; // 0xa2 + field public static final int MESSAGE_SET_MENU_LANGUAGE = 50; // 0x32 + field public static final int MESSAGE_SET_OSD_NAME = 71; // 0x47 + field public static final int MESSAGE_SET_OSD_STRING = 100; // 0x64 + field public static final int MESSAGE_SET_STREAM_PATH = 134; // 0x86 + field public static final int MESSAGE_SET_SYSTEM_AUDIO_MODE = 114; // 0x72 + field public static final int MESSAGE_SET_TIMER_PROGRAM_TITLE = 103; // 0x67 + field public static final int MESSAGE_STANDBY = 54; // 0x36 + field public static final int MESSAGE_SYSTEM_AUDIO_MODE_REQUEST = 112; // 0x70 + field public static final int MESSAGE_SYSTEM_AUDIO_MODE_STATUS = 126; // 0x7e + field public static final int MESSAGE_TEXT_VIEW_ON = 13; // 0xd + field public static final int MESSAGE_TIMER_CLEARED_STATUS = 67; // 0x43 + field public static final int MESSAGE_TIMER_STATUS = 53; // 0x35 + field public static final int MESSAGE_TUNER_DEVICE_STATUS = 7; // 0x7 + field public static final int MESSAGE_TUNER_STEP_DECREMENT = 6; // 0x6 + field public static final int MESSAGE_TUNER_STEP_INCREMENT = 5; // 0x5 + field public static final int MESSAGE_USER_CONTROL_PRESSED = 68; // 0x44 + field public static final int MESSAGE_USER_CONTROL_RELEASED = 69; // 0x45 + field public static final int MESSAGE_VENDOR_COMMAND = 137; // 0x89 + field public static final int MESSAGE_VENDOR_COMMAND_WITH_ID = 160; // 0xa0 + field public static final int MESSAGE_VENDOR_REMOTE_BUTTON_DOWN = 138; // 0x8a + field public static final int MESSAGE_VENDOR_REMOTE_BUTTON_UP = 139; // 0x8b + } + + public final class HdmiCecClient { + method public void sendActiveSource(); + method public void sendGiveDevicePowerStatus(int); + method public void sendImageViewOn(); + method public void sendInactiveSource(); + method public void sendTextViewOn(); + } + + public static abstract class HdmiCecClient.Listener { + ctor public HdmiCecClient.Listener(); + method public void onCableStatusChanged(boolean); + method public void onMessageReceived(android.hardware.hdmi.HdmiCecMessage); + } + + public final class HdmiCecManager { + method public android.hardware.hdmi.HdmiCecClient getClient(int, android.hardware.hdmi.HdmiCecClient.Listener); } public final class HdmiCecMessage implements android.os.Parcelable { diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index d9cad3b..bb46197 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -51,6 +51,8 @@ import android.hardware.ConsumerIrManager; import android.hardware.ISerialManager; import android.hardware.SerialManager; import android.hardware.SystemSensorManager; +import android.hardware.hdmi.HdmiCecManager; +import android.hardware.hdmi.IHdmiCecService; import android.hardware.camera2.CameraManager; import android.hardware.display.DisplayManager; import android.hardware.input.InputManager; @@ -357,6 +359,13 @@ class ContextImpl extends Context { return new BluetoothManager(ctx); }}); + registerService(HDMI_CEC_SERVICE, new StaticServiceFetcher() { + public Object createStaticService() { + IBinder b = ServiceManager.getService(HDMI_CEC_SERVICE); + return new HdmiCecManager(IHdmiCecService.Stub.asInterface(b)); + }}); + + registerService(CLIPBOARD_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new ClipboardManager(ctx.getOuterContext(), diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 2e4e209..f4b1afe 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1974,6 +1974,8 @@ public abstract class Context { * @see android.app.SearchManager * @see #SENSOR_SERVICE * @see android.hardware.SensorManager + * @see #HDMI_CEC_SERVICE + * @see android.hardware.hdmi.HdmiCecManager * @see #STORAGE_SERVICE * @see android.os.storage.StorageManager * @see #VIBRATOR_SERVICE @@ -2389,6 +2391,16 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a + * {@link android.hardware.hdmi.HdmiCecManager for controlling and managing + * HDMI-CEC protocol. + * + * @see #getSystemService + * @see android.hardware.hdmi.HdmiCecManager + */ + public static final String HDMI_CEC_SERVICE = "hdmi_cec"; + + /** + * Use with {@link #getSystemService} to retrieve a * {@link android.hardware.input.InputManager} for interacting with input devices. * * @see #getSystemService diff --git a/core/java/android/hardware/hdmi/HdmiCec.java b/core/java/android/hardware/hdmi/HdmiCec.java index c95431a..38d9de4 100644 --- a/core/java/android/hardware/hdmi/HdmiCec.java +++ b/core/java/android/hardware/hdmi/HdmiCec.java @@ -97,7 +97,68 @@ public final class HdmiCec { public static final int ADDR_INVALID = -1; // TODO: Complete the list of CEC messages definition. - public static final int MESSAGE_ACTIVE_SOURCE = 0x9D; + public static final int MESSAGE_FEATURE_ABORT = 0x00; + public static final int MESSAGE_IMAGE_VIEW_ON = 0x04; + public static final int MESSAGE_TUNER_STEP_INCREMENT = 0x05; + public static final int MESSAGE_TUNER_STEP_DECREMENT = 0x06; + public static final int MESSAGE_TUNER_DEVICE_STATUS = 0x07; + public static final int MESSAGE_GIVE_TUNER_DEVICE_STATUS = 0x08; + public static final int MESSAGE_RECORD_ON = 0x09; + public static final int MESSAGE_RECORD_STATUS = 0x0A; + public static final int MESSAGE_RECORD_OFF = 0x0B; + public static final int MESSAGE_TEXT_VIEW_ON = 0x0D; + public static final int MESSAGE_RECORD_TV_SCREEN = 0x0F; + public static final int MESSAGE_GIVE_DECK_STATUS = 0x1A; + public static final int MESSAGE_DECK_STATUS = 0x1B; + public static final int MESSAGE_SET_MENU_LANGUAGE = 0x32; + public static final int MESSAGE_CLEAR_ANALOG_TIMER = 0x33; + public static final int MESSAGE_SET_ANALOG_TIMER = 0x34; + public static final int MESSAGE_TIMER_STATUS = 0x35; + public static final int MESSAGE_STANDBY = 0x36; + public static final int MESSAGE_PLAY = 0x41; + public static final int MESSAGE_DECK_CONTROL = 0x42; + public static final int MESSAGE_TIMER_CLEARED_STATUS = 0x043; + public static final int MESSAGE_USER_CONTROL_PRESSED = 0x44; + public static final int MESSAGE_USER_CONTROL_RELEASED = 0x45; + public static final int MESSAGE_GET_OSD_NAME = 0x46; + public static final int MESSAGE_SET_OSD_NAME = 0x47; + public static final int MESSAGE_SET_OSD_STRING = 0x64; + public static final int MESSAGE_SET_TIMER_PROGRAM_TITLE = 0x67; + public static final int MESSAGE_SYSTEM_AUDIO_MODE_REQUEST = 0x70; + public static final int MESSAGE_GIVE_AUDIO_STATUS = 0x71; + public static final int MESSAGE_SET_SYSTEM_AUDIO_MODE = 0x72; + public static final int MESSAGE_REPORT_AUDIO_STATUS = 0x7A; + public static final int MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D; + public static final int MESSAGE_SYSTEM_AUDIO_MODE_STATUS = 0x7E; + public static final int MESSAGE_ROUTING_CHANGE = 0x80; + public static final int MESSAGE_ROUTING_INFORMATION = 0x81; + public static final int MESSAGE_ACTIVE_SOURCE = 0x82; + public static final int MESSAGE_GIVE_PHYSICAL_ADDRESS = 0x83; + public static final int MESSAGE_REPORT_PHYSICAL_ADDRESS = 0x84; + public static final int MESSAGE_REQUEST_ACTIVE_SOURCE = 0x85; + public static final int MESSAGE_SET_STREAM_PATH = 0x86; + public static final int MESSAGE_DEVICE_VENDOR_ID = 0x87; + public static final int MESSAGE_VENDOR_COMMAND = 0x89; + public static final int MESSAGE_VENDOR_REMOTE_BUTTON_DOWN = 0x8A; + public static final int MESSAGE_VENDOR_REMOTE_BUTTON_UP = 0x8B; + public static final int MESSAGE_GIVE_DEVICE_VENDOR_ID = 0x8C; + public static final int MESSAGE_MENU_REQUEST = 0x8D; + public static final int MESSAGE_MENU_STATUS = 0x8E; + public static final int MESSAGE_GIVE_DEVICE_POWER_STATUS = 0x8F; + public static final int MESSAGE_REPORT_POWER_STATUS = 0x90; + public static final int MESSAGE_GET_MENU_LANGUAGE = 0x91; + public static final int MESSAGE_SELECT_ANALOG_SERVICE = 0x92; + public static final int MESSAGE_SELECT_DIGITAL_SERVICE = 0x93; + public static final int MESSAGE_SET_DIGITAL_TIMER = 0x97; + public static final int MESSAGE_CLEAR_DIGITAL_TIMER = 0x99; + public static final int MESSAGE_SET_AUDIO_RATE = 0x9A; + public static final int MESSAGE_INACTIVE_SOURCE = 0x9D; + public static final int MESSAGE_CEC_VERSION = 0x9E; + public static final int MESSAGE_GET_CEC_VERSION = 0x9F; + public static final int MESSAGE_VENDOR_COMMAND_WITH_ID = 0xA0; + public static final int MESSAGE_CLEAR_EXTERNAL_TIMER = 0xA1; + public static final int MESSAGE_SET_EXTERNAL_TIMER = 0xA2; + public static final int MESSAGE_ABORT = 0xFF; private static final int[] ADDRESS_TO_TYPE = { DEVICE_TV, // ADDR_TV diff --git a/core/java/android/hardware/hdmi/HdmiCecClient.java b/core/java/android/hardware/hdmi/HdmiCecClient.java new file mode 100644 index 0000000..d7f4a72 --- /dev/null +++ b/core/java/android/hardware/hdmi/HdmiCecClient.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 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.hdmi; + +import android.os.IBinder; +import android.os.RemoteException; + +import android.util.Log; + +/** + * HdmiCecClient is used to control HDMI-CEC logical device instance in the system. + * It is connected to actual hardware part via HdmiCecService. It provides with methods + * to send CEC messages to other device on the bus, and listener that allows to receive + * incoming messages to the device. + */ +public final class HdmiCecClient { + private static final String TAG = "HdmiCecClient"; + + private final IHdmiCecService mService; + private final IBinder mBinder; + + /** + * Listener used by the client to get the incoming messages. + */ + public static abstract class Listener { + /** + * Called when CEC message arrives. Override this method to receive the incoming + * CEC messages from other device on the bus. + * + * @param message {@link HdmiCecMessage} object + */ + public void onMessageReceived(HdmiCecMessage message) { } + + /** + * Called when hotplug event occurs. Override this method to receive the events. + * + * @param connected true if the cable is connected; otherwise false. + */ + public void onCableStatusChanged(boolean connected) { } + } + + // Private constructor. + private HdmiCecClient(IHdmiCecService service, IBinder b) { + mService = service; + mBinder = b; + } + + // Factory method for HdmiCecClient. + // Declared package-private. Accessed by HdmiCecManager only. + static HdmiCecClient create(IHdmiCecService service, IBinder b) { + return new HdmiCecClient(service, b); + } + + /** + * Send <Active Source> message. + */ + public void sendActiveSource() { + try { + mService.sendActiveSource(mBinder); + } catch (RemoteException e) { + Log.e(TAG, "sendActiveSource threw exception ", e); + } + } + + /** + * Send <Inactive Source> message. + */ + public void sendInactiveSource() { + try { + mService.sendInactiveSource(mBinder); + } catch (RemoteException e) { + Log.e(TAG, "sendInactiveSource threw exception ", e); + } + } + + /** + * Send <TextViewOn> message. + */ + public void sendTextViewOn() { + try { + mService.sendTextViewOn(mBinder); + } catch (RemoteException e) { + Log.e(TAG, "sendTextViewOn threw exception ", e); + } + } + + /** + * Send <ImageViewOn> message. + */ + public void sendImageViewOn() { + try { + mService.sendImageViewOn(mBinder); + } catch (RemoteException e) { + Log.e(TAG, "sendImageViewOn threw exception ", e); + } + } + + /** + * Send <GiveDevicePowerStatus> message. + * + * @param address logical address of the device to send the message to, such as + * {@link HdmiCec#ADDR_TV}. + */ + public void sendGiveDevicePowerStatus(int address) { + try { + mService.sendGiveDevicePowerStatus(mBinder, address); + } catch (RemoteException e) { + Log.e(TAG, "sendGiveDevicePowerStatus threw exception ", e); + } + } +} diff --git a/core/java/android/hardware/hdmi/HdmiCecManager.java b/core/java/android/hardware/hdmi/HdmiCecManager.java new file mode 100644 index 0000000..575785d --- /dev/null +++ b/core/java/android/hardware/hdmi/HdmiCecManager.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 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.hdmi; + +import android.os.IBinder; +import android.os.RemoteException; + +/** + * The HdmiCecManager class is used to provide an HdmiCecClient instance, + * get various information on HDMI ports configuration. It is connected to actual hardware + * via HdmiCecService. + */ +public final class HdmiCecManager { + private final IHdmiCecService mService; + + /** + * @hide - hide this constructor because it has a parameter of type IHdmiCecService, + * which is a system private class. The right way to create an instance of this class + * is using the factory Context.getSystemService. + */ + public HdmiCecManager(IHdmiCecService service) { + mService = service; + } + + /** + * Provide the HdmiCecClient instance of the given type. It also registers the listener + * for client to get the events coming to the device. + * + * @param type type of the HDMI-CEC logical device + * @param listener listener to be called + * @return {@link HdmiCecClient} instance. {@code null} on failure. + */ + public HdmiCecClient getClient(int type, HdmiCecClient.Listener listener) { + try { + IBinder b = mService.allocateLogicalDevice(type, getListenerWrapper(listener)); + return HdmiCecClient.create(mService, b); + } catch (RemoteException e) { + return null; + } + } + + private IHdmiCecListener getListenerWrapper(final HdmiCecClient.Listener listener) { + // TODO: The message/events are not yet forwarded to client since it is not clearly + // defined as to how/who to handle them. Revisit it once the decision is + // made on what messages will have to reach the clients, what will be + // handled by service/manager. + return new IHdmiCecListener.Stub() { + @Override + public void onMessageReceived(HdmiCecMessage message) { + // Do nothing. + } + + @Override + public void onCableStatusChanged(boolean connected) { + // Do nothing. + } + }; + } +} diff --git a/services/core/java/com/android/server/hdmi/HdmiCecService.java b/services/core/java/com/android/server/hdmi/HdmiCecService.java index 01f2ec3..36a6e84 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecService.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecService.java @@ -63,10 +63,6 @@ public final class HdmiCecService extends SystemService { private static final String PERMISSION = "android.permission.HDMI_CEC"; - // Service name under which it is registered to service manager. - // TODO: Move this to Context once HdmiCecManager is introduced. - private static final String HDMI_CEC_SERVICE = "hdmi_cec"; - public HdmiCecService(Context context) { super(context); } @@ -76,7 +72,7 @@ public final class HdmiCecService extends SystemService { @Override public void onStart() { mNativePtr = nativeInit(this); - publishBinderService(HDMI_CEC_SERVICE, new BinderService()); + publishBinderService(Context.HDMI_CEC_SERVICE, new BinderService()); } /** @@ -143,6 +139,7 @@ public final class HdmiCecService extends SystemService { * <Set Osd Name> in response. */ private byte[] getOsdName(int type) { + // TODO: Consider getting the OSD name from device name instead. synchronized (mLock) { HdmiCecDevice device = mLogicalDevices.get(type); if (device != null) { |