OSDN Git Service

Volume: Show safe media warning in settings.
authorJohn Spurlock <jspurlock@google.com>
Thu, 24 Jul 2014 22:10:48 +0000 (18:10 -0400)
committerJohn Spurlock <jspurlock@google.com>
Fri, 25 Jul 2014 15:27:51 +0000 (11:27 -0400)
If the safe media warning is enabled, make sure
we display it from the new inline slider preference in
Settings (without showing the volume dialog itself).

Also:
 - Update the warning dialog to the new sysui theme.
 - Separate the warning sentences with an additional line.
 - Fix the auto-dismiss timeout.
 - Add a system property to additionally enable the safe
   media warning for testing
 - Add more information to audio service dumpsys.

Bug:15434662
Change-Id: I95fec12c9049bbfdb7ebdf246160e4b12c0c5be3

core/java/android/preference/SeekBarVolumizer.java
core/res/res/values/strings.xml
media/java/android/media/AudioManager.java
media/java/android/media/AudioService.java
packages/SystemUI/res/values/styles.xml
packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java

index d66fc0f..671f722 100644 (file)
@@ -113,7 +113,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
     public boolean handleMessage(Message msg) {
         switch (msg.what) {
             case MSG_SET_STREAM_VOLUME:
-                mAudioManager.setStreamVolume(mStreamType, mLastProgress, 0);
+                mAudioManager.setStreamVolume(mStreamType, mLastProgress,
+                        AudioManager.FLAG_SHOW_UI_WARNINGS);
                 break;
             case MSG_START_SAMPLE:
                 onStartSample();
index 351acf0..1782bc6 100644 (file)
     <!-- Message shown in dialog when user is attempting to set the music volume above the
     recommended maximum level for headphones -->
     <string name="safe_media_volume_warning" product="default">
-       "Raise volume above recommended level?\nListening at high volume for long periods may damage your hearing."
+       "Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."
     </string>
 
     <!-- Text spoken when the user is performing a gesture that will enable accessibility. [CHAR LIMIT=none] -->
index 52608a9..20ac8e9 100644 (file)
@@ -354,6 +354,12 @@ public class AudioManager {
     public static final int FLAG_ACTIVE_MEDIA_ONLY = 1 << 9;
 
     /**
+     * Like FLAG_SHOW_UI, but only dialog warnings and confirmations, no sliders.
+     * @hide
+     */
+    public static final int FLAG_SHOW_UI_WARNINGS = 1 << 10;
+
+    /**
      * Ringer mode that will be silent and will not vibrate. (This overrides the
      * vibrate setting.)
      *
index 050c268..d43aceb 100644 (file)
@@ -1131,6 +1131,13 @@ public class AudioService extends IAudioService.Stub {
             mFlags = flags;
             mDevice = device;
         }
+
+        @Override
+        public String toString() {
+            return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=")
+                    .append(mIndex).append(",flags=").append(mFlags).append(",device=")
+                    .append(mDevice).append('}').toString();
+        }
     };
 
     private void onSetStreamVolume(int streamType, int index, int flags, int device) {
@@ -2724,8 +2731,10 @@ public class AudioService extends IAudioService.Stub {
             if ((mMcc != mcc) || ((mMcc == 0) && force)) {
                 mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                         com.android.internal.R.integer.config_safe_media_volume_index) * 10;
-                boolean safeMediaVolumeEnabled = mContext.getResources().getBoolean(
-                        com.android.internal.R.bool.config_safe_media_volume_enabled);
+                boolean safeMediaVolumeEnabled =
+                        SystemProperties.getBoolean("audio.safemedia.force", false)
+                        || mContext.getResources().getBoolean(
+                                com.android.internal.R.bool.config_safe_media_volume_enabled);
 
                 // The persisted state is either "disabled" or "active": this is the state applied
                 // next time we boot and cannot be "inactive"
@@ -4863,10 +4872,10 @@ public class AudioService extends IAudioService.Stub {
     // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it
     // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume()
     // (when user opts out).
-    private final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
-    private final int SAFE_MEDIA_VOLUME_DISABLED = 1;
-    private final int SAFE_MEDIA_VOLUME_INACTIVE = 2;
-    private final int SAFE_MEDIA_VOLUME_ACTIVE = 3;
+    private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
+    private static final int SAFE_MEDIA_VOLUME_DISABLED = 1;
+    private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2;  // confirmed
+    private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3;  // unconfirmed
     private Integer mSafeMediaVolumeState;
 
     private int mMcc = 0;
@@ -5058,7 +5067,24 @@ public class AudioService extends IAudioService.Stub {
         pw.println("\nAudio routes:");
         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType));
         pw.print("  mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName);
+
+        pw.println("\nOther state:");
         pw.print("  mVolumeController="); pw.println(mVolumeController);
+        pw.print("  mSafeMediaVolumeState=");
+        pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
+        pw.print("  mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
+        pw.print("  mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
+        pw.print("  mMusicActiveMs="); pw.println(mMusicActiveMs);
+    }
+
+    private static String safeMediaVolumeStateToString(Integer state) {
+        switch(state) {
+            case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED";
+            case SAFE_MEDIA_VOLUME_DISABLED: return "SAFE_MEDIA_VOLUME_DISABLED";
+            case SAFE_MEDIA_VOLUME_INACTIVE: return "SAFE_MEDIA_VOLUME_INACTIVE";
+            case SAFE_MEDIA_VOLUME_ACTIVE: return "SAFE_MEDIA_VOLUME_ACTIVE";
+        }
+        return null;
     }
 
     // Inform AudioFlinger of our device's low RAM attribute
index 0b8f876..61e6121 100644 (file)
         <item name="android:colorControlActivated">@color/system_accent_color</item>
     </style>
 
+    <style name="Theme.SystemUI.Dialog" parent="@android:style/Theme.DeviceDefault.Light.Dialog">
+        <item name="android:colorPrimary">@color/system_primary_color</item>
+        <item name="android:colorControlActivated">@color/system_accent_color</item>
+    </style>
+
     <style name="NotificationsQuickSettings">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:textStyle">italic</item>
         <item name="android:textColor">#60000000</item>
     </style>
-
-    <style name="Theme.SystemUI.Dialog" parent="@android:style/Theme.DeviceDefault.Light.Dialog">
-    </style>
 </resources>
index 7f27a0c..86a6622 100644 (file)
@@ -29,12 +29,11 @@ public class SystemUIDialog extends AlertDialog {
 
     public SystemUIDialog(Context context) {
         super(context, R.style.Theme_SystemUI_Dialog);
-
         getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
         WindowManager.LayoutParams attrs = getWindow().getAttributes();
-        attrs.setTitle("SystemUIDialog");
+        attrs.setTitle(getClass().getSimpleName());
         getWindow().setAttributes(attrs);
     }
 }
index b85fbf3..149d09a 100644 (file)
@@ -58,6 +58,7 @@ import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 
 import com.android.internal.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.io.FileDescriptor;
@@ -89,6 +90,7 @@ public class VolumePanel extends Handler {
     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;
@@ -238,42 +240,61 @@ public class VolumePanel extends Handler {
     private ToneGenerator mToneGenerators[];
     private Vibrator mVibrator;
 
-    private static AlertDialog sConfirmSafeVolumeDialog;
-    private static Object sConfirmSafeVolumeLock = new Object();
+    private static AlertDialog sSafetyWarning;
+    private static Object sSafetyWarningLock = new Object();
 
-    private static class WarningDialogReceiver extends BroadcastReceiver
-            implements DialogInterface.OnDismissListener {
+    private static class SafetyWarning extends SystemUIDialog
+            implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
         private final Context mContext;
-        private final Dialog mDialog;
         private final VolumePanel mVolumePanel;
+        private final AudioManager mAudioManager;
 
-        WarningDialogReceiver(Context context, Dialog dialog, VolumePanel volumePanel) {
+        SafetyWarning(Context context, VolumePanel volumePanel, AudioManager audioManager) {
+            super(context);
             mContext = context;
-            mDialog = dialog;
             mVolumePanel = volumePanel;
+            mAudioManager = audioManager;
+
+            setMessage(mContext.getString(com.android.internal.R.string.safe_media_volume_warning));
+            setButton(DialogInterface.BUTTON_POSITIVE,
+                    mContext.getString(com.android.internal.R.string.yes), this);
+            setButton(DialogInterface.BUTTON_NEGATIVE,
+                    mContext.getString(com.android.internal.R.string.no), (OnClickListener) null);
+            setOnDismissListener(this);
+
             IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-            context.registerReceiver(this, filter);
+            context.registerReceiver(mReceiver, filter);
         }
 
         @Override
-        public void onReceive(Context context, Intent intent) {
-            mDialog.cancel();
-            cleanUp();
+        public void onClick(DialogInterface dialog, int which) {
+            mAudioManager.disableSafeMediaVolume();
         }
 
         @Override
         public void onDismiss(DialogInterface unused) {
-            mContext.unregisterReceiver(this);
+            mContext.unregisterReceiver(mReceiver);
             cleanUp();
         }
 
         private void cleanUp() {
-            synchronized (sConfirmSafeVolumeLock) {
-                sConfirmSafeVolumeDialog = null;
+            synchronized (sSafetyWarningLock) {
+                sSafetyWarning = null;
             }
             mVolumePanel.forceTimeout(0);
             mVolumePanel.updateStates();
         }
+
+        private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
+                    if (LOGD) Log.d(TAG, "Received ACTION_CLOSE_SYSTEM_DIALOGS");
+                    cancel();
+                    cleanUp();
+                }
+            }
+        };
     }
 
     public VolumePanel(Context context, ZenModeController zenController) {
@@ -305,7 +326,7 @@ public class VolumePanel extends Handler {
             @Override
             public boolean onTouchEvent(MotionEvent event) {
                 if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE &&
-                        sConfirmSafeVolumeDialog == null) {
+                        sSafetyWarning == null) {
                     forceTimeout(0);
                     return true;
                 }
@@ -389,7 +410,7 @@ public class VolumePanel extends Handler {
         pw.print("  isShowing()="); pw.println(isShowing());
         pw.print("  mCallback="); pw.println(mCallback);
         pw.print("  sConfirmSafeVolumeDialog=");
-        pw.println(sConfirmSafeVolumeDialog != null ? "<not null>" : null);
+        pw.println(sSafetyWarning != null ? "<not null>" : null);
         pw.print("  mActiveStreamType="); pw.println(mActiveStreamType);
         pw.print("  mStreamControls=");
         if (mStreamControls == null) {
@@ -640,7 +661,7 @@ public class VolumePanel extends Handler {
             sc.seekbarView.setEnabled(!fixedVolume);
         } else if (fixedVolume ||
                         (sc.streamType != mAudioManager.getMasterStreamType() && muted) ||
-                        (sConfirmSafeVolumeDialog != null)) {
+                        (sSafetyWarning != null)) {
             sc.seekbarView.setEnabled(false);
         } else if (isRinger && mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
             sc.seekbarView.setEnabled(false);
@@ -687,7 +708,8 @@ public class VolumePanel extends Handler {
     }
 
     private void updateTimeoutDelay() {
-        mTimeoutDelay = mActiveStreamType == AudioManager.STREAM_MUSIC ? TIMEOUT_DELAY_SHORT
+        mTimeoutDelay = sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
+                : mActiveStreamType == AudioManager.STREAM_MUSIC ? TIMEOUT_DELAY_SHORT
                 : mZenPanelExpanded ? TIMEOUT_DELAY_EXPANDED
                 : isZenPanelVisible() ? TIMEOUT_DELAY_COLLAPSED
                 : TIMEOUT_DELAY;
@@ -1105,30 +1127,14 @@ public class VolumePanel extends Handler {
     }
 
     protected void onDisplaySafeVolumeWarning(int flags) {
-        if ((flags & AudioManager.FLAG_SHOW_UI) != 0 || isShowing()) {
-            synchronized (sConfirmSafeVolumeLock) {
-                if (sConfirmSafeVolumeDialog != null) {
+        if ((flags & (AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_SHOW_UI_WARNINGS)) != 0
+                || isShowing()) {
+            synchronized (sSafetyWarningLock) {
+                if (sSafetyWarning != null) {
                     return;
                 }
-                sConfirmSafeVolumeDialog = new AlertDialog.Builder(mContext)
-                        .setMessage(com.android.internal.R.string.safe_media_volume_warning)
-                        .setPositiveButton(com.android.internal.R.string.yes,
-                                            new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int which) {
-                                mAudioManager.disableSafeMediaVolume();
-                            }
-                        })
-                        .setNegativeButton(com.android.internal.R.string.no, null)
-                        .setIconAttribute(android.R.attr.alertDialogIcon)
-                        .create();
-                final WarningDialogReceiver warning = new WarningDialogReceiver(mContext,
-                        sConfirmSafeVolumeDialog, this);
-
-                sConfirmSafeVolumeDialog.setOnDismissListener(warning);
-                sConfirmSafeVolumeDialog.getWindow().setType(
-                                                WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-                sConfirmSafeVolumeDialog.show();
+                sSafetyWarning = new SafetyWarning(mContext, this, mAudioManager);
+                sSafetyWarning.show();
             }
             updateStates();
         }
@@ -1232,9 +1238,10 @@ public class VolumePanel extends Handler {
                         mCallback.onVisible(false);
                     }
                 }
-                synchronized (sConfirmSafeVolumeLock) {
-                    if (sConfirmSafeVolumeDialog != null) {
-                        sConfirmSafeVolumeDialog.dismiss();
+                synchronized (sSafetyWarningLock) {
+                    if (sSafetyWarning != null) {
+                        if (LOGD) Log.d(mTag, "SafetyWarning timeout");
+                        sSafetyWarning.dismiss();
                     }
                 }
                 break;