am 08e7eb03: am ec2b8cb3: Merge "Volume: Show safe media warning in settings." into lmp-dev

* commit '08e7eb032a7790559846e177b7b3dd39c8839a3f':
  Volume: Show safe media warning in settings.
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index d66fc0f..671f722 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -113,7 +113,8 @@
     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();
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c7b5580..056c1a6 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4498,7 +4498,7 @@
     <!-- 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] -->
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 52608a9..20ac8e9 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -354,6 +354,12 @@
     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.)
      *
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 050c268..d43aceb 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1131,6 +1131,13 @@
             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 @@
             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 @@
     // 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 @@
         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
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 0b8f876..61e6121 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -249,6 +249,11 @@
         <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>
@@ -275,7 +280,4 @@
         <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>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 7f27a0c..86a6622 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -29,12 +29,11 @@
 
     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);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index b85fbf3..149d09a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -58,6 +58,7 @@
 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 @@
     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 @@
     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 @@
             @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 @@
         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 @@
             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 @@
     }
 
     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 @@
     }
 
     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 @@
                         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;