summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java')
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java1538
1 files changed, 0 insertions, 1538 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
deleted file mode 100644
index 45cb4a1..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.systemui.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.ColorDrawable;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.media.RingtoneManager;
-import android.media.ToneGenerator;
-import android.media.VolumeProvider;
-import android.media.session.MediaController;
-import android.media.session.MediaController.PlaybackInfo;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Vibrator;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.systemui.DemoMode;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Handles the user interface for the volume keys.
- *
- * @hide
- */
-public class VolumePanel extends Handler implements DemoMode {
- private static final String TAG = "VolumePanel";
- private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
-
- private static final int PLAY_SOUND_DELAY = AudioSystem.PLAY_SOUND_DELAY;
-
- /**
- * The delay before vibrating. This small period exists so if the user is
- * moving to silent mode, it will not emit a short vibrate (it normally
- * would since vibrate is between normal mode and silent mode using hardware
- * keys).
- */
- public static final int VIBRATE_DELAY = 300;
-
- private static final int VIBRATE_DURATION = 300;
- private static final int BEEP_DURATION = 150;
- private static final int MAX_VOLUME = 100;
- private static final int FREE_DELAY = 10000;
- private static final int TIMEOUT_DELAY = 3000;
- private static final int TIMEOUT_DELAY_SHORT = 1500;
- private static final int TIMEOUT_DELAY_COLLAPSED = 4500;
- private static final int TIMEOUT_DELAY_SAFETY_WARNING = 5000;
- private static final int TIMEOUT_DELAY_EXPANDED = 10000;
-
- private static final int MSG_VOLUME_CHANGED = 0;
- private static final int MSG_FREE_RESOURCES = 1;
- private static final int MSG_PLAY_SOUND = 2;
- private static final int MSG_STOP_SOUNDS = 3;
- private static final int MSG_VIBRATE = 4;
- private static final int MSG_TIMEOUT = 5;
- private static final int MSG_RINGER_MODE_CHANGED = 6;
- private static final int MSG_MUTE_CHANGED = 7;
- private static final int MSG_REMOTE_VOLUME_CHANGED = 8;
- private static final int MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN = 9;
- private static final int MSG_SLIDER_VISIBILITY_CHANGED = 10;
- private static final int MSG_DISPLAY_SAFE_VOLUME_WARNING = 11;
- private static final int MSG_LAYOUT_DIRECTION = 12;
- private static final int MSG_ZEN_MODE_AVAILABLE_CHANGED = 13;
- private static final int MSG_USER_ACTIVITY = 14;
- private static final int MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED = 15;
- private static final int MSG_INTERNAL_RINGER_MODE_CHANGED = 16;
-
- // Pseudo stream type for remote volume
- private static final int STREAM_REMOTE_MUSIC = -200;
-
- private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
- .build();
-
- private static final int IC_AUDIO_VOL = com.android.systemui.R.drawable.ic_audio_vol;
- private static final int IC_AUDIO_VOL_MUTE = com.android.systemui.R.drawable.ic_audio_vol_mute;
- private static final int IC_AUDIO_BT = com.android.systemui.R.drawable.ic_audio_bt;
- private static final int IC_AUDIO_BT_MUTE = com.android.systemui.R.drawable.ic_audio_bt_mute;
-
- private final String mTag;
- protected final Context mContext;
- private final AudioManager mAudioManager;
- private final ZenModeController mZenController;
- private boolean mRingIsSilent;
- private boolean mVoiceCapable;
- private boolean mZenModeAvailable;
- private boolean mZenPanelExpanded;
- private int mTimeoutDelay = TIMEOUT_DELAY;
- private float mDisabledAlpha;
- private int mLastRingerMode = AudioManager.RINGER_MODE_NORMAL;
- private int mLastRingerProgress = 0;
- private int mDemoIcon;
-
- /** Volume panel content view */
- private final View mView;
- /** Dialog hosting the panel */
- private final Dialog mDialog;
-
- /** The visible portion of the volume overlay */
- private final ViewGroup mPanel;
- /** Contains the slider and its touchable icons */
- private final ViewGroup mSliderPanel;
- /** The zen mode configuration panel view */
- private ZenModePanel mZenPanel;
- /** The component currently suppressing notification stream effects */
- private ComponentName mNotificationEffectsSuppressor;
-
- private Callback mCallback;
-
- /** Currently active stream that shows up at the top of the list of sliders */
- private int mActiveStreamType = -1;
- /** All the slider controls mapped by stream type */
- private SparseArray<StreamControl> mStreamControls;
- private final AccessibilityManager mAccessibilityManager;
- private final SecondaryIconTransition mSecondaryIconTransition;
- private final IconPulser mIconPulser;
-
- private enum StreamResources {
- BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
- R.string.volume_icon_description_bluetooth,
- IC_AUDIO_BT,
- IC_AUDIO_BT_MUTE,
- false),
- RingerStream(AudioManager.STREAM_RING,
- R.string.volume_icon_description_ringer,
- com.android.systemui.R.drawable.ic_ringer_audible,
- com.android.systemui.R.drawable.ic_ringer_mute,
- false),
- VoiceStream(AudioManager.STREAM_VOICE_CALL,
- R.string.volume_icon_description_incall,
- com.android.systemui.R.drawable.ic_audio_phone,
- com.android.systemui.R.drawable.ic_audio_phone,
- false),
- AlarmStream(AudioManager.STREAM_ALARM,
- R.string.volume_alarm,
- com.android.systemui.R.drawable.ic_audio_alarm,
- com.android.systemui.R.drawable.ic_audio_alarm_mute,
- false),
- MediaStream(AudioManager.STREAM_MUSIC,
- R.string.volume_icon_description_media,
- IC_AUDIO_VOL,
- IC_AUDIO_VOL_MUTE,
- true),
- NotificationStream(AudioManager.STREAM_NOTIFICATION,
- R.string.volume_icon_description_notification,
- com.android.systemui.R.drawable.ic_ringer_audible,
- com.android.systemui.R.drawable.ic_ringer_mute,
- true),
- RemoteStream(STREAM_REMOTE_MUSIC,
- R.string.volume_icon_description_media, //FIXME should have its own description
- com.android.systemui.R.drawable.ic_audio_remote,
- com.android.systemui.R.drawable.ic_audio_remote,
- false);// will be dynamically updated
-
- int streamType;
- int descRes;
- int iconRes;
- int iconMuteRes;
- // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
- boolean show;
-
- StreamResources(int streamType, int descRes, int iconRes, int iconMuteRes, boolean show) {
- this.streamType = streamType;
- this.descRes = descRes;
- this.iconRes = iconRes;
- this.iconMuteRes = iconMuteRes;
- this.show = show;
- }
- }
-
- // List of stream types and their order
- private static final StreamResources[] STREAMS = {
- StreamResources.BluetoothSCOStream,
- StreamResources.RingerStream,
- StreamResources.VoiceStream,
- StreamResources.MediaStream,
- StreamResources.NotificationStream,
- StreamResources.AlarmStream,
- StreamResources.RemoteStream
- };
-
- /** Object that contains data for each slider */
- private class StreamControl {
- int streamType;
- MediaController controller;
- ViewGroup group;
- ImageView icon;
- SeekBar seekbarView;
- TextView suppressorView;
- View divider;
- ImageView secondaryIcon;
- int iconRes;
- int iconMuteRes;
- int iconSuppressedRes;
- int minVolume;
- }
-
- // Synchronize when accessing this
- private ToneGenerator mToneGenerators[];
- private Vibrator mVibrator;
- private boolean mHasVibrator;
-
- private static AlertDialog sSafetyWarning;
- private static Object sSafetyWarningLock = new Object();
-
- protected LayoutParams getDialogLayoutParams(Window window, Resources res) {
- final LayoutParams lp = window.getAttributes();
- lp.token = null;
- lp.y = res.getDimensionPixelOffset(com.android.systemui.R.dimen.volume_panel_top);
- lp.type = LayoutParams.TYPE_STATUS_BAR_PANEL;
- lp.format = PixelFormat.TRANSLUCENT;
- lp.windowAnimations = com.android.systemui.R.style.VolumePanelAnimation;
- lp.setTitle(TAG);
- return lp;
- }
-
- public VolumePanel(Context context, ZenModeController zenController) {
- mTag = String.format("%s.%08x", TAG, hashCode());
- mContext = context;
- mZenController = zenController;
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- mAccessibilityManager = (AccessibilityManager) context.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
- mSecondaryIconTransition = new SecondaryIconTransition();
- mIconPulser = new IconPulser(context);
-
- if (LOGD) Log.d(mTag, "new VolumePanel");
-
- mDisabledAlpha = 0.5f;
- if (mContext.getTheme() != null) {
- final TypedArray arr = mContext.getTheme().obtainStyledAttributes(
- new int[] { android.R.attr.disabledAlpha });
- mDisabledAlpha = arr.getFloat(0, mDisabledAlpha);
- arr.recycle();
- }
-
- mDialog = new Dialog(context) {
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE &&
- sSafetyWarning == null) {
- forceTimeout(0);
- return true;
- }
- return false;
- }
- };
-
- final Window window = mDialog.getWindow();
- window.requestFeature(Window.FEATURE_NO_TITLE);
- mDialog.setCanceledOnTouchOutside(true);
- mDialog.setContentView(com.android.systemui.R.layout.volume_panel_dialog);
- mDialog.setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- mActiveStreamType = -1;
- mAudioManager.forceVolumeControlStream(mActiveStreamType);
- setZenPanelVisible(false);
- mDemoIcon = 0;
- mSecondaryIconTransition.cancel();
- }
- });
-
- mDialog.create();
-
- final Resources res = context.getResources();
- window.setAttributes(getDialogLayoutParams(window, res));
-
- updateWidth();
-
- window.setBackgroundDrawable(new ColorDrawable(0x00000000));
- window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
- window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
- | LayoutParams.FLAG_NOT_TOUCH_MODAL
- | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | LayoutParams.FLAG_HARDWARE_ACCELERATED);
- mView = window.findViewById(R.id.content);
- Interaction.register(mView, new Interaction.Callback() {
- @Override
- public void onInteraction() {
- resetTimeout();
- }
- });
-
- mPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.visible_panel);
- mSliderPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.slider_panel);
- mZenPanel = (ZenModePanel) mView.findViewById(com.android.systemui.R.id.zen_mode_panel);
- initZenModePanel();
-
- mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
- mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
- mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
- mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
-
- if (mZenController != null) {
- mZenModeAvailable = mZenController.isZenAvailable();
- mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
- mZenController.addCallback(mZenCallback);
- }
-
- registerReceiver();
- }
-
- public void onConfigurationChanged(Configuration newConfig) {
- updateWidth();
- if (mZenPanel != null) {
- mZenPanel.updateLocale();
- }
- }
-
- private void updateWidth() {
- final Resources res = mContext.getResources();
- final LayoutParams lp = mDialog.getWindow().getAttributes();
- lp.width = res.getDimensionPixelSize(com.android.systemui.R.dimen.notification_panel_width);
- lp.gravity =
- res.getInteger(com.android.systemui.R.integer.notification_panel_layout_gravity);
- mDialog.getWindow().setAttributes(lp);
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("VolumePanel state:");
- pw.print(" mTag="); pw.println(mTag);
- pw.print(" mRingIsSilent="); pw.println(mRingIsSilent);
- pw.print(" mVoiceCapable="); pw.println(mVoiceCapable);
- pw.print(" mHasVibrator="); pw.println(mHasVibrator);
- pw.print(" mZenModeAvailable="); pw.println(mZenModeAvailable);
- pw.print(" mZenPanelExpanded="); pw.println(mZenPanelExpanded);
- pw.print(" mNotificationEffectsSuppressor="); pw.println(mNotificationEffectsSuppressor);
- pw.print(" mTimeoutDelay="); pw.println(mTimeoutDelay);
- pw.print(" mDisabledAlpha="); pw.println(mDisabledAlpha);
- pw.print(" mLastRingerMode="); pw.println(mLastRingerMode);
- pw.print(" mLastRingerProgress="); pw.println(mLastRingerProgress);
- pw.print(" isShowing()="); pw.println(isShowing());
- pw.print(" mCallback="); pw.println(mCallback);
- pw.print(" sConfirmSafeVolumeDialog=");
- pw.println(sSafetyWarning != null ? "<not null>" : null);
- pw.print(" mActiveStreamType="); pw.println(mActiveStreamType);
- pw.print(" mStreamControls=");
- if (mStreamControls == null) {
- pw.println("null");
- } else {
- final int N = mStreamControls.size();
- pw.print("<size "); pw.print(N); pw.println('>');
- for (int i = 0; i < N; i++) {
- final StreamControl sc = mStreamControls.valueAt(i);
- pw.print(" stream "); pw.print(sc.streamType); pw.print(":");
- if (sc.seekbarView != null) {
- pw.print(" progress="); pw.print(sc.seekbarView.getProgress());
- pw.print(" of "); pw.print(sc.seekbarView.getMax());
- if (!sc.seekbarView.isEnabled()) pw.print(" (disabled)");
- }
- if (sc.icon != null && sc.icon.isClickable()) pw.print(" (clickable)");
- pw.println();
- }
- }
- if (mZenPanel != null) {
- mZenPanel.dump(fd, pw, args);
- }
- }
-
- private void initZenModePanel() {
- mZenPanel.init(mZenController);
- mZenPanel.setCallback(new ZenModePanel.Callback() {
- @Override
- public void onMoreSettings() {
- if (mCallback != null) {
- mCallback.onZenSettings();
- }
- }
-
- @Override
- public void onPrioritySettings() {
- if (mCallback != null) {
- mCallback.onZenPrioritySettings();
- }
- }
-
- @Override
- public void onInteraction() {
- resetTimeout();
- }
-
- @Override
- public void onExpanded(boolean expanded) {
- if (mZenPanelExpanded == expanded) return;
- mZenPanelExpanded = expanded;
- updateTimeoutDelay();
- resetTimeout();
- }
- });
- }
-
- private void setLayoutDirection(int layoutDirection) {
- mPanel.setLayoutDirection(layoutDirection);
- updateStates();
- }
-
- private void registerReceiver() {
- final IntentFilter filter = new IntentFilter();
- filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
- filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- mContext.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
-
- if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
- removeMessages(MSG_RINGER_MODE_CHANGED);
- sendEmptyMessage(MSG_RINGER_MODE_CHANGED);
- }
-
- if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
- removeMessages(MSG_INTERNAL_RINGER_MODE_CHANGED);
- sendEmptyMessage(MSG_INTERNAL_RINGER_MODE_CHANGED);
- }
-
- if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- postDismiss(0);
- }
- }
- }, filter);
- }
-
- private boolean isMuted(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- // TODO do we need to support a distinct mute property for remote?
- return false;
- } else {
- return mAudioManager.isStreamMute(streamType);
- }
- }
-
- private int getStreamMinVolume(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- return 0;
- } else {
- return mAudioManager.getStreamMinVolume(streamType);
- }
- }
-
- private int getStreamMaxVolume(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- if (mStreamControls != null) {
- StreamControl sc = mStreamControls.get(streamType);
- if (sc != null && sc.controller != null) {
- PlaybackInfo ai = sc.controller.getPlaybackInfo();
- return ai.getMaxVolume();
- }
- }
- return -1;
- } else {
- return mAudioManager.getStreamMaxVolume(streamType);
- }
- }
-
- private int getStreamVolume(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- if (mStreamControls != null) {
- StreamControl sc = mStreamControls.get(streamType);
- if (sc != null && sc.controller != null) {
- PlaybackInfo ai = sc.controller.getPlaybackInfo();
- return ai.getCurrentVolume();
- }
- }
- return -1;
- } else {
- return mAudioManager.getLastAudibleStreamVolume(streamType);
- }
- }
-
- private void setStreamVolume(StreamControl sc, int index, int flags) {
- if (sc.streamType == STREAM_REMOTE_MUSIC) {
- if (sc.controller != null) {
- sc.controller.setVolumeTo(index, flags);
- } else {
- Log.w(mTag, "Adjusting remote volume without a controller!");
- }
- } else if (getStreamVolume(sc.streamType) != index) {
- mAudioManager.setStreamVolume(sc.streamType, index, flags);
- }
- }
-
- private void createSliders() {
- final Resources res = mContext.getResources();
- final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
-
- mStreamControls = new SparseArray<StreamControl>(STREAMS.length);
-
- final StreamResources notificationStream = StreamResources.NotificationStream;
- for (int i = 0; i < STREAMS.length; i++) {
- StreamResources streamRes = STREAMS[i];
-
- final int streamType = streamRes.streamType;
- final boolean isNotification = isNotificationOrRing(streamType);
-
- final StreamControl sc = new StreamControl();
- sc.streamType = streamType;
- sc.group = (ViewGroup) inflater.inflate(
- com.android.systemui.R.layout.volume_panel_item, null);
- sc.group.setTag(sc);
- sc.icon = (ImageView) sc.group.findViewById(com.android.systemui.R.id.stream_icon);
- sc.icon.setTag(sc);
- sc.icon.setContentDescription(res.getString(streamRes.descRes));
- sc.iconRes = streamRes.iconRes;
- sc.iconMuteRes = streamRes.iconMuteRes;
- sc.icon.setImageResource(sc.iconRes);
- sc.icon.setClickable(isNotification && mHasVibrator);
- if (isNotification) {
- if (mHasVibrator) {
- sc.icon.setSoundEffectsEnabled(false);
- sc.iconMuteRes = com.android.systemui.R.drawable.ic_ringer_vibrate;
- sc.icon.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- resetTimeout();
- toggleRinger(sc);
- }
- });
- }
- sc.iconSuppressedRes = com.android.systemui.R.drawable.ic_ringer_mute;
- }
- sc.seekbarView = (SeekBar) sc.group.findViewById(com.android.systemui.R.id.seekbar);
- sc.suppressorView =
- (TextView) sc.group.findViewById(com.android.systemui.R.id.suppressor);
- sc.suppressorView.setVisibility(View.GONE);
- final boolean showSecondary = !isNotification && notificationStream.show;
- sc.divider = sc.group.findViewById(com.android.systemui.R.id.divider);
- sc.secondaryIcon = (ImageView) sc.group
- .findViewById(com.android.systemui.R.id.secondary_icon);
- sc.secondaryIcon.setImageResource(com.android.systemui.R.drawable.ic_ringer_audible);
- sc.secondaryIcon.setContentDescription(res.getString(notificationStream.descRes));
- sc.secondaryIcon.setClickable(showSecondary);
- sc.divider.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
- sc.secondaryIcon.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
- if (showSecondary) {
- sc.secondaryIcon.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mSecondaryIconTransition.start(sc);
- }
- });
- }
- sc.minVolume = getStreamMinVolume(streamType);
- sc.seekbarView.setMax(getStreamMaxVolume(streamType) - sc.minVolume);
- sc.seekbarView.setOnSeekBarChangeListener(mSeekListener);
- sc.seekbarView.setTag(sc);
- mStreamControls.put(streamType, sc);
- }
- }
-
- private void toggleRinger(StreamControl sc) {
- if (!mHasVibrator) return;
- if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL) {
- mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_VIBRATE);
- postVolumeChanged(sc.streamType, AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
- } else {
- mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
- postVolumeChanged(sc.streamType, AudioManager.FLAG_PLAY_SOUND);
- }
- }
-
- private void reorderSliders(int activeStreamType) {
- mSliderPanel.removeAllViews();
-
- final StreamControl active = mStreamControls.get(activeStreamType);
- if (active == null) {
- Log.e(TAG, "Missing stream type! - " + activeStreamType);
- mActiveStreamType = -1;
- } else {
- mSliderPanel.addView(active.group);
- mActiveStreamType = activeStreamType;
- active.group.setVisibility(View.VISIBLE);
- updateSlider(active, true /*forceReloadIcon*/);
- updateTimeoutDelay();
- updateZenPanelVisible();
- }
- }
-
- private void updateSliderProgress(StreamControl sc, int progress) {
- final boolean isRinger = isNotificationOrRing(sc.streamType);
- if (isRinger && mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
- progress = mLastRingerProgress;
- }
- if (progress < 0) {
- progress = getStreamVolume(sc.streamType);
- }
- sc.seekbarView.setProgress(progress - sc.minVolume);
- if (isRinger) {
- mLastRingerProgress = progress;
- }
- }
-
- private void updateSliderIcon(StreamControl sc, boolean muted) {
- ComponentName suppressor = null;
- if (isNotificationOrRing(sc.streamType)) {
- suppressor = mNotificationEffectsSuppressor;
- int ringerMode = mAudioManager.getRingerModeInternal();
- if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
- ringerMode = mLastRingerMode;
- } else {
- mLastRingerMode = ringerMode;
- }
- if (mHasVibrator) {
- muted = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
- } else {
- muted = false;
- }
- }
- sc.icon.setImageResource(mDemoIcon != 0 ? mDemoIcon
- : suppressor != null ? sc.iconSuppressedRes
- : muted ? sc.iconMuteRes
- : sc.iconRes);
- }
-
- private void updateSliderSuppressor(StreamControl sc) {
- final ComponentName suppressor = isNotificationOrRing(sc.streamType)
- ? mNotificationEffectsSuppressor : null;
- if (suppressor == null) {
- sc.seekbarView.setVisibility(View.VISIBLE);
- sc.suppressorView.setVisibility(View.GONE);
- } else {
- sc.seekbarView.setVisibility(View.GONE);
- sc.suppressorView.setVisibility(View.VISIBLE);
- sc.suppressorView.setText(mContext.getString(R.string.muted_by,
- getSuppressorCaption(suppressor)));
- }
- }
-
- private String getSuppressorCaption(ComponentName suppressor) {
- final PackageManager pm = mContext.getPackageManager();
- try {
- final ServiceInfo info = pm.getServiceInfo(suppressor, 0);
- if (info != null) {
- final CharSequence seq = info.loadLabel(pm);
- if (seq != null) {
- final String str = seq.toString().trim();
- if (str.length() > 0) {
- return str;
- }
- }
- }
- } catch (Throwable e) {
- Log.w(TAG, "Error loading suppressor caption", e);
- }
- return suppressor.getPackageName();
- }
-
- /** Update the mute and progress state of a slider */
- private void updateSlider(StreamControl sc, boolean forceReloadIcon) {
- updateSliderProgress(sc, -1);
- final boolean muted = isMuted(sc.streamType);
- if (forceReloadIcon) {
- sc.icon.setImageDrawable(null);
- }
- updateSliderIcon(sc, muted);
- updateSliderEnabled(sc, muted, false);
- updateSliderSuppressor(sc);
- }
-
- private void updateSliderEnabled(final StreamControl sc, boolean muted, boolean fixedVolume) {
- final boolean wasEnabled = sc.seekbarView.isEnabled();
- final boolean isRinger = isNotificationOrRing(sc.streamType);
- if (sc.streamType == STREAM_REMOTE_MUSIC) {
- // never disable touch interactions for remote playback, the muting is not tied to
- // the state of the phone.
- sc.seekbarView.setEnabled(!fixedVolume);
- } else if (isRinger && mNotificationEffectsSuppressor != null) {
- sc.icon.setEnabled(true);
- sc.icon.setAlpha(1f);
- sc.icon.setClickable(false);
- } else if (isRinger
- && mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
- sc.seekbarView.setEnabled(false);
- sc.icon.setEnabled(false);
- sc.icon.setAlpha(mDisabledAlpha);
- sc.icon.setClickable(false);
- } else if (fixedVolume ||
- (sc.streamType != mAudioManager.getUiSoundsStreamType() && !isRinger && muted) ||
- (sSafetyWarning != null)) {
- sc.seekbarView.setEnabled(false);
- } else {
- sc.seekbarView.setEnabled(true);
- sc.icon.setEnabled(true);
- sc.icon.setAlpha(1f);
- }
- // show the silent hint when the disabled slider is touched in silent mode
- if (isRinger && wasEnabled != sc.seekbarView.isEnabled()) {
- if (sc.seekbarView.isEnabled()) {
- sc.group.setOnTouchListener(null);
- sc.icon.setClickable(mHasVibrator);
- } else {
- final View.OnTouchListener showHintOnTouch = new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- resetTimeout();
- showSilentHint();
- return false;
- }
- };
- sc.group.setOnTouchListener(showHintOnTouch);
- }
- }
- }
-
- private void showSilentHint() {
- if (mZenPanel != null) {
- mZenPanel.showSilentHint();
- }
- }
-
- private void showVibrateHint() {
- final StreamControl active = mStreamControls.get(mActiveStreamType);
- if (active != null) {
- mIconPulser.start(active.icon);
- if (!hasMessages(MSG_VIBRATE)) {
- sendEmptyMessageDelayed(MSG_VIBRATE, VIBRATE_DELAY);
- }
- }
- }
-
- private static boolean isNotificationOrRing(int streamType) {
- return streamType == AudioManager.STREAM_RING
- || streamType == AudioManager.STREAM_NOTIFICATION;
- }
-
- public void setCallback(Callback callback) {
- mCallback = callback;
- }
-
- private void updateTimeoutDelay() {
- mTimeoutDelay = mDemoIcon != 0 ? TIMEOUT_DELAY_EXPANDED
- : sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
- : mActiveStreamType == AudioManager.STREAM_MUSIC ? TIMEOUT_DELAY_SHORT
- : mZenPanelExpanded ? TIMEOUT_DELAY_EXPANDED
- : isZenPanelVisible() ? TIMEOUT_DELAY_COLLAPSED
- : TIMEOUT_DELAY;
- }
-
- private boolean isZenPanelVisible() {
- return mZenPanel != null && mZenPanel.getVisibility() == View.VISIBLE;
- }
-
- private void setZenPanelVisible(boolean visible) {
- if (LOGD) Log.d(mTag, "setZenPanelVisible " + visible + " mZenPanel=" + mZenPanel);
- final boolean changing = visible != isZenPanelVisible();
- if (visible) {
- mZenPanel.setHidden(false);
- resetTimeout();
- } else {
- mZenPanel.setHidden(true);
- }
- if (changing) {
- updateTimeoutDelay();
- resetTimeout();
- }
- }
-
- private void updateStates() {
- final int count = mSliderPanel.getChildCount();
- for (int i = 0; i < count; i++) {
- StreamControl sc = (StreamControl) mSliderPanel.getChildAt(i).getTag();
- updateSlider(sc, true /*forceReloadIcon*/);
- }
- }
-
- private void updateActiveSlider() {
- final StreamControl active = mStreamControls.get(mActiveStreamType);
- if (active != null) {
- updateSlider(active, false /*forceReloadIcon*/);
- }
- }
-
- private void updateZenPanelVisible() {
- setZenPanelVisible(mZenModeAvailable && isNotificationOrRing(mActiveStreamType));
- }
-
- public void postVolumeChanged(int streamType, int flags) {
- if (hasMessages(MSG_VOLUME_CHANGED)) return;
- synchronized (this) {
- if (mStreamControls == null) {
- createSliders();
- }
- }
- removeMessages(MSG_FREE_RESOURCES);
- obtainMessage(MSG_VOLUME_CHANGED, streamType, flags).sendToTarget();
- }
-
- public void postRemoteVolumeChanged(MediaController controller, int flags) {
- if (hasMessages(MSG_REMOTE_VOLUME_CHANGED)) return;
- synchronized (this) {
- if (mStreamControls == null) {
- createSliders();
- }
- }
- removeMessages(MSG_FREE_RESOURCES);
- obtainMessage(MSG_REMOTE_VOLUME_CHANGED, flags, 0, controller).sendToTarget();
- }
-
- public void postRemoteSliderVisibility(boolean visible) {
- obtainMessage(MSG_SLIDER_VISIBILITY_CHANGED,
- STREAM_REMOTE_MUSIC, visible ? 1 : 0).sendToTarget();
- }
-
- /**
- * Called by AudioService when it has received new remote playback information that
- * would affect the VolumePanel display (mainly volumes). The difference with
- * {@link #postRemoteVolumeChanged(int, int)} is that the handling of the posted message
- * (MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN) will only update the volume slider if it is being
- * displayed.
- * This special code path is due to the fact that remote volume updates arrive to AudioService
- * asynchronously. So after AudioService has sent the volume update (which should be treated
- * as a request to update the volume), the application will likely set a new volume. If the UI
- * is still up, we need to refresh the display to show this new value.
- */
- public void postHasNewRemotePlaybackInfo() {
- if (hasMessages(MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN)) return;
- // don't create or prevent resources to be freed, if they disappear, this update came too
- // late and shouldn't warrant the panel to be displayed longer
- obtainMessage(MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN).sendToTarget();
- }
-
- public void postMuteChanged(int streamType, int flags) {
- if (hasMessages(MSG_VOLUME_CHANGED)) return;
- synchronized (this) {
- if (mStreamControls == null) {
- createSliders();
- }
- }
- removeMessages(MSG_FREE_RESOURCES);
- obtainMessage(MSG_MUTE_CHANGED, streamType, flags).sendToTarget();
- }
-
- public void postDisplaySafeVolumeWarning(int flags) {
- if (hasMessages(MSG_DISPLAY_SAFE_VOLUME_WARNING)) return;
- obtainMessage(MSG_DISPLAY_SAFE_VOLUME_WARNING, flags, 0).sendToTarget();
- }
-
- public void postDismiss(long delay) {
- forceTimeout(delay);
- }
-
- public void postLayoutDirection(int layoutDirection) {
- removeMessages(MSG_LAYOUT_DIRECTION);
- obtainMessage(MSG_LAYOUT_DIRECTION, layoutDirection, 0).sendToTarget();
- }
-
- private static String flagsToString(int flags) {
- return flags == 0 ? "0" : (flags + "=" + AudioManager.flagsToString(flags));
- }
-
- private static String streamToString(int stream) {
- return AudioSystem.streamToString(stream);
- }
-
- /**
- * Override this if you have other work to do when the volume changes (for
- * example, vibrating, playing a sound, etc.). Make sure to call through to
- * the superclass implementation.
- */
- protected void onVolumeChanged(int streamType, int flags) {
-
- if (LOGD) Log.d(mTag, "onVolumeChanged(streamType: " + streamToString(streamType)
- + ", flags: " + flagsToString(flags) + ")");
-
- if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
- synchronized (this) {
- if (mActiveStreamType != streamType) {
- reorderSliders(streamType);
- }
- onShowVolumeChanged(streamType, flags, null);
- }
- }
-
- if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && ! mRingIsSilent) {
- removeMessages(MSG_PLAY_SOUND);
- sendMessageDelayed(obtainMessage(MSG_PLAY_SOUND, streamType, flags), PLAY_SOUND_DELAY);
- }
-
- if ((flags & AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE) != 0) {
- removeMessages(MSG_PLAY_SOUND);
- removeMessages(MSG_VIBRATE);
- onStopSounds();
- }
-
- removeMessages(MSG_FREE_RESOURCES);
- sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
- resetTimeout();
- }
-
- protected void onMuteChanged(int streamType, int flags) {
-
- if (LOGD) Log.d(mTag, "onMuteChanged(streamType: " + streamToString(streamType)
- + ", flags: " + flagsToString(flags) + ")");
-
- StreamControl sc = mStreamControls.get(streamType);
- if (sc != null) {
- updateSliderIcon(sc, isMuted(sc.streamType));
- }
-
- onVolumeChanged(streamType, flags);
- }
-
- protected void onShowVolumeChanged(int streamType, int flags, MediaController controller) {
- int index = getStreamVolume(streamType);
-
- mRingIsSilent = false;
-
- if (LOGD) {
- Log.d(mTag, "onShowVolumeChanged(streamType: " + streamToString(streamType)
- + ", flags: " + flagsToString(flags) + "), index: " + index);
- }
-
- // get max volume for progress bar
-
- int max = getStreamMaxVolume(streamType) - getStreamMinVolume(streamType);
- StreamControl sc = mStreamControls.get(streamType);
-
- switch (streamType) {
-
- case AudioManager.STREAM_RING: {
- Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
- mContext, RingtoneManager.TYPE_RINGTONE);
- if (ringuri == null) {
- mRingIsSilent = true;
- }
- break;
- }
-
- case AudioManager.STREAM_MUSIC: {
- // Special case for when Bluetooth is active for music
- if ((mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC) &
- (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
- AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
- setMusicIcon(IC_AUDIO_BT, IC_AUDIO_BT_MUTE);
- } else {
- setMusicIcon(IC_AUDIO_VOL, IC_AUDIO_VOL_MUTE);
- }
- break;
- }
-
- case AudioManager.STREAM_ALARM: {
- break;
- }
-
- case AudioManager.STREAM_NOTIFICATION: {
- Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
- mContext, RingtoneManager.TYPE_NOTIFICATION);
- if (ringuri == null) {
- mRingIsSilent = true;
- }
- break;
- }
-
- case STREAM_REMOTE_MUSIC: {
- if (controller == null && sc != null) {
- // If we weren't passed one try using the last one set.
- controller = sc.controller;
- }
- if (controller == null) {
- // We still don't have one, ignore the command.
- Log.w(mTag, "sent remote volume change without a controller!");
- } else {
- PlaybackInfo vi = controller.getPlaybackInfo();
- index = vi.getCurrentVolume();
- max = vi.getMaxVolume();
- if ((vi.getVolumeControl() & VolumeProvider.VOLUME_CONTROL_FIXED) != 0) {
- // if the remote volume is fixed add the flag for the UI
- flags |= AudioManager.FLAG_FIXED_VOLUME;
- }
- }
- if (LOGD) { Log.d(mTag, "showing remote volume "+index+" over "+ max); }
- break;
- }
- }
-
- if (sc != null) {
- if (streamType == STREAM_REMOTE_MUSIC && controller != sc.controller) {
- if (sc.controller != null) {
- sc.controller.unregisterCallback(mMediaControllerCb);
- }
- sc.controller = controller;
- if (controller != null) {
- sc.controller.registerCallback(mMediaControllerCb);
- }
- }
- if (sc.seekbarView.getMax() != max) {
- sc.seekbarView.setMax(max);
- }
- updateSliderProgress(sc, index);
- final boolean muted = isMuted(streamType);
- updateSliderEnabled(sc, muted, (flags & AudioManager.FLAG_FIXED_VOLUME) != 0);
- if (isNotificationOrRing(streamType)) {
- // check for secondary-icon transition completion
- if (mSecondaryIconTransition.isRunning()) {
- mSecondaryIconTransition.cancel(); // safe to reset
- sc.seekbarView.setAlpha(0); sc.seekbarView.animate().alpha(1);
- mZenPanel.setAlpha(0); mZenPanel.animate().alpha(1);
- }
- updateSliderIcon(sc, muted);
- }
- }
-
- if (!isShowing()) {
- int stream = (streamType == STREAM_REMOTE_MUSIC) ? -1 : streamType;
- // when the stream is for remote playback, use -1 to reset the stream type evaluation
- mAudioManager.forceVolumeControlStream(stream);
- mDialog.show();
- if (mCallback != null) {
- mCallback.onVisible(true);
- }
- announceDialogShown();
- }
-
- // Do a little vibrate if applicable (only when going into vibrate mode)
- if ((streamType != STREAM_REMOTE_MUSIC) &&
- ((flags & AudioManager.FLAG_VIBRATE) != 0) &&
- isNotificationOrRing(streamType) &&
- mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
- sendMessageDelayed(obtainMessage(MSG_VIBRATE), VIBRATE_DELAY);
- }
-
- // Pulse the zen icon if an adjustment was suppressed due to silent mode.
- if ((flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
- showSilentHint();
- }
-
- // Pulse the slider icon & vibrate if an adjustment down was suppressed due to vibrate mode.
- if ((flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
- showVibrateHint();
- }
- }
-
- private void announceDialogShown() {
- mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- }
-
- private boolean isShowing() {
- return mDialog.isShowing();
- }
-
- protected void onPlaySound(int streamType, int flags) {
-
- if (hasMessages(MSG_STOP_SOUNDS)) {
- removeMessages(MSG_STOP_SOUNDS);
- // Force stop right now
- onStopSounds();
- }
-
- synchronized (this) {
- ToneGenerator toneGen = getOrCreateToneGenerator(streamType);
- if (toneGen != null) {
- toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
- sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
- }
- }
- }
-
- protected void onStopSounds() {
-
- synchronized (this) {
- int numStreamTypes = AudioSystem.getNumStreamTypes();
- for (int i = numStreamTypes - 1; i >= 0; i--) {
- ToneGenerator toneGen = mToneGenerators[i];
- if (toneGen != null) {
- toneGen.stopTone();
- }
- }
- }
- }
-
- protected void onVibrate() {
-
- // Make sure we ended up in vibrate ringer mode
- if (mAudioManager.getRingerModeInternal() != AudioManager.RINGER_MODE_VIBRATE) {
- return;
- }
- if (mVibrator != null) {
- mVibrator.vibrate(VIBRATE_DURATION, VIBRATION_ATTRIBUTES);
- }
- }
-
- protected void onRemoteVolumeChanged(MediaController controller, int flags) {
- if (LOGD) Log.d(mTag, "onRemoteVolumeChanged(controller:" + controller + ", flags: "
- + flagsToString(flags) + ")");
-
- if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || isShowing()) {
- synchronized (this) {
- if (mActiveStreamType != STREAM_REMOTE_MUSIC) {
- reorderSliders(STREAM_REMOTE_MUSIC);
- }
- onShowVolumeChanged(STREAM_REMOTE_MUSIC, flags, controller);
- }
- } else {
- if (LOGD) Log.d(mTag, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI");
- }
-
- removeMessages(MSG_FREE_RESOURCES);
- sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
- resetTimeout();
- }
-
- protected void onRemoteVolumeUpdateIfShown() {
- if (LOGD) Log.d(mTag, "onRemoteVolumeUpdateIfShown()");
- if (isShowing()
- && (mActiveStreamType == STREAM_REMOTE_MUSIC)
- && (mStreamControls != null)) {
- onShowVolumeChanged(STREAM_REMOTE_MUSIC, 0, null);
- }
- }
-
- /**
- * Clear the current remote stream controller.
- */
- private void clearRemoteStreamController() {
- if (mStreamControls != null) {
- StreamControl sc = mStreamControls.get(STREAM_REMOTE_MUSIC);
- if (sc != null) {
- if (sc.controller != null) {
- sc.controller.unregisterCallback(mMediaControllerCb);
- sc.controller = null;
- }
- }
- }
- }
-
- /**
- * Handler for MSG_SLIDER_VISIBILITY_CHANGED Hide or show a slider
- *
- * @param streamType can be a valid stream type value, or
- * VolumePanel.STREAM_MASTER, or VolumePanel.STREAM_REMOTE_MUSIC
- * @param visible
- */
- synchronized protected void onSliderVisibilityChanged(int streamType, int visible) {
- if (LOGD) Log.d(mTag, "onSliderVisibilityChanged(stream="+streamType+", visi="+visible+")");
- boolean isVisible = (visible == 1);
- for (int i = STREAMS.length - 1 ; i >= 0 ; i--) {
- StreamResources streamRes = STREAMS[i];
- if (streamRes.streamType == streamType) {
- streamRes.show = isVisible;
- if (!isVisible && (mActiveStreamType == streamType)) {
- mActiveStreamType = -1;
- }
- break;
- }
- }
- }
-
- protected void onDisplaySafeVolumeWarning(int flags) {
- if ((flags & (AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_SHOW_UI_WARNINGS)) != 0
- || isShowing()) {
- synchronized (sSafetyWarningLock) {
- if (sSafetyWarning != null) {
- return;
- }
- sSafetyWarning = new SafetyWarningDialog(mContext, mAudioManager) {
- @Override
- protected void cleanUp() {
- synchronized (sSafetyWarningLock) {
- sSafetyWarning = null;
- }
- forceTimeout(0);
- updateStates();
- }
- };
- sSafetyWarning.show();
- }
- updateStates();
- }
- if (mAccessibilityManager.isTouchExplorationEnabled()) {
- removeMessages(MSG_TIMEOUT);
- } else {
- updateTimeoutDelay();
- resetTimeout();
- }
- }
-
- /**
- * Lock on this VolumePanel instance as long as you use the returned ToneGenerator.
- */
- private ToneGenerator getOrCreateToneGenerator(int streamType) {
- synchronized (this) {
- if (mToneGenerators[streamType] == null) {
- try {
- mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
- } catch (RuntimeException e) {
- if (LOGD) {
- Log.d(mTag, "ToneGenerator constructor failed with "
- + "RuntimeException: " + e);
- }
- }
- }
- return mToneGenerators[streamType];
- }
- }
-
-
- /**
- * Switch between icons because Bluetooth music is same as music volume, but with
- * different icons.
- */
- private void setMusicIcon(int resId, int resMuteId) {
- StreamControl sc = mStreamControls.get(AudioManager.STREAM_MUSIC);
- if (sc != null) {
- sc.iconRes = resId;
- sc.iconMuteRes = resMuteId;
- updateSliderIcon(sc, isMuted(sc.streamType));
- }
- }
-
- protected void onFreeResources() {
- synchronized (this) {
- for (int i = mToneGenerators.length - 1; i >= 0; i--) {
- if (mToneGenerators[i] != null) {
- mToneGenerators[i].release();
- }
- mToneGenerators[i] = null;
- }
- }
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
-
- case MSG_VOLUME_CHANGED: {
- onVolumeChanged(msg.arg1, msg.arg2);
- break;
- }
-
- case MSG_MUTE_CHANGED: {
- onMuteChanged(msg.arg1, msg.arg2);
- break;
- }
-
- case MSG_FREE_RESOURCES: {
- onFreeResources();
- break;
- }
-
- case MSG_STOP_SOUNDS: {
- onStopSounds();
- break;
- }
-
- case MSG_PLAY_SOUND: {
- onPlaySound(msg.arg1, msg.arg2);
- break;
- }
-
- case MSG_VIBRATE: {
- onVibrate();
- break;
- }
-
- case MSG_TIMEOUT: {
- if (isShowing()) {
- mDialog.dismiss();
- clearRemoteStreamController();
- mActiveStreamType = -1;
- if (mCallback != null) {
- mCallback.onVisible(false);
- }
- }
- synchronized (sSafetyWarningLock) {
- if (sSafetyWarning != null) {
- if (LOGD) Log.d(mTag, "SafetyWarning timeout");
- sSafetyWarning.dismiss();
- }
- }
- break;
- }
-
- case MSG_RINGER_MODE_CHANGED:
- case MSG_INTERNAL_RINGER_MODE_CHANGED:
- case MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED: {
- if (isShowing()) {
- updateActiveSlider();
- }
- break;
- }
-
- case MSG_REMOTE_VOLUME_CHANGED: {
- onRemoteVolumeChanged((MediaController) msg.obj, msg.arg1);
- break;
- }
-
- case MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN:
- onRemoteVolumeUpdateIfShown();
- break;
-
- case MSG_SLIDER_VISIBILITY_CHANGED:
- onSliderVisibilityChanged(msg.arg1, msg.arg2);
- break;
-
- case MSG_DISPLAY_SAFE_VOLUME_WARNING:
- onDisplaySafeVolumeWarning(msg.arg1);
- break;
-
- case MSG_LAYOUT_DIRECTION:
- setLayoutDirection(msg.arg1);
- break;
-
- case MSG_ZEN_MODE_AVAILABLE_CHANGED:
- mZenModeAvailable = msg.arg1 != 0;
- updateZenPanelVisible();
- break;
-
- case MSG_USER_ACTIVITY:
- if (mCallback != null) {
- mCallback.onInteraction();
- }
- break;
- }
- }
-
- private void resetTimeout() {
- final boolean touchExploration = mAccessibilityManager.isTouchExplorationEnabled();
- if (LOGD) Log.d(mTag, "resetTimeout at " + System.currentTimeMillis()
- + " delay=" + mTimeoutDelay + " touchExploration=" + touchExploration);
- if (sSafetyWarning == null || !touchExploration) {
- removeMessages(MSG_TIMEOUT);
- sendEmptyMessageDelayed(MSG_TIMEOUT, mTimeoutDelay);
- removeMessages(MSG_USER_ACTIVITY);
- sendEmptyMessage(MSG_USER_ACTIVITY);
- }
- }
-
- private void forceTimeout(long delay) {
- if (LOGD) Log.d(mTag, "forceTimeout delay=" + delay + " callers=" + Debug.getCallers(3));
- removeMessages(MSG_TIMEOUT);
- sendEmptyMessageDelayed(MSG_TIMEOUT, delay);
- }
-
- public ZenModeController getZenController() {
- return mZenController;
- }
-
- @Override
- public void dispatchDemoCommand(String command, Bundle args) {
- if (!COMMAND_VOLUME.equals(command)) return;
- String icon = args.getString("icon");
- final String iconMute = args.getString("iconmute");
- final boolean mute = iconMute != null;
- icon = mute ? iconMute : icon;
- icon = icon.endsWith("Stream") ? icon : (icon + "Stream");
- final StreamResources sr = StreamResources.valueOf(icon);
- mDemoIcon = mute ? sr.iconMuteRes : sr.iconRes;
- final int forcedStreamType = StreamResources.MediaStream.streamType;
- mAudioManager.forceVolumeControlStream(forcedStreamType);
- mAudioManager.adjustStreamVolume(forcedStreamType, AudioManager.ADJUST_SAME,
- AudioManager.FLAG_SHOW_UI);
- }
-
- private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- final Object tag = seekBar.getTag();
- if (fromUser && tag instanceof StreamControl) {
- StreamControl sc = (StreamControl) tag;
- setStreamVolume(sc, progress + sc.minVolume,
- AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
- }
- resetTimeout();
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
- };
-
- private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
- @Override
- public void onZenAvailableChanged(boolean available) {
- obtainMessage(MSG_ZEN_MODE_AVAILABLE_CHANGED, available ? 1 : 0, 0).sendToTarget();
- }
-
- @Override
- public void onEffectsSupressorChanged() {
- mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
- sendEmptyMessage(MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED);
- }
- };
-
- private final MediaController.Callback mMediaControllerCb = new MediaController.Callback() {
- public void onAudioInfoChanged(PlaybackInfo info) {
- onRemoteVolumeUpdateIfShown();
- }
- };
-
- private final class SecondaryIconTransition extends AnimatorListenerAdapter
- implements Runnable {
- private static final int ANIMATION_TIME = 400;
- private static final int WAIT_FOR_SWITCH_TIME = 1000;
-
- private final int mAnimationTime = (int)(ANIMATION_TIME * ValueAnimator.getDurationScale());
- private final int mFadeOutTime = mAnimationTime / 2;
- private final int mDelayTime = mAnimationTime / 3;
-
- private final Interpolator mIconInterpolator =
- AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in);
-
- private StreamControl mTarget;
-
- public void start(StreamControl sc) {
- if (sc == null) throw new IllegalArgumentException();
- if (LOGD) Log.d(mTag, "Secondary icon animation start");
- if (mTarget != null) {
- cancel();
- }
- mTarget = sc;
- mTimeoutDelay = mAnimationTime + WAIT_FOR_SWITCH_TIME;
- resetTimeout();
- mTarget.secondaryIcon.setClickable(false);
- final int N = mTarget.group.getChildCount();
- for (int i = 0; i < N; i++) {
- final View child = mTarget.group.getChildAt(i);
- if (child != mTarget.secondaryIcon) {
- child.animate().alpha(0).setDuration(mFadeOutTime).start();
- }
- }
- mTarget.secondaryIcon.animate()
- .translationXBy(mTarget.icon.getX() - mTarget.secondaryIcon.getX())
- .setInterpolator(mIconInterpolator)
- .setStartDelay(mDelayTime)
- .setDuration(mAnimationTime - mDelayTime)
- .setListener(this)
- .start();
- }
-
- public boolean isRunning() {
- return mTarget != null;
- }
-
- public void cancel() {
- if (mTarget == null) return;
- mTarget.secondaryIcon.setClickable(true);
- final int N = mTarget.group.getChildCount();
- for (int i = 0; i < N; i++) {
- final View child = mTarget.group.getChildAt(i);
- if (child != mTarget.secondaryIcon) {
- child.animate().cancel();
- child.setAlpha(1);
- }
- }
- mTarget.secondaryIcon.animate().cancel();
- mTarget.secondaryIcon.setTranslationX(0);
- mTarget = null;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mTarget == null) return;
- AsyncTask.execute(this);
- }
-
- @Override
- public void run() {
- if (mTarget == null) return;
- if (LOGD) Log.d(mTag, "Secondary icon animation complete, show notification slider");
- mAudioManager.forceVolumeControlStream(StreamResources.NotificationStream.streamType);
- mAudioManager.adjustStreamVolume(StreamResources.NotificationStream.streamType,
- AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
- }
- }
-
- public interface Callback {
- void onZenSettings();
- void onZenPrioritySettings();
- void onInteraction();
- void onVisible(boolean visible);
- }
-}