[go: nahoru, domu]

1d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi/*
2d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * Copyright (C) 2016 The Android Open Source Project
3d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi *
4d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * you may not use this file except in compliance with the License.
6d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * You may obtain a copy of the License at
7d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi *
8d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi *
10d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * See the License for the specific language governing permissions and
14d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * limitations under the License.
15d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi */
16d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
17d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivipackage com.android.server.audio;
18d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
1933fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Triviimport android.media.AudioFormat;
20d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport android.media.AudioManager;
21598c0c9f659184971e974de6a0184a3000e7900cJean-Michel Triviimport android.media.AudioRecordingConfiguration;
22d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport android.media.AudioSystem;
23d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport android.media.IRecordingConfigDispatcher;
24dd2772a33949796cb371f0d45bc0ba86f2007bdeJean-Michel Triviimport android.media.MediaRecorder;
25d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport android.os.IBinder;
26d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport android.os.RemoteException;
27d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport android.util.Log;
28d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
29d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport java.util.ArrayList;
30d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport java.util.HashMap;
31d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviimport java.util.Iterator;
32f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Triviimport java.util.List;
33d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
34d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi/**
35d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi * Class to receive and dispatch updates from AudioSystem about recording configurations.
36d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi */
37d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivipublic final class RecordingActivityMonitor implements AudioSystem.AudioRecordingCallback {
38d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
39d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    public final static String TAG = "AudioService.RecordingActivityMonitor";
40d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
41d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    private ArrayList<RecMonitorClient> mClients = new ArrayList<RecMonitorClient>();
42d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
43598c0c9f659184971e974de6a0184a3000e7900cJean-Michel Trivi    private HashMap<Integer, AudioRecordingConfiguration> mRecordConfigs =
44598c0c9f659184971e974de6a0184a3000e7900cJean-Michel Trivi            new HashMap<Integer, AudioRecordingConfiguration>();
45d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
46d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    RecordingActivityMonitor() {
47d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        RecMonitorClient.sMonitor = this;
48d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
49d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
50d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    /**
51d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     * Implementation of android.media.AudioSystem.AudioRecordingCallback
52d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     */
5333fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    public void onRecordingConfigurationChanged(int event, int session, int source,
548ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi            int[] recordingInfo) {
55dd2772a33949796cb371f0d45bc0ba86f2007bdeJean-Michel Trivi        if (MediaRecorder.isSystemOnlyAudioSource(source)) {
56dd2772a33949796cb371f0d45bc0ba86f2007bdeJean-Michel Trivi            return;
57dd2772a33949796cb371f0d45bc0ba86f2007bdeJean-Michel Trivi        }
58f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Trivi        final List<AudioRecordingConfiguration> configs =
5928ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                updateSnapshot(event, session, source, recordingInfo);
6028ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi        if (configs != null){
61d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            synchronized(mClients) {
6228ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
63d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                while (clientIterator.hasNext()) {
64d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                    try {
6528ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                        clientIterator.next().mDispatcherCb.dispatchRecordingConfigChange(
6628ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                                configs);
67d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                    } catch (RemoteException e) {
68d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                        Log.w(TAG, "Could not call dispatchRecordingConfigChange() on client", e);
69d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                    }
70d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                }
71d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            }
72d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
73d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
74d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
75d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    void initMonitor() {
76d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        AudioSystem.setRecordingCallback(this);
77d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
78d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
79d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
80d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        if (rcdb == null) {
81d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            return;
82d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
83d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        synchronized(mClients) {
84d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            final RecMonitorClient rmc = new RecMonitorClient(rcdb);
85d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            if (rmc.init()) {
86d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                mClients.add(rmc);
87d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            }
88d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
89d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
90d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
91d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
92d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        if (rcdb == null) {
93d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            return;
94d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
95d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        synchronized(mClients) {
96d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
97d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            while (clientIterator.hasNext()) {
98d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                RecMonitorClient rmc = clientIterator.next();
99d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                if (rcdb.equals(rmc.mDispatcherCb)) {
100d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                    rmc.release();
101d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                    clientIterator.remove();
102d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                    break;
103d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                }
104d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            }
105d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
106d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
107d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
108f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Trivi    List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
109d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        synchronized(mRecordConfigs) {
110f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Trivi            return new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values());
111d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
112d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
113d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
114d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    /**
115d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     * Update the internal "view" of the active recording sessions
116d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     * @param event
117d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     * @param session
118d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     * @param source
11933fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi     * @param recordingFormat see
12033fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi     *     {@link AudioSystem.AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])}
12133fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi     *     for the definition of the contents of the array
122f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Trivi     * @return null if the list of active recording sessions has not been modified, a list
12328ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi     *     with the current active configurations otherwise.
124d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     */
125f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Trivi    private List<AudioRecordingConfiguration> updateSnapshot(int event, int session, int source,
12628ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi            int[] recordingInfo) {
12728ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi        final boolean configChanged;
128f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Trivi        final ArrayList<AudioRecordingConfiguration> configs;
129d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        synchronized(mRecordConfigs) {
130d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            switch (event) {
131d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            case AudioManager.RECORD_CONFIG_EVENT_STOP:
132d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                // return failure if an unknown recording session stopped
13328ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                configChanged = (mRecordConfigs.remove(new Integer(session)) != null);
13428ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                break;
135d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            case AudioManager.RECORD_CONFIG_EVENT_START:
13633fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi                final AudioFormat clientFormat = new AudioFormat.Builder()
1378ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        .setEncoding(recordingInfo[0])
13833fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi                        // FIXME this doesn't support index-based masks
1398ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        .setChannelMask(recordingInfo[1])
1408ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        .setSampleRate(recordingInfo[2])
14133fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi                        .build();
14233fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi                final AudioFormat deviceFormat = new AudioFormat.Builder()
1438ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        .setEncoding(recordingInfo[3])
14433fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi                        // FIXME this doesn't support index-based masks
1458ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        .setChannelMask(recordingInfo[4])
1468ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        .setSampleRate(recordingInfo[5])
14733fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi                        .build();
1488ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                final int patchHandle = recordingInfo[6];
1498ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                final Integer sessionKey = new Integer(session);
1508ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                if (mRecordConfigs.containsKey(sessionKey)) {
151598c0c9f659184971e974de6a0184a3000e7900cJean-Michel Trivi                    final AudioRecordingConfiguration updatedConfig =
152598c0c9f659184971e974de6a0184a3000e7900cJean-Michel Trivi                            new AudioRecordingConfiguration(session, source,
1538ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                                    clientFormat, deviceFormat, patchHandle);
1548ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                    if (updatedConfig.equals(mRecordConfigs.get(sessionKey))) {
15528ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                        configChanged = false;
1568ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                    } else {
1578ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        // config exists but has been modified
1588ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        mRecordConfigs.remove(sessionKey);
1598ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                        mRecordConfigs.put(sessionKey, updatedConfig);
16028ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                        configChanged = true;
1618ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                    }
162d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                } else {
1638ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                    mRecordConfigs.put(sessionKey,
164598c0c9f659184971e974de6a0184a3000e7900cJean-Michel Trivi                            new AudioRecordingConfiguration(session, source,
1658ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi                                    clientFormat, deviceFormat, patchHandle));
16628ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                    configChanged = true;
167d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                }
16828ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                break;
169d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            default:
170d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                Log.e(TAG, String.format("Unknown event %d for session %d, source %d",
171d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                        event, session, source));
17228ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                configChanged = false;
17328ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi            }
17428ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi            if (configChanged) {
175f04fab160a044e4e7d936c0457a156d7911f924cJean-Michel Trivi                configs = new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values());
17628ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi            } else {
17728ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi                configs = null;
178d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            }
179d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
18028ff76b455d35f99e68bee41b629c11ccf4f46d0Jean-Michel Trivi        return configs;
181d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
182d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
183d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    /**
184d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     * Inner class to track clients that want to be notified of recording updates
185d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi     */
186d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    private final static class RecMonitorClient implements IBinder.DeathRecipient {
187d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
188d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        // can afford to be static because only one RecordingActivityMonitor ever instantiated
189d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        static RecordingActivityMonitor sMonitor;
190d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
191d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        final IRecordingConfigDispatcher mDispatcherCb;
192d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
193d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        RecMonitorClient(IRecordingConfigDispatcher rcdb) {
194d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            mDispatcherCb = rcdb;
195d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
196d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
197d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        public void binderDied() {
198d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            Log.w(TAG, "client died");
199d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            sMonitor.unregisterRecordingCallback(mDispatcherCb);
200d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
201d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
202d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        boolean init() {
203d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            try {
204d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                mDispatcherCb.asBinder().linkToDeath(this, 0);
205d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                return true;
206d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            } catch (RemoteException e) {
207d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                Log.w(TAG, "Could not link to client death", e);
208d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                return false;
209d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            }
210d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
211d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
212d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        void release() {
213d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            mDispatcherCb.asBinder().unlinkToDeath(this, 0);
214d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        }
215d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
216d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi}
217