more fixes on safe volume warning message

Fixes the following problems with safe headphone volume warning message:
- Do not display the warning dialog when screen is off.
- Use the same 3 second timeout as for the volume slider to dismiss the dialog.
- Do not dismiss the warning dialog when touching outside of the slider window
but inside the warning window.
- Disable the volume slider when the warning message is displayed.
- When setting volume directly (touching the volume slider), and the warning
is displayed, save the requested volume and apply it if acknowledged by the user.
- Do not display the warning message when restoring safe volume after 20h of
cumulative listenening

Bug 7658641.

Change-Id: Ib3d1315193a433dad918aa5df78fa071062b2394
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index d7c7f46..6251c45 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -218,12 +218,14 @@
 
     private static class WarningDialogReceiver extends BroadcastReceiver
             implements DialogInterface.OnDismissListener {
-        private Context mContext;
-        private Dialog mDialog;
+        private final Context mContext;
+        private final Dialog mDialog;
+        private final VolumePanel mVolumePanel;
 
-        WarningDialogReceiver(Context context, Dialog dialog) {
+        WarningDialogReceiver(Context context, Dialog dialog, VolumePanel volumePanel) {
             mContext = context;
             mDialog = dialog;
+            mVolumePanel = volumePanel;
             IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
             context.registerReceiver(this, filter);
         }
@@ -231,16 +233,20 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             mDialog.cancel();
-            synchronized (sConfirmSafeVolumeLock) {
-                sConfirmSafeVolumeDialog = null;
-            }
+            cleanUp();
         }
 
         public void onDismiss(DialogInterface unused) {
             mContext.unregisterReceiver(this);
+            cleanUp();
+        }
+
+        private void cleanUp() {
             synchronized (sConfirmSafeVolumeLock) {
                 sConfirmSafeVolumeDialog = null;
             }
+            mVolumePanel.forceTimeout();
+            mVolumePanel.updateStates();
         }
     }
 
@@ -276,7 +282,8 @@
 
         mDialog = new Dialog(context, R.style.Theme_Panel_Volume) {
             public boolean onTouchEvent(MotionEvent event) {
-                if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+                if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE &&
+                        sConfirmSafeVolumeDialog == null) {
                     forceTimeout();
                     return true;
                 }
@@ -461,7 +468,8 @@
             // never disable touch interactions for remote playback, the muting is not tied to
             // the state of the phone.
             sc.seekbarView.setEnabled(true);
-        } else if (sc.streamType != mAudioManager.getMasterStreamType() && muted) {
+        } else if ((sc.streamType != mAudioManager.getMasterStreamType() && muted) ||
+                        (sConfirmSafeVolumeDialog != null)) {
             sc.seekbarView.setEnabled(false);
         } else {
             sc.seekbarView.setEnabled(true);
@@ -490,7 +498,7 @@
         }
     }
 
-    private void updateStates() {
+    public void updateStates() {
         final int count = mSliderGroup.getChildCount();
         for (int i = 0; i < count; i++) {
             StreamControl sc = (StreamControl) mSliderGroup.getChildAt(i).getTag();
@@ -562,9 +570,9 @@
         postMuteChanged(STREAM_MASTER, flags);
     }
 
-    public void postDisplaySafeVolumeWarning() {
+    public void postDisplaySafeVolumeWarning(int flags) {
         if (hasMessages(MSG_DISPLAY_SAFE_VOLUME_WARNING)) return;
-        obtainMessage(MSG_DISPLAY_SAFE_VOLUME_WARNING, 0, 0).sendToTarget();
+        obtainMessage(MSG_DISPLAY_SAFE_VOLUME_WARNING, flags, 0).sendToTarget();
     }
 
     /**
@@ -598,7 +606,6 @@
 
         removeMessages(MSG_FREE_RESOURCES);
         sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
-
         resetTimeout();
     }
 
@@ -704,7 +711,8 @@
             if (((flags & AudioManager.FLAG_FIXED_VOLUME) != 0) ||
                     (streamType != mAudioManager.getMasterStreamType() &&
                      streamType != AudioService.STREAM_REMOTE_MUSIC &&
-                     isMuted(streamType))) {
+                     isMuted(streamType)) ||
+                     sConfirmSafeVolumeDialog != null) {
                 sc.seekbarView.setEnabled(false);
             } else {
                 sc.seekbarView.setEnabled(true);
@@ -802,7 +810,6 @@
 
         removeMessages(MSG_FREE_RESOURCES);
         sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
-
         resetTimeout();
     }
 
@@ -838,30 +845,34 @@
         }
     }
 
-    protected void onDisplaySafeVolumeWarning() {
-        synchronized (sConfirmSafeVolumeLock) {
-            if (sConfirmSafeVolumeDialog != 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() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            mAudioService.disableSafeMediaVolume();
-                        }
-                    })
-                    .setNegativeButton(com.android.internal.R.string.no, null)
-                    .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .create();
-            final WarningDialogReceiver warning = new WarningDialogReceiver(mContext,
-                    sConfirmSafeVolumeDialog);
+    protected void onDisplaySafeVolumeWarning(int flags) {
+        if ((flags & AudioManager.FLAG_SHOW_UI) != 0 || mDialog.isShowing()) {
+            synchronized (sConfirmSafeVolumeLock) {
+                if (sConfirmSafeVolumeDialog != 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() {
+                            public void onClick(DialogInterface dialog, int which) {
+                                mAudioService.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();
+                sConfirmSafeVolumeDialog.setOnDismissListener(warning);
+                sConfirmSafeVolumeDialog.getWindow().setType(
+                                                WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+                sConfirmSafeVolumeDialog.show();
+            }
+            updateStates();
         }
+        resetTimeout();
     }
 
     /**
@@ -957,6 +968,11 @@
                     mDialog.dismiss();
                     mActiveStreamType = -1;
                 }
+                synchronized (sConfirmSafeVolumeLock) {
+                    if (sConfirmSafeVolumeDialog != null) {
+                        sConfirmSafeVolumeDialog.dismiss();
+                    }
+                }
                 break;
             }
             case MSG_RINGER_MODE_CHANGED: {
@@ -980,7 +996,7 @@
                 break;
 
             case MSG_DISPLAY_SAFE_VOLUME_WARNING:
-                onDisplaySafeVolumeWarning();
+                onDisplaySafeVolumeWarning(msg.arg1);
                 break;
         }
     }