blob: 074188e01000c40d4d28297cdb9bc2e4c2ddf3f8 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media.audiopolicy;
import android.annotation.NonNull;
import android.media.AudioManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import com.android.internal.util.Preconditions;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
* The AudioVolumeGroupChangeHandler handles AudioManager.OnAudioVolumeGroupChangedListener
* callbacks posted from JNI
*
* TODO: Make use of Executor of callbacks.
* @hide
*/
public class AudioVolumeGroupChangeHandler {
private Handler mHandler;
private HandlerThread mHandlerThread;
private final ArrayList<AudioManager.VolumeGroupCallback> mListeners =
new ArrayList<AudioManager.VolumeGroupCallback>();
private static final String TAG = "AudioVolumeGroupChangeHandler";
private static final int AUDIOVOLUMEGROUP_EVENT_VOLUME_CHANGED = 1000;
private static final int AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER = 4;
/**
* Accessed by native methods: JNI Callback context.
*/
@SuppressWarnings("unused")
private long mJniCallback;
/**
* Initialization
*/
public void init() {
synchronized (this) {
if (mHandler != null) {
return;
}
// create a new thread for our new event handler
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
if (mHandlerThread.getLooper() == null) {
mHandler = null;
return;
}
mHandler = new Handler(mHandlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
ArrayList<AudioManager.VolumeGroupCallback> listeners;
synchronized (this) {
if (msg.what == AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER) {
listeners =
new ArrayList<AudioManager.VolumeGroupCallback>();
if (mListeners.contains(msg.obj)) {
listeners.add(
(AudioManager.VolumeGroupCallback) msg.obj);
}
} else {
listeners = mListeners;
}
}
if (listeners.isEmpty()) {
return;
}
switch (msg.what) {
case AUDIOVOLUMEGROUP_EVENT_VOLUME_CHANGED:
for (int i = 0; i < listeners.size(); i++) {
listeners.get(i).onAudioVolumeGroupChanged((int) msg.arg1,
(int) msg.arg2);
}
break;
default:
break;
}
}
};
native_setup(new WeakReference<AudioVolumeGroupChangeHandler>(this));
}
}
private native void native_setup(Object moduleThis);
@Override
protected void finalize() {
native_finalize();
if (mHandlerThread.isAlive()) {
mHandlerThread.quit();
}
}
private native void native_finalize();
/**
* @param cb the {@link AudioManager.VolumeGroupCallback} to register
*/
public void registerListener(@NonNull AudioManager.VolumeGroupCallback cb) {
Preconditions.checkNotNull(cb, "volume group callback shall not be null");
synchronized (this) {
mListeners.add(cb);
}
if (mHandler != null) {
Message m = mHandler.obtainMessage(
AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER, 0, 0, cb);
mHandler.sendMessage(m);
}
}
/**
* @param cb the {@link AudioManager.VolumeGroupCallback} to unregister
*/
public void unregisterListener(@NonNull AudioManager.VolumeGroupCallback cb) {
Preconditions.checkNotNull(cb, "volume group callback shall not be null");
synchronized (this) {
mListeners.remove(cb);
}
}
Handler handler() {
return mHandler;
}
@SuppressWarnings("unused")
private static void postEventFromNative(Object moduleRef,
int what, int arg1, int arg2, Object obj) {
AudioVolumeGroupChangeHandler eventHandler =
(AudioVolumeGroupChangeHandler) ((WeakReference) moduleRef).get();
if (eventHandler == null) {
return;
}
if (eventHandler != null) {
Handler handler = eventHandler.handler();
if (handler != null) {
Message m = handler.obtainMessage(what, arg1, arg2, obj);
if (what != AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER) {
handler.removeMessages(what);
}
handler.sendMessage(m);
}
}
}
}