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