Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/hdmi/IHdmiControlService.aidl \ core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl \ core/java/android/hardware/hdmi/IHdmiHotplugEventListener.aidl \ core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl \ core/java/android/hardware/input/IInputManager.aidl \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/location/IFusedLocationHardware.aidl \ Loading core/java/android/hardware/hdmi/IHdmiControlService.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.hdmi.HdmiPortInfo; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.IHdmiDeviceEventListener; import android.hardware.hdmi.IHdmiHotplugEventListener; import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener; import java.util.List; Loading @@ -42,4 +43,9 @@ interface IHdmiControlService { void portSelect(int portId, IHdmiControlCallback callback); void sendKeyEvent(int keyCode, boolean isPressed); List<HdmiPortInfo> getPortInfo(); boolean canChangeSystemAudioMode(); boolean getSystemAudioMode(); void setSystemAudioMode(boolean enabled, IHdmiControlCallback callback); void addSystemAudioModeChangeListener(IHdmiSystemAudioModeChangeListener listener); void removeSystemAudioModeChangeListener(IHdmiSystemAudioModeChangeListener listener); } core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * 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; /** * Callback interface definition for HDMI client to get informed of * "System Audio" mode change. * * @hide */ oneway interface IHdmiSystemAudioModeChangeListener { /** * @param enabled true if the device gets activated */ void onStatusChanged(in boolean enabled); } services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +18 −3 Original line number Diff line number Diff line Loading @@ -253,20 +253,35 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { mDeviceInfos.clear(); } void changeSystemAudioMode(boolean enabled, IHdmiControlCallback callback) { assertRunOnServiceThread(); HdmiCecDeviceInfo avr = getAvrDeviceInfo(); if (avr == null) { invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } addAndStartAction( new SystemAudioActionFromTv(this, avr.getLogicalAddress(), enabled, callback)); } boolean canChangeSystemAudioMode() { // TODO: once have immutable device info, test whether avr info exists or not. return false; } void setSystemAudioMode(boolean on) { synchronized (mLock) { if (on != mSystemAudioMode) { mSystemAudioMode = on; // TODO: Need to set the preference for SystemAudioMode. // TODO: Need to handle the notification of changing the mode and // to identify the notification should be handled in the service or TvSettings. mService.announceSystemAudioModeChange(on); } } } boolean getSystemAudioMode() { synchronized (mLock) { assertRunOnServiceThread(); return mSystemAudioMode; } } Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +122 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.IHdmiControlService; import android.hardware.hdmi.IHdmiDeviceEventListener; import android.hardware.hdmi.IHdmiHotplugEventListener; import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; Loading Loading @@ -113,6 +114,14 @@ public final class HdmiControlService extends SystemService { private final ArrayList<DeviceEventListenerRecord> mDeviceEventListenerRecords = new ArrayList<>(); // List of listeners registered by callers that want to get notified of // system audio mode changes. private final ArrayList<IHdmiSystemAudioModeChangeListener> mSystemAudioModeChangeListeners = new ArrayList<>(); // List of records for system audio mode change to handle the the caller killed in action. private final ArrayList<SystemAudioModeChangeListenerRecord> mSystemAudioModeChangeListenerRecords = new ArrayList<>(); // Handler used to run a task in service thread. private final Handler mHandler = new Handler(); Loading Loading @@ -447,6 +456,12 @@ public final class HdmiControlService extends SystemService { // TODO: Hook up with AudioManager. } void announceSystemAudioModeChange(boolean enabled) { for (IHdmiSystemAudioModeChangeListener listener : mSystemAudioModeChangeListeners) { invokeSystemAudioModeChange(listener, enabled); } } private HdmiCecDeviceInfo createDeviceInfo(int logicalAddress, int deviceType) { // TODO: find better name instead of model name. String displayName = Build.MODEL; Loading Loading @@ -488,6 +503,22 @@ public final class HdmiControlService extends SystemService { } } private final class SystemAudioModeChangeListenerRecord implements IBinder.DeathRecipient { private IHdmiSystemAudioModeChangeListener mListener; public SystemAudioModeChangeListenerRecord(IHdmiSystemAudioModeChangeListener listener) { mListener = listener; } @Override public void binderDied() { synchronized (mLock) { mSystemAudioModeChangeListenerRecords.remove(this); mSystemAudioModeChangeListeners.remove(mListener); } } } private void enforceAccessPermission() { getContext().enforceCallingOrSelfPermission(PERMISSION, TAG); } Loading Loading @@ -616,6 +647,57 @@ public final class HdmiControlService extends SystemService { enforceAccessPermission(); return mPortInfo; } @Override public boolean canChangeSystemAudioMode() { enforceAccessPermission(); HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { return false; } return tv.canChangeSystemAudioMode(); } @Override public boolean getSystemAudioMode() { enforceAccessPermission(); HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { return false; } return tv.getSystemAudioMode(); } @Override public void setSystemAudioMode(final boolean enabled, final IHdmiControlCallback callback) { enforceAccessPermission(); runOnServiceThread(new Runnable() { @Override public void run() { HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { Slog.w(TAG, "Local tv device not available"); invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } tv.changeSystemAudioMode(enabled, callback); } }); } @Override public void addSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); HdmiControlService.this.addSystemAudioModeChangeListner(listener); } @Override public void removeSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); HdmiControlService.this.removeSystemAudioModeChangeListener(listener); } } private void oneTouchPlay(final IHdmiControlCallback callback) { Loading Loading @@ -693,6 +775,35 @@ public final class HdmiControlService extends SystemService { } } private void addSystemAudioModeChangeListner(IHdmiSystemAudioModeChangeListener listener) { SystemAudioModeChangeListenerRecord record = new SystemAudioModeChangeListenerRecord( listener); try { listener.asBinder().linkToDeath(record, 0); } catch (RemoteException e) { Slog.w(TAG, "Listener already died"); return; } synchronized (mLock) { mSystemAudioModeChangeListeners.add(listener); mSystemAudioModeChangeListenerRecords.add(record); } } private void removeSystemAudioModeChangeListener(IHdmiSystemAudioModeChangeListener listener) { synchronized (mLock) { for (SystemAudioModeChangeListenerRecord record : mSystemAudioModeChangeListenerRecords) { if (record.mListener.asBinder() == listener) { listener.asBinder().unlinkToDeath(record, 0); mSystemAudioModeChangeListenerRecords.remove(record); break; } } mSystemAudioModeChangeListeners.remove(listener); } } private void invokeCallback(IHdmiControlCallback callback, int result) { try { callback.onComplete(result); Loading @@ -701,6 +812,15 @@ public final class HdmiControlService extends SystemService { } } private void invokeSystemAudioModeChange(IHdmiSystemAudioModeChangeListener listener, boolean enabled) { try { listener.onStatusChanged(enabled); } catch (RemoteException e) { Slog.e(TAG, "Invoking callback failed:" + e); } } private void announceHotplugEvent(int portId, boolean connected) { HdmiHotplugEvent event = new HdmiHotplugEvent(portId, connected); synchronized (mLock) { Loading Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/hdmi/IHdmiControlService.aidl \ core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl \ core/java/android/hardware/hdmi/IHdmiHotplugEventListener.aidl \ core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl \ core/java/android/hardware/input/IInputManager.aidl \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/location/IFusedLocationHardware.aidl \ Loading
core/java/android/hardware/hdmi/IHdmiControlService.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.hdmi.HdmiPortInfo; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.IHdmiDeviceEventListener; import android.hardware.hdmi.IHdmiHotplugEventListener; import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener; import java.util.List; Loading @@ -42,4 +43,9 @@ interface IHdmiControlService { void portSelect(int portId, IHdmiControlCallback callback); void sendKeyEvent(int keyCode, boolean isPressed); List<HdmiPortInfo> getPortInfo(); boolean canChangeSystemAudioMode(); boolean getSystemAudioMode(); void setSystemAudioMode(boolean enabled, IHdmiControlCallback callback); void addSystemAudioModeChangeListener(IHdmiSystemAudioModeChangeListener listener); void removeSystemAudioModeChangeListener(IHdmiSystemAudioModeChangeListener listener); }
core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * 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; /** * Callback interface definition for HDMI client to get informed of * "System Audio" mode change. * * @hide */ oneway interface IHdmiSystemAudioModeChangeListener { /** * @param enabled true if the device gets activated */ void onStatusChanged(in boolean enabled); }
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +18 −3 Original line number Diff line number Diff line Loading @@ -253,20 +253,35 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { mDeviceInfos.clear(); } void changeSystemAudioMode(boolean enabled, IHdmiControlCallback callback) { assertRunOnServiceThread(); HdmiCecDeviceInfo avr = getAvrDeviceInfo(); if (avr == null) { invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } addAndStartAction( new SystemAudioActionFromTv(this, avr.getLogicalAddress(), enabled, callback)); } boolean canChangeSystemAudioMode() { // TODO: once have immutable device info, test whether avr info exists or not. return false; } void setSystemAudioMode(boolean on) { synchronized (mLock) { if (on != mSystemAudioMode) { mSystemAudioMode = on; // TODO: Need to set the preference for SystemAudioMode. // TODO: Need to handle the notification of changing the mode and // to identify the notification should be handled in the service or TvSettings. mService.announceSystemAudioModeChange(on); } } } boolean getSystemAudioMode() { synchronized (mLock) { assertRunOnServiceThread(); return mSystemAudioMode; } } Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +122 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.IHdmiControlService; import android.hardware.hdmi.IHdmiDeviceEventListener; import android.hardware.hdmi.IHdmiHotplugEventListener; import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; Loading Loading @@ -113,6 +114,14 @@ public final class HdmiControlService extends SystemService { private final ArrayList<DeviceEventListenerRecord> mDeviceEventListenerRecords = new ArrayList<>(); // List of listeners registered by callers that want to get notified of // system audio mode changes. private final ArrayList<IHdmiSystemAudioModeChangeListener> mSystemAudioModeChangeListeners = new ArrayList<>(); // List of records for system audio mode change to handle the the caller killed in action. private final ArrayList<SystemAudioModeChangeListenerRecord> mSystemAudioModeChangeListenerRecords = new ArrayList<>(); // Handler used to run a task in service thread. private final Handler mHandler = new Handler(); Loading Loading @@ -447,6 +456,12 @@ public final class HdmiControlService extends SystemService { // TODO: Hook up with AudioManager. } void announceSystemAudioModeChange(boolean enabled) { for (IHdmiSystemAudioModeChangeListener listener : mSystemAudioModeChangeListeners) { invokeSystemAudioModeChange(listener, enabled); } } private HdmiCecDeviceInfo createDeviceInfo(int logicalAddress, int deviceType) { // TODO: find better name instead of model name. String displayName = Build.MODEL; Loading Loading @@ -488,6 +503,22 @@ public final class HdmiControlService extends SystemService { } } private final class SystemAudioModeChangeListenerRecord implements IBinder.DeathRecipient { private IHdmiSystemAudioModeChangeListener mListener; public SystemAudioModeChangeListenerRecord(IHdmiSystemAudioModeChangeListener listener) { mListener = listener; } @Override public void binderDied() { synchronized (mLock) { mSystemAudioModeChangeListenerRecords.remove(this); mSystemAudioModeChangeListeners.remove(mListener); } } } private void enforceAccessPermission() { getContext().enforceCallingOrSelfPermission(PERMISSION, TAG); } Loading Loading @@ -616,6 +647,57 @@ public final class HdmiControlService extends SystemService { enforceAccessPermission(); return mPortInfo; } @Override public boolean canChangeSystemAudioMode() { enforceAccessPermission(); HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { return false; } return tv.canChangeSystemAudioMode(); } @Override public boolean getSystemAudioMode() { enforceAccessPermission(); HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { return false; } return tv.getSystemAudioMode(); } @Override public void setSystemAudioMode(final boolean enabled, final IHdmiControlCallback callback) { enforceAccessPermission(); runOnServiceThread(new Runnable() { @Override public void run() { HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { Slog.w(TAG, "Local tv device not available"); invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } tv.changeSystemAudioMode(enabled, callback); } }); } @Override public void addSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); HdmiControlService.this.addSystemAudioModeChangeListner(listener); } @Override public void removeSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); HdmiControlService.this.removeSystemAudioModeChangeListener(listener); } } private void oneTouchPlay(final IHdmiControlCallback callback) { Loading Loading @@ -693,6 +775,35 @@ public final class HdmiControlService extends SystemService { } } private void addSystemAudioModeChangeListner(IHdmiSystemAudioModeChangeListener listener) { SystemAudioModeChangeListenerRecord record = new SystemAudioModeChangeListenerRecord( listener); try { listener.asBinder().linkToDeath(record, 0); } catch (RemoteException e) { Slog.w(TAG, "Listener already died"); return; } synchronized (mLock) { mSystemAudioModeChangeListeners.add(listener); mSystemAudioModeChangeListenerRecords.add(record); } } private void removeSystemAudioModeChangeListener(IHdmiSystemAudioModeChangeListener listener) { synchronized (mLock) { for (SystemAudioModeChangeListenerRecord record : mSystemAudioModeChangeListenerRecords) { if (record.mListener.asBinder() == listener) { listener.asBinder().unlinkToDeath(record, 0); mSystemAudioModeChangeListenerRecords.remove(record); break; } } mSystemAudioModeChangeListeners.remove(listener); } } private void invokeCallback(IHdmiControlCallback callback, int result) { try { callback.onComplete(result); Loading @@ -701,6 +812,15 @@ public final class HdmiControlService extends SystemService { } } private void invokeSystemAudioModeChange(IHdmiSystemAudioModeChangeListener listener, boolean enabled) { try { listener.onStatusChanged(enabled); } catch (RemoteException e) { Slog.e(TAG, "Invoking callback failed:" + e); } } private void announceHotplugEvent(int portId, boolean connected) { HdmiHotplugEvent event = new HdmiHotplugEvent(portId, connected); synchronized (mLock) { Loading