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 android.util.Log; 23700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 24700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentimport java.util.ArrayList; 25700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentimport java.lang.ref.WeakReference; 26700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 27700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent/** 28700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * The AudioPortEventHandler handles AudioManager.OnAudioPortUpdateListener callbacks 29700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * posted from JNI 30700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent * @hide 31700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent */ 32700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 33700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentclass AudioPortEventHandler { 34f076db407029e734703d8676f806bea94393e824Eric Laurent private Handler mHandler; 35f076db407029e734703d8676f806bea94393e824Eric Laurent private final ArrayList<AudioManager.OnAudioPortUpdateListener> mListeners = 36f076db407029e734703d8676f806bea94393e824Eric Laurent new ArrayList<AudioManager.OnAudioPortUpdateListener>(); 37700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 38f076db407029e734703d8676f806bea94393e824Eric Laurent private static final String TAG = "AudioPortEventHandler"; 39700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 40700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1; 41700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2; 42700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_SERVICE_DIED = 3; 43700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static final int AUDIOPORT_EVENT_NEW_LISTENER = 4; 44700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 45f076db407029e734703d8676f806bea94393e824Eric Laurent void init() { 46f076db407029e734703d8676f806bea94393e824Eric Laurent synchronized (this) { 47f076db407029e734703d8676f806bea94393e824Eric Laurent if (mHandler != null) { 48f076db407029e734703d8676f806bea94393e824Eric Laurent return; 49f076db407029e734703d8676f806bea94393e824Eric Laurent } 50f076db407029e734703d8676f806bea94393e824Eric Laurent // find the looper for our new event handler 51f076db407029e734703d8676f806bea94393e824Eric Laurent Looper looper = Looper.getMainLooper(); 52f076db407029e734703d8676f806bea94393e824Eric Laurent 53f076db407029e734703d8676f806bea94393e824Eric Laurent if (looper != null) { 54f076db407029e734703d8676f806bea94393e824Eric Laurent mHandler = new Handler(looper) { 55f076db407029e734703d8676f806bea94393e824Eric Laurent @Override 56f076db407029e734703d8676f806bea94393e824Eric Laurent public void handleMessage(Message msg) { 57f076db407029e734703d8676f806bea94393e824Eric Laurent ArrayList<AudioManager.OnAudioPortUpdateListener> listeners; 58f076db407029e734703d8676f806bea94393e824Eric Laurent synchronized (this) { 59f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what == AUDIOPORT_EVENT_NEW_LISTENER) { 60f076db407029e734703d8676f806bea94393e824Eric Laurent listeners = new ArrayList<AudioManager.OnAudioPortUpdateListener>(); 61f076db407029e734703d8676f806bea94393e824Eric Laurent if (mListeners.contains(msg.obj)) { 62f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.add((AudioManager.OnAudioPortUpdateListener)msg.obj); 63f076db407029e734703d8676f806bea94393e824Eric Laurent } 64f076db407029e734703d8676f806bea94393e824Eric Laurent } else { 65f076db407029e734703d8676f806bea94393e824Eric Laurent listeners = mListeners; 66ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 67700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 68f076db407029e734703d8676f806bea94393e824Eric Laurent if (listeners.isEmpty()) { 69ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent return; 70ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 71f076db407029e734703d8676f806bea94393e824Eric Laurent // reset audio port cache if the event corresponds to a change coming 72f076db407029e734703d8676f806bea94393e824Eric Laurent // from audio policy service or if mediaserver process died. 73f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED || 74f076db407029e734703d8676f806bea94393e824Eric Laurent msg.what == AUDIOPORT_EVENT_PATCH_LIST_UPDATED || 75f076db407029e734703d8676f806bea94393e824Eric Laurent msg.what == AUDIOPORT_EVENT_SERVICE_DIED) { 76f076db407029e734703d8676f806bea94393e824Eric Laurent AudioManager.resetAudioPortGeneration(); 77ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 78f076db407029e734703d8676f806bea94393e824Eric Laurent ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); 79f076db407029e734703d8676f806bea94393e824Eric Laurent ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>(); 80f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) { 81f076db407029e734703d8676f806bea94393e824Eric Laurent int status = AudioManager.updateAudioPortCache(ports, patches); 82f076db407029e734703d8676f806bea94393e824Eric Laurent if (status != AudioManager.SUCCESS) { 83f076db407029e734703d8676f806bea94393e824Eric Laurent return; 84f076db407029e734703d8676f806bea94393e824Eric Laurent } 85ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 86700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 87f076db407029e734703d8676f806bea94393e824Eric Laurent switch (msg.what) { 88f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_NEW_LISTENER: 89f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_PORT_LIST_UPDATED: 90f076db407029e734703d8676f806bea94393e824Eric Laurent AudioPort[] portList = ports.toArray(new AudioPort[0]); 91f076db407029e734703d8676f806bea94393e824Eric Laurent for (int i = 0; i < listeners.size(); i++) { 92f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.get(i).onAudioPortListUpdate(portList); 93f076db407029e734703d8676f806bea94393e824Eric Laurent } 94f076db407029e734703d8676f806bea94393e824Eric Laurent if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED) { 95f076db407029e734703d8676f806bea94393e824Eric Laurent break; 96f076db407029e734703d8676f806bea94393e824Eric Laurent } 97f076db407029e734703d8676f806bea94393e824Eric Laurent // FALL THROUGH 98700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 99f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_PATCH_LIST_UPDATED: 100f076db407029e734703d8676f806bea94393e824Eric Laurent AudioPatch[] patchList = patches.toArray(new AudioPatch[0]); 101f076db407029e734703d8676f806bea94393e824Eric Laurent for (int i = 0; i < listeners.size(); i++) { 102f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.get(i).onAudioPatchListUpdate(patchList); 103f076db407029e734703d8676f806bea94393e824Eric Laurent } 104f076db407029e734703d8676f806bea94393e824Eric Laurent break; 105f076db407029e734703d8676f806bea94393e824Eric Laurent 106f076db407029e734703d8676f806bea94393e824Eric Laurent case AUDIOPORT_EVENT_SERVICE_DIED: 107f076db407029e734703d8676f806bea94393e824Eric Laurent for (int i = 0; i < listeners.size(); i++) { 108f076db407029e734703d8676f806bea94393e824Eric Laurent listeners.get(i).onServiceDied(); 109f076db407029e734703d8676f806bea94393e824Eric Laurent } 110f076db407029e734703d8676f806bea94393e824Eric Laurent break; 111ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent 112f076db407029e734703d8676f806bea94393e824Eric Laurent default: 113f076db407029e734703d8676f806bea94393e824Eric Laurent break; 114f076db407029e734703d8676f806bea94393e824Eric Laurent } 115ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 116f076db407029e734703d8676f806bea94393e824Eric Laurent }; 117f076db407029e734703d8676f806bea94393e824Eric Laurent native_setup(new WeakReference<AudioPortEventHandler>(this)); 118f076db407029e734703d8676f806bea94393e824Eric Laurent } else { 119f076db407029e734703d8676f806bea94393e824Eric Laurent mHandler = null; 120f076db407029e734703d8676f806bea94393e824Eric Laurent } 121ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent } 122700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 123f076db407029e734703d8676f806bea94393e824Eric Laurent 124700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private native void native_setup(Object module_this); 125700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 126700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent @Override 127700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent protected void finalize() { 128700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent native_finalize(); 129700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 130700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private native void native_finalize(); 131700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 132700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent void registerListener(AudioManager.OnAudioPortUpdateListener l) { 133700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent synchronized (this) { 134700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent mListeners.add(l); 135700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 136700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (mHandler != null) { 137700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Message m = mHandler.obtainMessage(AUDIOPORT_EVENT_NEW_LISTENER, 0, 0, l); 138700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent mHandler.sendMessage(m); 139700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 140700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 141700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 142700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent void unregisterListener(AudioManager.OnAudioPortUpdateListener l) { 143700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent synchronized (this) { 144700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent mListeners.remove(l); 145700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 146700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 147700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 148700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Handler handler() { 149700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent return mHandler; 150700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 151700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 152700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent @SuppressWarnings("unused") 153700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent private static void postEventFromNative(Object module_ref, 154700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent int what, int arg1, int arg2, Object obj) { 155700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent AudioPortEventHandler eventHandler = 156700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent (AudioPortEventHandler)((WeakReference)module_ref).get(); 157700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (eventHandler == null) { 158700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent return; 159700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 160700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 161700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (eventHandler != null) { 162700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Handler handler = eventHandler.handler(); 163700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent if (handler != null) { 164700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent Message m = handler.obtainMessage(what, arg1, arg2, obj); 165700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent handler.sendMessage(m); 166700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 167700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 168700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent } 169700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent 170700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent} 171