Merge "Improve javadocs of some DPM APIs" into pi-dev
diff --git a/media/OWNERS b/media/OWNERS
index 287ec39..f198f43 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -3,3 +3,4 @@
 lajos@google.com
 marcone@google.com
 sungsoo@google.com
+wjia@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index da042d2..407be62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -113,7 +113,7 @@
     private static final String EXTRA_DISABLE_STATE = "disabled_state";
 
     private final static int BUTTON_FADE_IN_OUT_DURATION_MS = 100;
-    private final static int ROTATE_BUTTON_LOOP_DURATION_MS = 2000;
+    private final static int NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS = 20000;
 
     private static final int NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION = 3;
 
@@ -152,11 +152,14 @@
     public boolean mHomeBlockedThisTouch;
 
     private int mLastRotationSuggestion;
+    private boolean mPendingRotationSuggestion;
     private boolean mHoveringRotationSuggestion;
     private RotationLockController mRotationLockController;
     private TaskStackListenerImpl mTaskStackListener;
 
     private final Runnable mRemoveRotationProposal = () -> setRotateSuggestionButtonState(false);
+    private final Runnable mCancelPendingRotationProposal =
+            () -> mPendingRotationSuggestion = false;
     private Animator mRotateHideAnimator;
     private ViewRippler mViewRippler = new ViewRippler();
 
@@ -365,6 +368,11 @@
                 && mNavigationBarWindowState != state) {
             mNavigationBarWindowState = state;
             if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
+
+            // If the navbar is visible, show the rotate button if there's a pending suggestion
+            if (state == WINDOW_STATE_SHOWING && mPendingRotationSuggestion) {
+                showAndLogRotationSuggestion();
+            }
         }
     }
 
@@ -373,38 +381,51 @@
         // This method will be called on rotation suggestion changes even if the proposed rotation
         // is not valid for the top app. Use invalid rotation choices as a signal to remove the
         // rotate button if shown.
-
         if (!isValid) {
             setRotateSuggestionButtonState(false);
             return;
         }
 
+        // If window rotation matches suggested rotation, remove any current suggestions
         final int winRotation = mWindowManager.getDefaultDisplay().getRotation();
         if (rotation == winRotation) {
-            // Use this as a signal to remove any current suggestions
-            getView().getHandler().removeCallbacks(mRemoveRotationProposal);
+            getView().removeCallbacks(mRemoveRotationProposal);
             setRotateSuggestionButtonState(false);
-        } else {
-            mLastRotationSuggestion = rotation; // Remember rotation for click
-
-            // Update the icon style to change animation parameters
-            if (mNavigationBarView != null) {
-                final boolean rotationCCW = isRotationAnimationCCW(winRotation, rotation);
-                int style;
-                if (winRotation == Surface.ROTATION_0 || winRotation == Surface.ROTATION_180) {
-                    style = rotationCCW ? R.style.RotateButtonCCWStart90 :
-                            R.style.RotateButtonCWStart90;
-                } else { // 90 or 270
-                    style = rotationCCW ? R.style.RotateButtonCCWStart0 :
-                            R.style.RotateButtonCWStart0;
-                }
-                mNavigationBarView.updateRotateSuggestionButtonStyle(style, true);
-            }
-
-            setRotateSuggestionButtonState(true);
-            rescheduleRotationTimeout(false);
-            mMetricsLogger.visible(MetricsEvent.ROTATION_SUGGESTION_SHOWN);
+            return;
         }
+
+        // Prepare to show the navbar icon by updating the icon style to change anim params
+        mLastRotationSuggestion = rotation; // Remember rotation for click
+        if (mNavigationBarView != null) {
+            final boolean rotationCCW = isRotationAnimationCCW(winRotation, rotation);
+            int style;
+            if (winRotation == Surface.ROTATION_0 || winRotation == Surface.ROTATION_180) {
+                style = rotationCCW ? R.style.RotateButtonCCWStart90 :
+                        R.style.RotateButtonCWStart90;
+            } else { // 90 or 270
+                style = rotationCCW ? R.style.RotateButtonCCWStart0 :
+                        R.style.RotateButtonCWStart0;
+            }
+            mNavigationBarView.updateRotateSuggestionButtonStyle(style, true);
+        }
+
+        if (mNavigationBarWindowState != WINDOW_STATE_SHOWING) {
+            // If the navbar isn't shown, flag the rotate icon to be shown should the navbar become
+            // visible given some time limit.
+            mPendingRotationSuggestion = true;
+            getView().removeCallbacks(mCancelPendingRotationProposal);
+            getView().postDelayed(mCancelPendingRotationProposal,
+                    NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS);
+
+        } else { // The navbar is visible so show the icon right away
+            showAndLogRotationSuggestion();
+        }
+    }
+
+    private void showAndLogRotationSuggestion() {
+        setRotateSuggestionButtonState(true);
+        rescheduleRotationTimeout(false);
+        mMetricsLogger.visible(MetricsEvent.ROTATION_SUGGESTION_SHOWN);
     }
 
     private boolean isRotationAnimationCCW(int from, int to) {
@@ -453,6 +474,11 @@
             animIcon = (AnimatedVectorDrawable) kbd.getDrawable(0);
         }
 
+        // Clear any pending suggestion flag as it has either been nullified or is being shown
+        mPendingRotationSuggestion = false;
+        getView().removeCallbacks(mCancelPendingRotationProposal);
+
+        // Handle the visibility change and animation
         if (visible) { // Appear and change (cannot force)
             // Stop and clear any currently running hide animations
             if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
@@ -516,9 +542,8 @@
             if (!mNavigationBarView.isRotateButtonVisible()) return;
         }
 
-        Handler h = getView().getHandler();
-        h.removeCallbacks(mRemoveRotationProposal); // Stop any pending removal
-        h.postDelayed(mRemoveRotationProposal,
+        getView().removeCallbacks(mRemoveRotationProposal); // Stop any pending removal
+        getView().postDelayed(mRemoveRotationProposal,
                 computeRotationProposalTimeout()); // Schedule timeout
     }
 
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index a1f184d..796ac4f 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5419,6 +5419,32 @@
     // OS: P
     ZEN_WHAT_TO_BLOCK = 1339;
 
+    // ACTION: DND Settings > Priority only allows > System toggle
+    // SUBTYPE: 0 is off, 1 is on
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ALLOW_SYSTEM = 1340;
+
+    // OPEN: Settings > Sounds > Do Not Disturb > Duration
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_DURATION_DIALOG = 1341;
+
+    // OPEN: Settings > Sound & notification > Do Not Disturb > Duration -> Time Option (ie: for one hour)
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_DURATION_TIME = 1342;
+
+    // OPEN: Settings > Sound & notification > Do Not Disturb > Duration -> Until you turn off
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_DURATION_FOREVER = 1343;
+
+    // OPEN: Settings > Sound & notification > Do Not Disturb > Duration -> Ask every time
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_DURATION_PROMPT = 1344;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS