- dedup volume stream - run UI update from UI thread
am: ebcc0e52fd
Change-Id: Ibb8fe4b45c067015b6081e357a1a4a217acb2f65
diff --git a/src/com/android/car/settings/sound/SoundSettingsFragment.java b/src/com/android/car/settings/sound/SoundSettingsFragment.java
index c729381..9390a33 100644
--- a/src/com/android/car/settings/sound/SoundSettingsFragment.java
+++ b/src/com/android/car/settings/sound/SoundSettingsFragment.java
@@ -15,16 +15,20 @@
*/
package com.android.car.settings.sound;
+import android.app.Activity;
import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.media.CarAudioManager;
+import android.annotation.DrawableRes;
+import android.annotation.StringRes;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.media.AudioAttributes;
-import android.media.AudioManager;
import android.media.IVolumeController;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -34,6 +38,7 @@
import com.android.car.view.PagedListView;
import java.util.ArrayList;
+import java.util.HashSet;
/**
* Activity hosts sound related settings.
@@ -46,42 +51,50 @@
private TypedPagedListAdapter mPagedListAdapter;
private final ArrayList<VolumeLineItem> mVolumeLineItems = new ArrayList<>();
- private final SoundSettingsFragment.VolumnCallback
- mVolumeCallback = new SoundSettingsFragment.VolumnCallback();
+ private final VolumeCallback
+ mVolumeCallback = new VolumeCallback();
+
+ private final Handler handler = new Handler(Looper.getMainLooper());
+ private final HashSet<StreamItem> mUniqueStreamItems = new HashSet<>();
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- AudioAttributes naviAudioAttributes;
- AudioAttributes systemAudioAttributes;
- AudioAttributes mediaAudioAttributes;
try {
mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
mCarAudioManager.setVolumeController(mVolumeCallback);
- systemAudioAttributes = mCarAudioManager.getAudioAttributesForCarUsage(
- mCarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND);
- mediaAudioAttributes = mCarAudioManager.getAudioAttributesForCarUsage(
- mCarAudioManager.CAR_AUDIO_USAGE_MUSIC);
+ mUniqueStreamItems.add(new StreamItem(
+ mCarAudioManager.getAudioAttributesForCarUsage(
+ mCarAudioManager.CAR_AUDIO_USAGE_MUSIC)
+ .getVolumeControlStream(),
+ R.string.media_volume_title,
+ com.android.internal.R.drawable.ic_audio_media));
+ mUniqueStreamItems.add(new StreamItem(
+ mCarAudioManager.getAudioAttributesForCarUsage(
+ mCarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND)
+ .getVolumeControlStream(),
+ R.string.ring_volume_title,
+ com.android.internal.R.drawable.ic_audio_ring_notif));
+ mUniqueStreamItems.add(new StreamItem(
+ mCarAudioManager.getAudioAttributesForCarUsage(
+ mCarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE)
+ .getVolumeControlStream(),
+ R.string.navi_volume_title,
+ R.drawable.ic_audio_navi));
} catch (CarNotConnectedException e) {
Log.e(TAG, "Car is not connected!", e);
return;
}
- // It turns out that the stream id for system and navigation are the same.
- // skip navi for now
- mVolumeLineItems.add(new VolumeLineItem(
- getContext(),
- mCarAudioManager,
- mediaAudioAttributes.getVolumeControlStream(),
- R.string.media_volume_title,
- com.android.internal.R.drawable.ic_audio_media));
- mVolumeLineItems.add(new VolumeLineItem(
- getContext(),
- mCarAudioManager,
- systemAudioAttributes.getVolumeControlStream(),
- R.string.ring_volume_title,
- com.android.internal.R.drawable.ic_audio_ring_notif));
+ for (StreamItem streamItem : mUniqueStreamItems) {
+ mVolumeLineItems.add(new VolumeLineItem(
+ getContext(),
+ mCarAudioManager,
+ streamItem.volumeStream,
+ streamItem.nameStringId,
+ streamItem.iconId));
+ }
// if list is already initiated, update it's content.
if (mPagedListAdapter != null) {
mPagedListAdapter.updateList(new ArrayList<>(mVolumeLineItems));
@@ -90,6 +103,12 @@
@Override
public void onServiceDisconnected(ComponentName name) {
+ try {
+ mCarAudioManager.setVolumeController(null);
+ } catch (CarNotConnectedException e) {
+ Log.e(TAG, "Car is not connected!", e);
+ return;
+ }
mCarAudioManager = null;
}
};
@@ -141,20 +160,26 @@
/**
* The interface has a terrible name, it is actually a callback, so here name it accordingly.
*/
- private final class VolumnCallback extends IVolumeController.Stub {
+ private final class VolumeCallback extends IVolumeController.Stub {
@Override
public void displaySafeVolumeWarning(int flags) throws RemoteException {
}
@Override
public void volumeChanged(int streamType, int flags) throws RemoteException {
- for (VolumeLineItem item : mVolumeLineItems) {
- if (streamType == item.getStreamType()) {
- break;
- }
+ Activity activity = getActivity();
+ if (activity == null) {
+ Log.w(TAG, "no activity attached.");
return;
}
- mPagedListAdapter.notifyDataSetChanged();
+
+ for (VolumeLineItem item : mVolumeLineItems) {
+ if (streamType == item.getStreamType()) {
+ handler.post(() -> mPagedListAdapter.notifyDataSetChanged());
+ return;
+ }
+ }
+
}
// this is not mute of this stream
@@ -174,4 +199,42 @@
public void setA11yMode(int mode) {
}
}
+
+ /**
+ * Wraps information needed to render an audio stream, keyed by volumeControlStream.
+ */
+ private static final class StreamItem {
+ final int volumeStream;
+
+ @StringRes
+ final int nameStringId;
+
+ @DrawableRes
+ final int iconId;
+
+ StreamItem(
+ int volumeStream,
+ @StringRes int nameStringId,
+ @DrawableRes int iconId) {
+ this.volumeStream = volumeStream;
+ this.nameStringId = nameStringId;
+ this.iconId = iconId;
+ }
+
+ @Override
+ public int hashCode() {
+ return volumeStream;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof StreamItem)) {
+ return false;
+ }
+ return volumeStream == ((StreamItem) o).volumeStream;
+ }
+ }
}