1700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent/* 2700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * Copyright (C) 2014 The Android Open Source Project 3700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * 4700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 5700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * you may not use this file except in compliance with the License. 6700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * You may obtain a copy of the License at 7700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * 8700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 9700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * 10700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * Unless required by applicable law or agreed to in writing, software 11700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 12700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * See the License for the specific language governing permissions and 14700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * limitations under the License. 15700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent */ 16700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 17700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentpackage android.media; 18700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 19700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentimport android.os.Handler; 20700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentimport android.os.Looper; 21700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentimport android.os.Message; 22700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentimport java.util.ArrayList; 23700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentimport java.lang.ref.WeakReference; 24700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 25700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent/** 26700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * The AudioPortEventHandler handles AudioManager.OnAudioPortUpdateListener callbacks 27700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * posted from JNI 28700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * @hide 29700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent */ 30700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 31700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentclass AudioPortEventHandler { 32f076db407029e734703d8676f806bea94393e824Eric Laurent private Handler mHandler; 33f076db407029e734703d8676f806bea94393e824Eric Laurent private final ArrayList<AudioManager.OnAudioPortUpdateListener> mListeners = 34f076db407029e734703d8676f806bea94393e824Eric Laurent new ArrayList<AudioManager.OnAudioPortUpdateListener>(); 35700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 36f076db407029e734703d8676f806bea94393e824Eric Laurent private static final String TAG = "AudioPortEventHandler"; 37700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 38700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1; 39700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2; 40700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_SERVICE_DIED = 3; 41700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_NEW_LISTENER = 4; 42700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 432615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent /** 442615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent * Accessed by native methods: JNI Callback context. 452615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent */ 462615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent @SuppressWarnings("unused") 472615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent private long mJniCallback; 482615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent 49f076db407029e734703d8676f806bea94393e824Eric Laurent void init() { 50f076db407029e734703d8676f806bea94393e824Eric Laurent synchronized (this) { 51f076db407029e734703d8676f806bea94393e824Eric Laurent if (mHandler != null) { 52f076db407029e734703d8676f806bea94393e824Eric Laurent return; 53f076db407029e734703d8676f806bea94393e824Eric Laurent } 54f076db407029e734703d8676f806bea94393e824Eric Laurent // find the looper for our new event handler 55f076db407029e734703d8676f806bea94393e824Eric Laurent Looper looper = Looper.getMainLooper(); 56f076db407029e734703d8676f806bea94393e824Eric Laurent 57f076db407029e734703d8676f806bea94393e824Eric Laurent if (looper != null) { 58f076db407029e734703d8676f806bea94393e824Eric Laurent mHandler = new Handler(looper) { 59f076db407029e734703d8676f806bea94393e824Eric Laurent @Override 60f076db407029e734703d8676f806bea94393e824Eric Laurent public void handleMessage(Message msg) { 61f076db407029e734703d8676f806bea94393e824Eric Laurent ArrayList<AudioManager.OnAudioPortUpdateListener> listeners; 62f076db407029e734703d8676f806bea94393e824Eric Laurent synchronized (this) { 63f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what == AUDIOPORT_EVENT_NEW_LISTENER) { 64f076db407029e734703d8676f806bea94393e824Eric Laurent listeners = new ArrayList<AudioManager.OnAudioPortUpdateListener>(); 65f076db407029e734703d8676f806bea94393e824Eric Laurent if (mListeners.contains(msg.obj)) { 66f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.add((AudioManager.OnAudioPortUpdateListener)msg.obj); 67f076db407029e734703d8676f806bea94393e824Eric Laurent } 68f076db407029e734703d8676f806bea94393e824Eric Laurent } else { 69f076db407029e734703d8676f806bea94393e824Eric Laurent listeners = mListeners; 70ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 71700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 72f076db407029e734703d8676f806bea94393e824Eric Laurent // reset audio port cache if the event corresponds to a change coming 73f076db407029e734703d8676f806bea94393e824Eric Laurent // from audio policy service or if mediaserver process died. 74f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED || 75f076db407029e734703d8676f806bea94393e824Eric Laurent msg.what == AUDIOPORT_EVENT_PATCH_LIST_UPDATED || 76f076db407029e734703d8676f806bea94393e824Eric Laurent msg.what == AUDIOPORT_EVENT_SERVICE_DIED) { 77f076db407029e734703d8676f806bea94393e824Eric Laurent AudioManager.resetAudioPortGeneration(); 78ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 792615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent 802615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent if (listeners.isEmpty()) { 812615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent return; 822615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent } 832615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent 84f076db407029e734703d8676f806bea94393e824Eric Laurent ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); 85f076db407029e734703d8676f806bea94393e824Eric Laurent ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>(); 86f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) { 878a1e7a881ee73b9b1e492e7014c3eaefe81cfbd7Eric Laurent int status = AudioManager.updateAudioPortCache(ports, patches, null); 88f076db407029e734703d8676f806bea94393e824Eric Laurent if (status != AudioManager.SUCCESS) { 89f076db407029e734703d8676f806bea94393e824Eric Laurent return; 90f076db407029e734703d8676f806bea94393e824Eric Laurent } 91ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 92700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 93f076db407029e734703d8676f806bea94393e824Eric Laurent switch (msg.what) { 94f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_NEW_LISTENER: 95f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_PORT_LIST_UPDATED: 96f076db407029e734703d8676f806bea94393e824Eric Laurent AudioPort[] portList = ports.toArray(new AudioPort[0]); 97f076db407029e734703d8676f806bea94393e824Eric Laurent for (int i = 0; i < listeners.size(); i++) { 98f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.get(i).onAudioPortListUpdate(portList); 99f076db407029e734703d8676f806bea94393e824Eric Laurent } 100f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED) { 101f076db407029e734703d8676f806bea94393e824Eric Laurent break; 102f076db407029e734703d8676f806bea94393e824Eric Laurent } 103f076db407029e734703d8676f806bea94393e824Eric Laurent // FALL THROUGH 104700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 105f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_PATCH_LIST_UPDATED: 106f076db407029e734703d8676f806bea94393e824Eric Laurent AudioPatch[] patchList = patches.toArray(new AudioPatch[0]); 107f076db407029e734703d8676f806bea94393e824Eric Laurent for (int i = 0; i < listeners.size(); i++) { 108f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.get(i).onAudioPatchListUpdate(patchList); 109f076db407029e734703d8676f806bea94393e824Eric Laurent } 110f076db407029e734703d8676f806bea94393e824Eric Laurent break; 111f076db407029e734703d8676f806bea94393e824Eric Laurent 112f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_SERVICE_DIED: 113f076db407029e734703d8676f806bea94393e824Eric Laurent for (int i = 0; i < listeners.size(); i++) { 114f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.get(i).onServiceDied(); 115f076db407029e734703d8676f806bea94393e824Eric Laurent } 116f076db407029e734703d8676f806bea94393e824Eric Laurent break; 117ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent 118f076db407029e734703d8676f806bea94393e824Eric Laurent default: 119f076db407029e734703d8676f806bea94393e824Eric Laurent break; 120f076db407029e734703d8676f806bea94393e824Eric Laurent } 121ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 122f076db407029e734703d8676f806bea94393e824Eric Laurent }; 123f076db407029e734703d8676f806bea94393e824Eric Laurent native_setup(new WeakReference<AudioPortEventHandler>(this)); 124f076db407029e734703d8676f806bea94393e824Eric Laurent } else { 125f076db407029e734703d8676f806bea94393e824Eric Laurent mHandler = null; 126f076db407029e734703d8676f806bea94393e824Eric Laurent } 127ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 128700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 129f076db407029e734703d8676f806bea94393e824Eric Laurent 130700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private native void native_setup(Object module_this); 131700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 132700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent @Override 133700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent protected void finalize() { 134700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent native_finalize(); 135700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 136700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private native void native_finalize(); 137700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 138700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent void registerListener(AudioManager.OnAudioPortUpdateListener l) { 139700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent synchronized (this) { 140700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent mListeners.add(l); 141700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 142700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (mHandler != null) { 143700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Message m = mHandler.obtainMessage(AUDIOPORT_EVENT_NEW_LISTENER, 0, 0, l); 144700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent mHandler.sendMessage(m); 145700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 146700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 147700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 148700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent void unregisterListener(AudioManager.OnAudioPortUpdateListener l) { 149700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent synchronized (this) { 150700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent mListeners.remove(l); 151700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 152700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 153700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 154700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Handler handler() { 155700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent return mHandler; 156700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 157700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 158700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent @SuppressWarnings("unused") 159700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static void postEventFromNative(Object module_ref, 160700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent int what, int arg1, int arg2, Object obj) { 161700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent AudioPortEventHandler eventHandler = 162700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent (AudioPortEventHandler)((WeakReference)module_ref).get(); 163700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (eventHandler == null) { 164700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent return; 165700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 166700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 167700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (eventHandler != null) { 168700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Handler handler = eventHandler.handler(); 169700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (handler != null) { 170700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Message m = handler.obtainMessage(what, arg1, arg2, obj); 171700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent handler.sendMessage(m); 172700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 173700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 174700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 175700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 176700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent} 177