Loading core/java/android/provider/Settings.java +8 −0 Original line number Diff line number Diff line Loading @@ -7102,6 +7102,14 @@ public final class Settings { public static final int SHOW_ROTATION_SUGGESTIONS_DEFAULT = SHOW_ROTATION_SUGGESTIONS_ENABLED; /** * The number of accepted rotation suggestions. Used to determine if the user has been * introduced to rotation suggestions. * @hide */ public static final String NUM_ROTATION_SUGGESTIONS_ACCEPTED = "num_rotation_suggestions_accepted"; /** * Read only list of the service components that the current user has explicitly allowed to * see and assist with all of the user's notifications. Loading core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -524,6 +524,7 @@ public class SettingsBackupTest { Settings.Secure.NFC_PAYMENT_FOREGROUND, Settings.Secure.NIGHT_DISPLAY_ACTIVATED, Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, Settings.Secure.PACKAGE_VERIFIER_STATE, Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT, Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE, Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +56 −0 Original line number Diff line number Diff line Loading @@ -115,6 +115,8 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private final static int BUTTON_FADE_IN_OUT_DURATION_MS = 100; private final static int ROTATE_BUTTON_LOOP_DURATION_MS = 2000; private static final int NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION = 3; /** Allow some time inbetween the long press for back and recents. */ private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; Loading Loading @@ -156,6 +158,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private final Runnable mRemoveRotationProposal = () -> setRotateSuggestionButtonState(false); private Animator mRotateHideAnimator; private ViewRippler mViewRippler = new ViewRippler(); private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { @Override Loading Loading @@ -464,12 +467,16 @@ public class NavigationBarFragment extends Fragment implements Callbacks { animIcon.start(); } if (!isRotateSuggestionIntroduced()) mViewRippler.start(view); // Set visibility, may fail if a11y service is active. // If invisible, call will stop animation. mNavigationBarView.setRotateButtonVisibility(true); } else { // Hide mViewRippler.stop(); // Prevent any pending ripples, force hide or not if (force) { // If a hide animator is running stop it and make invisible if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) { Loading Loading @@ -519,6 +526,25 @@ public class NavigationBarFragment extends Fragment implements Callbacks { return 6000; } private boolean isRotateSuggestionIntroduced() { ContentResolver cr = getContext().getContentResolver(); return Settings.Secure.getInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0) >= NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION; } private void incrementNumAcceptedRotationSuggestionsIfNeeded() { // Get the number of accepted suggestions ContentResolver cr = getContext().getContentResolver(); final int numSuggestions = Settings.Secure.getInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0); // Increment the number of accepted suggestions only if it would change intro mode if (numSuggestions < NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION) { Settings.Secure.putInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, numSuggestions + 1); } } // Injected from StatusBar at creation. public void setCurrentSysuiVisibility(int systemUiVisibility) { mSystemUiVisibility = systemUiVisibility; Loading Loading @@ -861,6 +887,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private void onRotateSuggestionClick(View v) { mMetricsLogger.action(MetricsEvent.ACTION_ROTATION_SUGGESTION_ACCEPTED); incrementNumAcceptedRotationSuggestionsIfNeeded(); mRotationLockController.setRotationLockedAtAngle(true, mLastRotationSuggestion); } Loading Loading @@ -989,6 +1016,35 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } } private class ViewRippler { private static final int RIPPLE_OFFSET_MS = 50; private static final int RIPPLE_INTERVAL_MS = 2000; private View mRoot; public void start(View root) { stop(); // Stop any pending ripple animations mRoot = root; // Schedule pending ripples, offset the 1st to avoid problems with visibility change mRoot.postOnAnimationDelayed(mRipple, RIPPLE_OFFSET_MS); mRoot.postOnAnimationDelayed(mRipple, RIPPLE_INTERVAL_MS); mRoot.postOnAnimationDelayed(mRipple, 2*RIPPLE_INTERVAL_MS); } public void stop() { if (mRoot != null) mRoot.removeCallbacks(mRipple); } private final Runnable mRipple = new Runnable() { @Override public void run() { // Cause the ripple to fire via false presses mRoot.setPressed(true); mRoot.setPressed(false); } }; } public static View create(Context context, FragmentListener listener) { WindowManager.LayoutParams lp = new WindowManager.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Loading Loading
core/java/android/provider/Settings.java +8 −0 Original line number Diff line number Diff line Loading @@ -7102,6 +7102,14 @@ public final class Settings { public static final int SHOW_ROTATION_SUGGESTIONS_DEFAULT = SHOW_ROTATION_SUGGESTIONS_ENABLED; /** * The number of accepted rotation suggestions. Used to determine if the user has been * introduced to rotation suggestions. * @hide */ public static final String NUM_ROTATION_SUGGESTIONS_ACCEPTED = "num_rotation_suggestions_accepted"; /** * Read only list of the service components that the current user has explicitly allowed to * see and assist with all of the user's notifications. Loading
core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -524,6 +524,7 @@ public class SettingsBackupTest { Settings.Secure.NFC_PAYMENT_FOREGROUND, Settings.Secure.NIGHT_DISPLAY_ACTIVATED, Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, Settings.Secure.PACKAGE_VERIFIER_STATE, Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT, Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE, Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +56 −0 Original line number Diff line number Diff line Loading @@ -115,6 +115,8 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private final static int BUTTON_FADE_IN_OUT_DURATION_MS = 100; private final static int ROTATE_BUTTON_LOOP_DURATION_MS = 2000; private static final int NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION = 3; /** Allow some time inbetween the long press for back and recents. */ private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; Loading Loading @@ -156,6 +158,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private final Runnable mRemoveRotationProposal = () -> setRotateSuggestionButtonState(false); private Animator mRotateHideAnimator; private ViewRippler mViewRippler = new ViewRippler(); private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { @Override Loading Loading @@ -464,12 +467,16 @@ public class NavigationBarFragment extends Fragment implements Callbacks { animIcon.start(); } if (!isRotateSuggestionIntroduced()) mViewRippler.start(view); // Set visibility, may fail if a11y service is active. // If invisible, call will stop animation. mNavigationBarView.setRotateButtonVisibility(true); } else { // Hide mViewRippler.stop(); // Prevent any pending ripples, force hide or not if (force) { // If a hide animator is running stop it and make invisible if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) { Loading Loading @@ -519,6 +526,25 @@ public class NavigationBarFragment extends Fragment implements Callbacks { return 6000; } private boolean isRotateSuggestionIntroduced() { ContentResolver cr = getContext().getContentResolver(); return Settings.Secure.getInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0) >= NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION; } private void incrementNumAcceptedRotationSuggestionsIfNeeded() { // Get the number of accepted suggestions ContentResolver cr = getContext().getContentResolver(); final int numSuggestions = Settings.Secure.getInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0); // Increment the number of accepted suggestions only if it would change intro mode if (numSuggestions < NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION) { Settings.Secure.putInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, numSuggestions + 1); } } // Injected from StatusBar at creation. public void setCurrentSysuiVisibility(int systemUiVisibility) { mSystemUiVisibility = systemUiVisibility; Loading Loading @@ -861,6 +887,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private void onRotateSuggestionClick(View v) { mMetricsLogger.action(MetricsEvent.ACTION_ROTATION_SUGGESTION_ACCEPTED); incrementNumAcceptedRotationSuggestionsIfNeeded(); mRotationLockController.setRotationLockedAtAngle(true, mLastRotationSuggestion); } Loading Loading @@ -989,6 +1016,35 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } } private class ViewRippler { private static final int RIPPLE_OFFSET_MS = 50; private static final int RIPPLE_INTERVAL_MS = 2000; private View mRoot; public void start(View root) { stop(); // Stop any pending ripple animations mRoot = root; // Schedule pending ripples, offset the 1st to avoid problems with visibility change mRoot.postOnAnimationDelayed(mRipple, RIPPLE_OFFSET_MS); mRoot.postOnAnimationDelayed(mRipple, RIPPLE_INTERVAL_MS); mRoot.postOnAnimationDelayed(mRipple, 2*RIPPLE_INTERVAL_MS); } public void stop() { if (mRoot != null) mRoot.removeCallbacks(mRipple); } private final Runnable mRipple = new Runnable() { @Override public void run() { // Cause the ripple to fire via false presses mRoot.setPressed(true); mRoot.setPressed(false); } }; } public static View create(Context context, FragmentListener listener) { WindowManager.LayoutParams lp = new WindowManager.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Loading