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 {
34700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    private final Handler mHandler;
35700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    private ArrayList<AudioManager.OnAudioPortUpdateListener> mListeners;
36700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    private AudioManager mAudioManager;
37700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
38700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    private static 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
45700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    AudioPortEventHandler(AudioManager audioManager) {
46700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        mAudioManager = audioManager;
47700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        mListeners = new ArrayList<AudioManager.OnAudioPortUpdateListener>();
48700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
49700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        // find the looper for our new event handler
505a7e9207f0e530cd95beda087ddd3680d661e5abEric Laurent        Looper looper = Looper.getMainLooper();
51700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
52ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent        if (looper != null) {
53ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent            mHandler = new Handler(looper) {
54ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                @Override
55ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                public void handleMessage(Message msg) {
56ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    ArrayList<AudioManager.OnAudioPortUpdateListener> listeners;
57ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    synchronized (this) {
58ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        if (msg.what == AUDIOPORT_EVENT_NEW_LISTENER) {
59ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            listeners = new ArrayList<AudioManager.OnAudioPortUpdateListener>();
60ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            if (mListeners.contains(msg.obj)) {
61ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                                listeners.add((AudioManager.OnAudioPortUpdateListener)msg.obj);
62ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            }
63ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        } else {
64ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            listeners = mListeners;
65700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                        }
66700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                    }
67ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    if (listeners.isEmpty()) {
68700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                        return;
69700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                    }
70ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    // reset audio port cache if the event corresponds to a change coming
71ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    // from audio policy service or if mediaserver process died.
72ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED ||
73ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            msg.what == AUDIOPORT_EVENT_PATCH_LIST_UPDATED ||
74ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            msg.what == AUDIOPORT_EVENT_SERVICE_DIED) {
75ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        mAudioManager.resetAudioPortGeneration();
76700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                    }
77ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
78ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
79ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) {
80ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        int status = mAudioManager.updateAudioPortCache(ports, patches);
81ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        if (status != AudioManager.SUCCESS) {
82ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            return;
83ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        }
84700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                    }
85700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
86ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    switch (msg.what) {
87ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    case AUDIOPORT_EVENT_NEW_LISTENER:
88ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    case AUDIOPORT_EVENT_PORT_LIST_UPDATED:
89ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        AudioPort[] portList = ports.toArray(new AudioPort[0]);
90ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        for (int i = 0; i < listeners.size(); i++) {
91fdaed9dcb63171379fd7c5a6208014bac505dbc6Eric Laurent                            listeners.get(i).onAudioPortListUpdate(portList);
92ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        }
93ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED) {
94ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                            break;
95ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        }
96ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        // FALL THROUGH
97700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
98ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    case AUDIOPORT_EVENT_PATCH_LIST_UPDATED:
99ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        AudioPatch[] patchList = patches.toArray(new AudioPatch[0]);
100ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        for (int i = 0; i < listeners.size(); i++) {
101fdaed9dcb63171379fd7c5a6208014bac505dbc6Eric Laurent                            listeners.get(i).onAudioPatchListUpdate(patchList);
102ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        }
103ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        break;
104700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
105ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    case AUDIOPORT_EVENT_SERVICE_DIED:
106ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        for (int i = 0; i < listeners.size(); i++) {
107fdaed9dcb63171379fd7c5a6208014bac505dbc6Eric Laurent                            listeners.get(i).onServiceDied();
108ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        }
109ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        break;
110ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent
111ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    default:
112ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                        break;
113ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent                    }
114700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                }
115ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent            };
116ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent        } else {
117ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent            mHandler = null;
118ddc93ce3438618a15f30fc20d45634325f8ce84fEric Laurent        }
119700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
120700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        native_setup(new WeakReference<AudioPortEventHandler>(this));
121700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
122700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    private native void native_setup(Object module_this);
123700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
124700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    @Override
125700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    protected void finalize() {
126700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        native_finalize();
127700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
128700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    private native void native_finalize();
129700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
130700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    void registerListener(AudioManager.OnAudioPortUpdateListener l) {
131700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        synchronized (this) {
132700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            mListeners.add(l);
133700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        }
134700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        if (mHandler != null) {
135700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            Message m = mHandler.obtainMessage(AUDIOPORT_EVENT_NEW_LISTENER, 0, 0, l);
136700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            mHandler.sendMessage(m);
137700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        }
138700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
139700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
140700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    void unregisterListener(AudioManager.OnAudioPortUpdateListener l) {
141700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        synchronized (this) {
142700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            mListeners.remove(l);
143700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        }
144700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
145700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
146700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    Handler handler() {
147700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        return mHandler;
148700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
149700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
150700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    @SuppressWarnings("unused")
151700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    private static void postEventFromNative(Object module_ref,
152700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                                            int what, int arg1, int arg2, Object obj) {
153700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        AudioPortEventHandler eventHandler =
154700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                (AudioPortEventHandler)((WeakReference)module_ref).get();
155700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        if (eventHandler == null) {
156700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            return;
157700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        }
158700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
159700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        if (eventHandler != null) {
160700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            Handler handler = eventHandler.handler();
161700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            if (handler != null) {
162700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                Message m = handler.obtainMessage(what, arg1, arg2, obj);
163700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                handler.sendMessage(m);
164700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent            }
165700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        }
166700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
167700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
168700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
169