Merge "Display the current connected audio device"
This commit is contained in:
committed by
Android (Google) Code Review
commit
78bf68c4f2
@@ -172,5 +172,6 @@ public interface VolumeDialogController {
|
||||
void onScreenOff();
|
||||
void onShowSafetyWarning(int flags);
|
||||
void onAccessibilityModeChanged(Boolean showA11yStream);
|
||||
void onConnectedDeviceChanged(String deviceName);
|
||||
}
|
||||
}
|
||||
|
||||
25
packages/SystemUI/res/drawable/ic_swap.xml
Normal file
25
packages/SystemUI/res/drawable/ic_swap.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorForeground">
|
||||
<path
|
||||
android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
||||
@@ -38,23 +38,34 @@
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/colorControlNormal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
<TextView
|
||||
android:id="@+id/volume_row_connected_device"
|
||||
android:visibility="gone"
|
||||
<LinearLayout
|
||||
android:id="@+id/output_chooser"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary" />
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/output_chooser"
|
||||
style="@style/VolumeButtons"
|
||||
android:minWidth="48dp"
|
||||
android:minHeight="48dp"
|
||||
android:paddingTop="10dp"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:layout_width="@dimen/volume_button_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_volume_expand_animation"
|
||||
android:soundEffectsEnabled="false" />
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/volume_row_connected_device"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary" />
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/output_chooser_button"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
style="@style/VolumeButtons"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_swap"
|
||||
android:soundEffectsEnabled="false" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/volume_row_slider_frame"
|
||||
|
||||
@@ -514,5 +514,8 @@ public class OutputChooserDialog extends Dialog
|
||||
|
||||
@Override
|
||||
public void onAccessibilityModeChanged(Boolean showA11yStream) {}
|
||||
|
||||
@Override
|
||||
public void onConnectedDeviceChanged(String deviceName) {}
|
||||
};
|
||||
}
|
||||
@@ -26,6 +26,8 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.database.ContentObserver;
|
||||
import android.media.AudioDeviceCallback;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.IVolumeController;
|
||||
@@ -105,6 +107,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
private boolean mShowA11yStream;
|
||||
private boolean mShowVolumeDialog;
|
||||
private boolean mShowSafetyWarning;
|
||||
private DeviceCallback mDeviceCallback = new DeviceCallback();
|
||||
private AudioDeviceInfo mConnectedDevice;
|
||||
|
||||
private boolean mDestroyed;
|
||||
private VolumePolicy mVolumePolicy;
|
||||
@@ -180,6 +184,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
} catch (SecurityException e) {
|
||||
Log.w(TAG, "No access to media sessions", e);
|
||||
}
|
||||
mAudio.registerAudioDeviceCallback(mDeviceCallback, mWorker);
|
||||
}
|
||||
|
||||
public void setVolumePolicy(VolumePolicy policy) {
|
||||
@@ -205,6 +210,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
mMediaSessions.destroy();
|
||||
mObserver.destroy();
|
||||
mReceiver.destroy();
|
||||
mAudio.unregisterAudioDeviceCallback(mDeviceCallback);
|
||||
mWorkerThread.quitSafely();
|
||||
}
|
||||
|
||||
@@ -664,6 +670,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
case USER_ACTIVITY: onUserActivityW(); break;
|
||||
case SHOW_SAFETY_WARNING: onShowSafetyWarningW(msg.arg1); break;
|
||||
case ACCESSIBILITY_MODE_CHANGED: onAccessibilityModeChanged((Boolean) msg.obj);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -803,6 +810,18 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedDeviceChanged(String deviceName) {
|
||||
for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) {
|
||||
entry.getValue().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
entry.getKey().onConnectedDeviceChanged(deviceName);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1005,6 +1024,34 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
}
|
||||
}
|
||||
|
||||
protected final class DeviceCallback extends AudioDeviceCallback {
|
||||
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
|
||||
for (AudioDeviceInfo info : addedDevices) {
|
||||
if (info.isSink()
|
||||
&& (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
|
||||
|| info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO)) {
|
||||
mConnectedDevice = info;
|
||||
mCallbacks.onConnectedDeviceChanged(info.getProductName().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
|
||||
if (mConnectedDevice == null) {
|
||||
mCallbacks.onConnectedDeviceChanged(null);
|
||||
return;
|
||||
}
|
||||
for (AudioDeviceInfo info : removedDevices) {
|
||||
if (info.isSink() == mConnectedDevice.isSink()
|
||||
&& Objects.equals(info.getProductName(), mConnectedDevice.getProductName())
|
||||
&& info.getType() == mConnectedDevice.getType()) {
|
||||
mConnectedDevice = null;
|
||||
mCallbacks.onConnectedDeviceChanged(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface UserActivityListener {
|
||||
void onUserActivity();
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.support.v7.media.MediaRouter;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -73,6 +74,7 @@ import android.widget.TextView;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.plugins.VolumeDialog;
|
||||
import com.android.systemui.plugins.VolumeDialogController;
|
||||
import com.android.systemui.plugins.VolumeDialogController.State;
|
||||
@@ -332,8 +334,11 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));
|
||||
row.anim = null;
|
||||
|
||||
ImageButton outputChooser = row.view.findViewById(R.id.output_chooser);
|
||||
outputChooser.setOnClickListener(mClickOutputChooser);
|
||||
row.outputChooser = row.view.findViewById(R.id.output_chooser);
|
||||
row.outputChooser.setOnClickListener(mClickOutputChooser);
|
||||
row.outputChooser.findViewById(R.id.output_chooser_button)
|
||||
.setOnClickListener(mClickOutputChooser);
|
||||
row.connectedDevice = row.view.findViewById(R.id.volume_row_connected_device);
|
||||
|
||||
// forward events above the slider into the slider
|
||||
row.view.setOnTouchListener(new OnTouchListener() {
|
||||
@@ -422,7 +427,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
dismissH(DISMISS_REASON_SETTINGS_CLICKED);
|
||||
mContext.startActivity(intent);
|
||||
Dependency.get(ActivityStarter.class).startActivity(intent, true /* dismissShade */);
|
||||
return true;
|
||||
});
|
||||
updateRingerH();
|
||||
@@ -546,6 +551,13 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateConnectedDeviceH(String deviceName) {
|
||||
for (final VolumeRow row : mRows) {
|
||||
row.connectedDevice.setText(deviceName);
|
||||
Util.setVisOrGone(row.connectedDevice, !TextUtils.isEmpty(deviceName));
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateRingerH() {
|
||||
if (mState != null) {
|
||||
final StreamState ss = mState.states.get(AudioManager.STREAM_RING);
|
||||
@@ -957,6 +969,11 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedDeviceChanged(String deviceName) {
|
||||
updateConnectedDeviceH(deviceName);
|
||||
}
|
||||
};
|
||||
|
||||
private final class H extends Handler {
|
||||
@@ -1155,5 +1172,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private ObjectAnimator anim; // slider progress animation for non-touch-related updates
|
||||
private int animTargetProgress;
|
||||
private int lastAudibleLevel = 1;
|
||||
private View outputChooser;
|
||||
private TextView connectedDevice;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user