package com.iwedia.service.io; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.Log; import com.iwedia.comm.IInputOutputCallback; import com.iwedia.comm.IInputOutputControl; import com.iwedia.dtv.io.AnalogVideoType; import com.iwedia.dtv.io.AspectRatioOutput; import com.iwedia.dtv.io.AudioOutputMode; import com.iwedia.dtv.io.LastInputDescriptor; import com.iwedia.dtv.io.VideoScanning; import com.iwedia.dtv.route.common.RouteInputOutputDescriptor; import com.iwedia.dtv.types.AudioDigitalType; import com.iwedia.dtv.types.InternalException; import com.iwedia.dtv.types.VideoResolution; import com.iwedia.service.IWEDIAService; import com.iwedia.service.system.InputSettings; public class InputOutputControl extends IInputOutputControl.Stub { public static boolean DEBUG = true; public static final String LOG_TAG = "InputOutputControl"; private static Object lock = new Object(); final static RemoteCallbackList<IInputOutputCallback> mInputDeviceCallback = new RemoteCallbackList<IInputOutputCallback>(); private RouteInputOutputDescriptor activeDevice = null; private int activeDeviceIndex = -1; private static InputOutputControl instance = null; private InputOutputControl() { } public static InputOutputControl getInstance() { if (instance == null) { instance = new InputOutputControl(); } return instance; } public void ioDeviceResetActiveDevice() throws RemoteException { activeDevice = null; activeDeviceIndex = -1; } @Override public int ioDeviceGetAudioDelay(int deviceIndex) throws RemoteException { int delay; delay = IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().deviceGetAudioDelay(deviceIndex); return delay; } @Override public AudioDigitalType ioDeviceGetDigitalAudioEncodingMode(int deviceIndex) throws RemoteException { // TODO Auto-generated method stub return null; } @Override public VideoResolution ioDeviceGetResolution(int deviceIndex) throws RemoteException { VideoResolution resolution = null; if (activeDevice != null) { resolution = IWEDIAService.getInstance().getDTVManager() .getInputOutputControl() .deviceGetResolution(activeDeviceIndex); } return resolution; } @Override public int ioDeviceGetAudioChannels(int deviceIndex) throws RemoteException { int channels = 0; if (activeDevice != null) { channels = IWEDIAService.getInstance().getDTVManager() .getInputOutputControl() .deviceGetAudioChannels(activeDeviceIndex); } return channels; } @Override public int ioDeviceGetAudioSampleRate(int deviceIndex) throws RemoteException { int sampleRate = 0; if (activeDevice != null) { sampleRate = IWEDIAService.getInstance().getDTVManager() .getInputOutputControl() .deviceGetAudioSampleRate(activeDeviceIndex); } return sampleRate; } @Override public int ioDeviceGetFrameRate(int deviceIndex) throws RemoteException { int frameRate = 0; if (activeDevice != null) { frameRate = IWEDIAService.getInstance().getDTVManager() .getInputOutputControl() .deviceGetFrameRate(activeDeviceIndex); } return frameRate; } @Override public VideoScanning ioDeviceGetVideoScanning(int deviceIndex) throws RemoteException { VideoScanning scanning = null; if (activeDevice != null) { scanning = IWEDIAService.getInstance().getDTVManager() .getInputOutputControl() .deviceGetVideoScanning(activeDeviceIndex); } return scanning; } @Override public AnalogVideoType ioDeviceGetVideoType(int deviceIndex) throws RemoteException { // TODO Auto-generated method stub return null; } @Override public int ioDeviceSetAudioDelay(int deviceIndex, int delay) throws RemoteException { IWEDIAService.getInstance().getDTVManager().getInputOutputControl() .deviceSetAudioDelay(deviceIndex, delay); return 0; } @Override public int ioDeviceSetAudioOutputMode(int deviceIndex, AudioOutputMode mode) throws RemoteException { IWEDIAService.getInstance().getDTVManager().getInputOutputControl() .deviceSetAudioOutputMode(deviceIndex, mode); return 0; } @Override public AudioOutputMode ioDeviceGetAudioOutputMode(int deviceIndex) throws RemoteException { return IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().deviceGetAudioOutputMode(deviceIndex); } @Override public int ioDeviceSetDigitalAudioEncodingMode(int deviceIndex, AudioDigitalType encodingMode) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public int ioDeviceSetResolution(int deviceIndex, int videoWidth, int videoHeight) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public int ioDeviceSetVideoType(int deviceIndex, AnalogVideoType videoOutType) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public int ioDeviceStart(int decoderId, int deviceIndex) throws RemoteException { int routeID = IWEDIAService.getInstance().getDtvManagerProxy() .getRouteManager().getInputRouteID(deviceIndex, decoderId); int ret; if (activeDevice != null) { try { IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().deviceStop(routeID); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { IWEDIAService.getInstance().getDTVManager().getInputOutputControl() .deviceStart(routeID); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } activeDevice = ioGetDeviceDescriptor(deviceIndex); activeDeviceIndex = deviceIndex; notifyInputDeviceStarted(deviceIndex); return 0; } @Override public int ioDeviceStop(int decoderID, int deviceIndex) throws RemoteException { int routeID = IWEDIAService.getInstance().getDtvManagerProxy() .getRouteManager().getInputRouteID(deviceIndex, decoderID); if (activeDevice != null) { try { IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().deviceStop(routeID); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } notifyInputDeviceStopped(deviceIndex); activeDevice = null; activeDeviceIndex = -1; } return 0; } @Override public boolean ioGetDeviceActive(int deviceIndex) throws RemoteException { return IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().isDeviceActive(deviceIndex); } @Override public RouteInputOutputDescriptor ioGetDeviceDescriptor(int deviceIndex) throws RemoteException { Log.e(LOG_TAG, "ioGetDeviceDescriptor (" + deviceIndex + ")"); RouteInputOutputDescriptor deviceDescriptor = IWEDIAService .getInstance().getDTVManager().getCommonRouteControl() .getInputOutputDescriptor(deviceIndex); Log.e(LOG_TAG, deviceDescriptor.toString()); return deviceDescriptor; } @Override public boolean ioGetDeviceConnected(int deviceIndex) throws RemoteException { Log.e(LOG_TAG, "ioGetDeviceConnected (" + deviceIndex + ")"); return IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().isDeviceConnected(deviceIndex); } @Override public boolean ioGetDeviceInput(int deviceIndex) throws RemoteException { return IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().isDeviceInput(deviceIndex); } @Override public boolean ioGetDeviceOutput(int deviceIndex) throws RemoteException { return IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().isDeviceOutput(deviceIndex); } @Override public int ioGetDevicesCount() throws RemoteException { Log.e(LOG_TAG, "ioGetDevicesCount()"); int count = IWEDIAService.getInstance().getDTVManager() .getCommonRouteControl().getInputOutputNumber(); Log.e(LOG_TAG, "ioGetDevicesCount() count = " + count); return count; } @Override public boolean ioHdmiCecGetTvPowerOn() throws RemoteException { // TODO Auto-generated method stub return false; } @Override public int ioHdmiCecSetTvPowerOn(int deviceIndex) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public boolean ioHdmiGetArc(int deviceIndex) throws RemoteException { // TODO Auto-generated method stub return false; } @Override public boolean ioHdmiGetAutoLinkPowerOff() throws RemoteException { // TODO Auto-generated method stub return false; } @Override public boolean ioHdmiGetHdmiCec(int deviceIndex) throws RemoteException { // TODO Auto-generated method stub return false; } @Override public boolean ioHdmiGetSpeakerOutput(int deviceIndex) throws RemoteException { // TODO Auto-generated method stub return false; } @Override public void ioHdmiScanDevices() throws RemoteException { // TODO Auto-generated method stub } @Override public int ioHdmiSetAutoLinkPowerOff(int autoLinkPowerOffStatus) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public int ioHdmiSetHdmiCec(int deviceIndex, int hdmiCecStatus) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public int ioHdmiSetSpeakerOutput(int deviceIndex, int speakerOutputStatus) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public boolean ioInit() throws RemoteException { // TODO Auto-generated method stub return false; } @Override public boolean ioTerm() throws RemoteException { // TODO Auto-generated method stub return false; } @Override public AspectRatioOutput outputDeviceGetAspectRatio(int deviceIndex) throws RemoteException { // TODO Auto-generated method stub return null; } @Override public int outputDeviceSetAspectRatio(int deviceIndex, AspectRatioOutput ratio) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override public LastInputDescriptor ioGetLastInput() throws RemoteException { return IWEDIAService.getInstance().getDTVManager() .getInputOutputControl().getLastInput(); } public static void notifyInputDeviceStarted(int deviceIndex) { synchronized (lock) { int i = mInputDeviceCallback.beginBroadcast(); if (i > 1) { Log.e("ActionControl", "More than one callback (" + i + ")"); } while (i > 0) { i--; try { mInputDeviceCallback.getBroadcastItem(i) .inputDeviceStarted(deviceIndex); } catch (RemoteException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); mInputDeviceCallback.unregister(mInputDeviceCallback .getBroadcastItem(i)); } } mInputDeviceCallback.finishBroadcast(); } } public static void notifyInputDeviceStopped(int deviceIndex) { synchronized (lock) { int i = mInputDeviceCallback.beginBroadcast(); if (i > 1) { Log.e(LOG_TAG, "More than one callback (" + i + ")"); } while (i > 0) { i--; try { mInputDeviceCallback.getBroadcastItem(i) .inputDeviceStopped(deviceIndex); } catch (RemoteException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); mInputDeviceCallback.unregister(mInputDeviceCallback .getBroadcastItem(i)); } } mInputDeviceCallback.finishBroadcast(); } } public static void notifyInputDeviceConnected(int deviceIndex) { synchronized (lock) { int i = mInputDeviceCallback.beginBroadcast(); if (i > 1) { Log.e("ActionControl", "More than one callback (" + i + ")"); } while (i > 0) { i--; try { mInputDeviceCallback.getBroadcastItem(i) .inputDeviceConnected(deviceIndex); } catch (RemoteException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); mInputDeviceCallback.unregister(mInputDeviceCallback .getBroadcastItem(i)); } } mInputDeviceCallback.finishBroadcast(); } } public static void notifyInputDeviceDisconnected(int deviceIndex) { synchronized (lock) { int i = mInputDeviceCallback.beginBroadcast(); if (i > 1) { Log.e("ActionControl", "More than one callback (" + i + ")"); } while (i > 0) { i--; try { mInputDeviceCallback.getBroadcastItem(i) .inputDeviceDisconnected(deviceIndex); } catch (RemoteException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); mInputDeviceCallback.unregister(mInputDeviceCallback .getBroadcastItem(i)); } } mInputDeviceCallback.finishBroadcast(); } } public static void notifyInputDeviceVideoSignalChanged(int deviceIndex, boolean signalAvailable) { synchronized (lock) { int i = mInputDeviceCallback.beginBroadcast(); if (i > 1) { Log.e("ActionControl", "More than one callback (" + i + ")"); } while (i > 0) { i--; try { mInputDeviceCallback.getBroadcastItem(i) .inputDeviceVideoSignalChanged(deviceIndex, signalAvailable); } catch (RemoteException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); mInputDeviceCallback.unregister(mInputDeviceCallback .getBroadcastItem(i)); } } mInputDeviceCallback.finishBroadcast(); } } public static void notifyInputDeviceAudioSignalChanged(int deviceIndex, boolean signalAvailable) { synchronized (lock) { int i = mInputDeviceCallback.beginBroadcast(); if (i > 1) { Log.e("ActionControl", "More than one callback (" + i + ")"); } while (i > 0) { i--; try { mInputDeviceCallback.getBroadcastItem(i) .inputDeviceAudioSignalChanged(deviceIndex, signalAvailable); } catch (RemoteException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); mInputDeviceCallback.unregister(mInputDeviceCallback .getBroadcastItem(i)); } } mInputDeviceCallback.finishBroadcast(); } } public void ioDeviceStartDVB() { if (activeDevice != null) { try { ioDeviceStop(0, activeDeviceIndex); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { /* * This is a temporary hack to notify MainActivity to reactivate * switch ack to main view. Will be fixed when we have better state * handling in application */ notifyInputDeviceStopped(-1); } } private static boolean isClbkRegistered = false; public static com.iwedia.dtv.io.IInputOutputCallback getIoCallback() { return dtvServiceCallback; } private static com.iwedia.dtv.io.IInputOutputCallback dtvServiceCallback = new com.iwedia.dtv.io.IInputOutputCallback() { @Override public void afdChanged(int deviceIndex, int afd) { // TODO Auto-generated method stub } @Override public void deviceDisconnected(int deviceIndex) { getInstance().logd("Device disconnected, index: " + deviceIndex); notifyInputDeviceDisconnected(deviceIndex); } @Override public void deviceFound(int deviceIndex) { // TODO Auto-generated method stub } @Override public void deviceHotPlug(int deviceIndex) { getInstance().logd("Device connected, index: " + deviceIndex); notifyInputDeviceConnected(deviceIndex); } @Override public void videoSignalChanged(int deviceIndex, boolean signalAvailable) { getInstance().logd( "videoSignalChanged, index: " + deviceIndex + " status: " + signalAvailable); notifyInputDeviceVideoSignalChanged(deviceIndex, signalAvailable); } @Override public void audioSignalChanged(int deviceIndex, boolean signalAvailable) { getInstance().logd( "audioSignalChanged, index: " + deviceIndex + " status: " + signalAvailable); notifyInputDeviceAudioSignalChanged(deviceIndex, signalAvailable); } @Override public void hdmiAuthStatusChange(int deviceIndex, boolean success) { // TODO Auto-generated method stub } @Override public void scanFinished() { // TODO Auto-generated method stub } @Override public void wssChanged(int deviceIndex, int wss) { // TODO Auto-generated method stub } }; @Override public void registerCallback(IInputOutputCallback callback) throws RemoteException { if (isClbkRegistered == false) { isClbkRegistered = mInputDeviceCallback.register(callback); } else { logd("registerCallback: Callback is already registered!"); } } @Override public void unregisterCallback(IInputOutputCallback callback) throws RemoteException { if (isClbkRegistered == true) { mInputDeviceCallback.unregister(callback); isClbkRegistered = false; } else { logd("unregisterCallback: Callback is not registered!"); } } private void logd(String message) { if (InputSettings.DEBUG) { Log.i(LOG_TAG, message); } } }