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