Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea67c183 authored by Jungshik Jang's avatar Jungshik Jang
Browse files

Add for System Audio Mode

Note that this is skeleton change and do not merge
till get full review from outside of CEC team.

This change introduce four apis for System Audio Mode

1. boolean canChangeSystemAudioMode()
  -  Whether to change system audio mode or not.

2. setSystemAudioMode(boolean enabled, IHdmiControlCallback callback);
  - Change system audio mode.

3. add/removeSystemAudioModeChangeLister.
  - Register/deregister listner for AudioModeChange.

4. getSystemAudioMode()
  - Whether to system audio is enabled or not.

Change-Id: I1e82365155a9f7f6c3ac5d9db4871cf6bad46865
parent 3722c328
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 \
+6 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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);
}
+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);
}
+18 −3
Original line number Diff line number Diff line
@@ -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;
        }
    }
+122 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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();

@@ -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;
@@ -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);
    }
@@ -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) {
@@ -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);
@@ -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