Merge "Using the activity size for swipe-dow animation in fallback+multiWindow mode" into ub-launcher3-edmonton
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
index 79d8a61..8632f8b 100644
--- a/quickstep/res/layout/overview_clear_all_button.xml
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/clear_all_button"
android:layout_width="wrap_content"
@@ -11,6 +10,5 @@
android:text="@string/recents_clear_all"
android:textColor="?attr/workspaceTextColor"
android:background="?android:attr/selectableItemBackground"
- launcher:layout_ignoreInsets="true"
android:textSize="14sp"
/>
\ No newline at end of file
diff --git a/quickstep/res/xml/indexable_launcher_prefs.xml b/quickstep/res/xml/indexable_launcher_prefs.xml
index 2655402..30f3100 100644
--- a/quickstep/res/xml/indexable_launcher_prefs.xml
+++ b/quickstep/res/xml/indexable_launcher_prefs.xml
@@ -20,8 +20,14 @@
android:key="pref_add_icon_to_home"
android:title="@string/auto_add_shortcuts_label"
android:summary="@string/auto_add_shortcuts_description"
- android:defaultValue="true"
- />
+ android:defaultValue="true" />
+
+ <SwitchPreference
+ android:key="pref_allowRotation"
+ android:title="@string/allow_rotation_title"
+ android:summary="@string/allow_rotation_desc"
+ android:defaultValue="@bool/allow_rotation"
+ android:persistent="true" />
<ListPreference
android:key="pref_override_icon_shape"
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index ce17d25..353ed84 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -50,7 +50,6 @@
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
-import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
import android.view.Surface;
@@ -249,7 +248,7 @@
mLauncher.getStateManager()
.createAnimationToNewWorkspace(NORMAL, RECENTS_LAUNCH_DURATION);
controller.dispatchOnStart();
- childStateAnimation = controller.getOriginalTarget();
+ childStateAnimation = controller.getTarget();
launcherAnim = controller.getAnimationPlayer().setDuration(RECENTS_LAUNCH_DURATION);
windowAnimEndListener = new AnimatorListenerAdapter() {
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 70b0355..7676a70 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -87,7 +87,8 @@
private int mTaskChangeId;
private ISystemUiProxy mSystemUiProxy;
private boolean mClearAssistCacheOnStackChange = true;
- private final boolean mPreloadTasksInBackground;
+ private final boolean mIsLowRamDevice;
+ private boolean mPreloadTasksInBackground;
private final AccessibilityManager mAccessibilityManager;
private RecentsModel(Context context) {
@@ -95,7 +96,7 @@
ActivityManager activityManager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- mPreloadTasksInBackground = !activityManager.isLowRamDevice();
+ mIsLowRamDevice = activityManager.isLowRamDevice();
mMainThreadExecutor = new MainThreadExecutor();
Resources res = context.getResources();
@@ -160,6 +161,10 @@
return requestId;
}
+ public void setPreloadTasksInBackground(boolean preloadTasksInBackground) {
+ mPreloadTasksInBackground = preloadTasksInBackground && !mIsLowRamDevice;
+ }
+
@Override
public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
mTaskChangeId++;
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index 2ebf252..e3f6543 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -101,13 +101,9 @@
}
}
- public static class SplitScreen extends TaskSystemShortcut implements OnPreDrawListener,
- DeviceProfile.OnDeviceProfileChangeListener, View.OnLayoutChangeListener {
+ public static class SplitScreen extends TaskSystemShortcut {
private Handler mHandler;
- private RecentsView mRecentsView;
- private TaskView mTaskView;
- private BaseDraggingActivity mActivity;
public SplitScreen() {
super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
@@ -125,11 +121,44 @@
if (!task.isDockable) {
return null;
}
- mActivity = activity;
- mRecentsView = activity.getOverviewPanel();
- mTaskView = taskView;
+ final RecentsView recentsView = activity.getOverviewPanel();
+
final TaskThumbnailView thumbnailView = taskView.getThumbnail();
return (v -> {
+ final View.OnLayoutChangeListener onLayoutChangeListener =
+ new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int l, int t, int r, int b,
+ int oldL, int oldT, int oldR, int oldB) {
+ taskView.getRootView().removeOnLayoutChangeListener(this);
+ recentsView.removeIgnoreResetTask(taskView);
+
+ // Start animating in the side pages once launcher has been resized
+ recentsView.dismissTask(taskView, false, false);
+ }
+ };
+
+ final DeviceProfile.OnDeviceProfileChangeListener onDeviceProfileChangeListener =
+ new DeviceProfile.OnDeviceProfileChangeListener() {
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ activity.removeOnDeviceProfileChangeListener(this);
+ if (dp.isMultiWindowMode) {
+ taskView.getRootView().addOnLayoutChangeListener(
+ onLayoutChangeListener);
+ }
+ }
+ };
+
+ final OnPreDrawListener preDrawListener = new OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ taskView.getViewTreeObserver().removeOnPreDrawListener(this);
+ WindowManagerWrapper.getInstance().endProlongedAnimations();
+ return true;
+ }
+ };
+
AbstractFloatingView.closeOpenViews(activity, true,
AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
@@ -145,15 +174,15 @@
// Add a device profile change listener to kick off animating the side tasks
// once we enter multiwindow mode and relayout
- activity.addOnDeviceProfileChangeListener(this);
+ activity.addOnDeviceProfileChangeListener(onDeviceProfileChangeListener);
final Runnable animStartedListener = () -> {
// Hide the task view and wait for the window to be resized
// TODO: Consider animating in launcher and do an in-place start activity
// afterwards
- mRecentsView.addIgnoreResetTask(mTaskView);
- mTaskView.setAlpha(0f);
- mTaskView.getViewTreeObserver().addOnPreDrawListener(SplitScreen.this);
+ recentsView.addIgnoreResetTask(taskView);
+ taskView.setAlpha(0f);
+ taskView.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
};
final int[] position = new int[2];
@@ -179,31 +208,6 @@
}
});
}
-
- @Override
- public boolean onPreDraw() {
- mTaskView.getViewTreeObserver().removeOnPreDrawListener(this);
- WindowManagerWrapper.getInstance().endProlongedAnimations();
- return true;
- }
-
- @Override
- public void onDeviceProfileChanged(DeviceProfile dp) {
- mActivity.removeOnDeviceProfileChangeListener(this);
- if (dp.isMultiWindowMode) {
- mTaskView.getRootView().addOnLayoutChangeListener(this);
- }
- }
-
- @Override
- public void onLayoutChange(View v, int l, int t, int r, int b,
- int oldL, int oldT, int oldR, int oldB) {
- mTaskView.getRootView().removeOnLayoutChangeListener(this);
- mRecentsView.removeIgnoreResetTask(mTaskView);
-
- // Start animating in the side pages once launcher has been resized
- mRecentsView.dismissTask(mTaskView, false, false);
- }
}
public static class Pin extends TaskSystemShortcut {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 57f46b8..b89a835 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -173,6 +173,7 @@
super.onCreate();
mAM = ActivityManagerWrapper.getInstance();
mRecentsModel = RecentsModel.getInstance(this);
+ mRecentsModel.setPreloadTasksInBackground(true);
mMainThreadExecutor = new MainThreadExecutor();
mOverviewCommandHelper = new OverviewCommandHelper(this);
mMainThreadChoreographer = Choreographer.getInstance();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a41b36e..a7b018a 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -170,7 +170,7 @@
// Keeps track of task views whose visual state should not be reset
private ArraySet<TaskView> mIgnoreResetTaskViews = new ArraySet<>();
- private RecentsViewContainer mContainerView;
+ private View mClearAllButton;
// Variables for empty state
private final Drawable mEmptyIcon;
@@ -312,12 +312,15 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (DEBUG_SHOW_CLEAR_ALL_BUTTON && mTouchState == TOUCH_STATE_REST && mScroller.isFinished()
- && getChildCount() != 0
- && ev.getX() > getChildAt(getChildCount() - 1).getRight() - getScrollX()) {
- // If nothing is in motion, allow events to the right of the last task to go to the
- // Clear All button.
- return false;
+ if (DEBUG_SHOW_CLEAR_ALL_BUTTON && ev.getAction() == MotionEvent.ACTION_DOWN
+ && mTouchState == TOUCH_STATE_REST && mScroller.isFinished()
+ && mClearAllButton.getVisibility() == View.VISIBLE) {
+ mClearAllButton.getHitRect(mTempRect);
+ mTempRect.offset(-getLeft(), -getTop());
+ if (mTempRect.contains((int) ev.getX(), (int) ev.getY())) {
+ // If nothing is in motion, let the Clear All button process the event.
+ return false;
+ }
}
if (ev.getAction() == MotionEvent.ACTION_UP && mShowEmptyMessage) {
@@ -928,8 +931,8 @@
mShowEmptyMessage = isEmpty;
updateEmptyStateUi(hasSizeChanged);
invalidate();
- if (mContainerView != null) {
- mContainerView.onEmptyStateChanged(!DEBUG_SHOW_CLEAR_ALL_BUTTON || mShowEmptyMessage);
+ if (mClearAllButton != null) {
+ updateClearAllButtonVisibility();
}
}
@@ -943,6 +946,7 @@
boolean hasValidSize = getWidth() > 0 && getHeight() > 0;
if (sizeChanged && hasValidSize) {
mEmptyTextLayout = null;
+ mLastMeasureSize.set(getWidth(), getHeight());
}
if (!mShowEmptyMessage) return;
@@ -953,7 +957,6 @@
scrollTo(0, 0);
if (hasValidSize && mEmptyTextLayout == null) {
- mLastMeasureSize.set(getWidth(), getHeight());
int availableWidth = mLastMeasureSize.x - mEmptyMessagePadding - mEmptyMessagePadding;
mEmptyTextLayout = StaticLayout.Builder.obtain(mEmptyMessage, 0, mEmptyMessage.length(),
mEmptyMessagePaint, availableWidth)
@@ -1136,8 +1139,13 @@
R.dimen.clear_all_container_width) - getPaddingEnd();
}
- public void setContainerView(RecentsViewContainer containerView) {
- mContainerView = containerView;
- mContainerView.onEmptyStateChanged(!DEBUG_SHOW_CLEAR_ALL_BUTTON || mShowEmptyMessage);
+ private void updateClearAllButtonVisibility() {
+ mClearAllButton.setVisibility(
+ !DEBUG_SHOW_CLEAR_ALL_BUTTON || mShowEmptyMessage ? GONE : VISIBLE);
+ }
+
+ public void setClearAllButton(View clearAllButton) {
+ mClearAllButton = clearAllButton;
+ updateClearAllButtonVisibility();
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index ece78c1..988b3ad 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -43,7 +43,7 @@
});
mRecentsView = (RecentsView) findViewById(R.id.overview_panel);
- mRecentsView.setContainerView(this);
+ mRecentsView.setClearAllButton(mClearAllButton);
}
@Override
@@ -56,7 +56,8 @@
(mClearAllButton.getMeasuredWidth() - getResources().getDimension(
R.dimen.clear_all_container_width)) / 2);
mClearAllButton.setTranslationY(
- mTempRect.top + (mTempRect.height() - mClearAllButton.getMeasuredHeight()) / 2);
+ mTempRect.top + (mTempRect.height() - mClearAllButton.getMeasuredHeight()) / 2
+ - mClearAllButton.getTop());
}
@Override
@@ -74,8 +75,4 @@
mRecentsView.setContentAlpha(alpha);
setVisibility(alpha > 0 ? VISIBLE : GONE);
}
-
- public void onEmptyStateChanged(boolean isEmpty) {
- mClearAllButton.setVisibility(isEmpty ? GONE : VISIBLE);
- }
}
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bcb90e3..4fbd806 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -179,6 +179,10 @@
<string name="msg_disabled_by_admin">Disabled by your admin</string>
<!-- Strings for settings -->
+ <!-- Title for Allow Rotation setting. [CHAR LIMIT=50] -->
+ <string name="allow_rotation_title">Allow Home screen rotation</string>
+ <!-- Text explaining when the home screen will get rotated. [CHAR LIMIT=100] -->
+ <string name="allow_rotation_desc">When phone is rotated</string>
<!-- Title for Notification dots setting. Tapping this will link to the system Notifications settings screen where the user can turn off notification dots globally. [CHAR LIMIT=50] -->
<string name="icon_badging_title">Notification dots</string>
<!-- Text to indicate that the system icon badging setting is on [CHAR LIMIT=100] -->
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 7bb19f3..3bba73a 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -34,8 +34,14 @@
android:title="@string/auto_add_shortcuts_label"
android:summary="@string/auto_add_shortcuts_description"
android:defaultValue="true"
- android:persistent="true"
- />
+ android:persistent="true" />
+
+ <SwitchPreference
+ android:key="pref_allowRotation"
+ android:title="@string/allow_rotation_title"
+ android:summary="@string/allow_rotation_desc"
+ android:defaultValue="@bool/allow_rotation"
+ android:persistent="true" />
<ListPreference
android:key="pref_override_icon_shape"
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index a41edc0..d133472 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -143,6 +143,15 @@
}
@Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+
+ // Needed for activities that auto-enter PiP, which will not trigger a remote animation to
+ // be created
+ clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+ }
+
+ @Override
protected void onStop() {
mActivityFlags &= ~ACTIVITY_STATE_STARTED & ~ACTIVITY_STATE_USER_ACTIVE;
mForceInvisible = 0;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ec0a8ff..5e06d92 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -360,7 +360,7 @@
dispatchDeviceProfileChanged();
getRootView().dispatchInsets();
- getStateManager().reapplyState();
+ getStateManager().reapplyState(true /* cancelCurrentAnimation */);
// Recreate touch controllers
mDragLayer.setup(mDragController);
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index f204c16..ad1456a2 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -1,5 +1,8 @@
package com.android.launcher3;
+import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
+import static com.android.launcher3.util.SystemUiController.UI_STATE_ROOT_VIEW;
+
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
@@ -13,9 +16,6 @@
import com.android.launcher3.util.Themes;
-import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
-import static com.android.launcher3.util.SystemUiController.UI_STATE_ROOT_VIEW;
-
public class LauncherRootView extends InsettableFrameLayout {
private final Launcher mLauncher;
@@ -82,7 +82,7 @@
}
}
if (resetState) {
- mLauncher.getStateManager().reapplyState();
+ mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
}
return true; // I'll take it from here
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index e611af7..d196c37 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -157,6 +157,13 @@
}
public void reapplyState() {
+ reapplyState(false);
+ }
+
+ public void reapplyState(boolean cancelCurrentAnimation) {
+ if (cancelCurrentAnimation) {
+ cancelAnimation();
+ }
if (mConfig.mCurrentAnimation == null) {
for (StateHandler handler : getStateHandlers()) {
handler.setState(mState);
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index c9bd32b..32c198a 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -16,6 +16,9 @@
package com.android.launcher3;
+import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
+import static com.android.launcher3.states.RotationHelper.getAllowRotationDefaultValue;
+
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
@@ -59,6 +62,7 @@
private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
private static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
+ private static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args";
private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
@@ -123,6 +127,16 @@
getPreferenceScreen().removePreference(iconShapeOverride);
}
}
+
+ // Setup allow rotation preference
+ Preference rotationPref = findPreference(ALLOW_ROTATION_PREFERENCE_KEY);
+ if (getResources().getBoolean(R.bool.allow_rotation)) {
+ // Launcher supports rotation by default. No need to show this setting.
+ getPreferenceScreen().removePreference(rotationPref);
+ } else {
+ // Initialize the UI once
+ rotationPref.setDefaultValue(getAllowRotationDefaultValue());
+ }
}
@Override
@@ -273,9 +287,13 @@
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ComponentName cn = new ComponentName(getActivity(), NotificationListener.class);
+ Bundle showFragmentArgs = new Bundle();
+ showFragmentArgs.putString(EXTRA_FRAGMENT_ARG_KEY, cn.flattenToString());
+
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .putExtra(":settings:fragment_args_key", cn.flattenToString());
+ .putExtra(EXTRA_FRAGMENT_ARG_KEY, cn.flattenToString())
+ .putExtra(EXTRA_SHOW_FRAGMENT_ARGS, showFragmentArgs);
getActivity().startActivity(intent);
}
}
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 087752d..1dba7d6 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -17,6 +17,7 @@
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
@@ -52,45 +53,37 @@
private final long mDuration;
protected final AnimatorSet mAnim;
- private AnimatorSet mOriginalTarget;
protected float mCurrentFraction;
private Runnable mEndAction;
+ protected boolean mTargetCancelled = false;
+
protected AnimatorPlaybackController(AnimatorSet anim, long duration) {
mAnim = anim;
- mOriginalTarget = mAnim;
mDuration = duration;
mAnimationPlayer = ValueAnimator.ofFloat(0, 1);
mAnimationPlayer.setInterpolator(Interpolators.LINEAR);
mAnimationPlayer.addListener(new OnAnimationEndDispatcher());
mAnimationPlayer.addUpdateListener(this);
+
+ mAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mTargetCancelled = true;
+ }
+ });
}
public AnimatorSet getTarget() {
return mAnim;
}
- public void setOriginalTarget(AnimatorSet anim) {
- mOriginalTarget = anim;
- }
-
- public AnimatorSet getOriginalTarget() {
- return mOriginalTarget;
- }
-
public long getDuration() {
return mDuration;
}
- public AnimatorPlaybackController cloneFor(AnimatorSet anim) {
- AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(anim, mDuration);
- controller.setOriginalTarget(mOriginalTarget);
- controller.setPlayFraction(mCurrentFraction);
- return controller;
- }
-
/**
* Starts playing the animation forward from current position.
*/
@@ -206,6 +199,11 @@
@Override
public void setPlayFraction(float fraction) {
mCurrentFraction = fraction;
+ // Let the animator report the progress but don't apply the progress to child
+ // animations if it has been cancelled.
+ if (mTargetCancelled) {
+ return;
+ }
long playPos = clampDuration(fraction);
for (ValueAnimator anim : mChildAnimations) {
anim.setCurrentPlayTime(Math.min(playPos, anim.getDuration()));
diff --git a/src/com/android/launcher3/graphics/IconNormalizer.java b/src/com/android/launcher3/graphics/IconNormalizer.java
index 680c020..81f3f90 100644
--- a/src/com/android/launcher3/graphics/IconNormalizer.java
+++ b/src/com/android/launcher3/graphics/IconNormalizer.java
@@ -80,6 +80,7 @@
private final float[] mLeftBorder;
private final float[] mRightBorder;
private final Rect mBounds;
+ private final Path mShapePath;
private final Matrix mMatrix;
private final Paint mPaintIcon;
@@ -116,6 +117,7 @@
mPaintMaskShapeOutline.setColor(Color.BLACK);
mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+ mShapePath = new Path();
mMatrix = new Matrix();
mAdaptiveIconScale = SCALE_NOT_INITIALIZED;
}
@@ -146,13 +148,13 @@
mMatrix.reset();
mMatrix.setScale(mBounds.width(), mBounds.height());
mMatrix.postTranslate(mBounds.left, mBounds.top);
- maskPath.transform(mMatrix);
+ maskPath.transform(mMatrix, mShapePath);
// XOR operation
- mCanvasARGB.drawPath(maskPath, mPaintMaskShape);
+ mCanvasARGB.drawPath(mShapePath, mPaintMaskShape);
// DST_OUT operation around the mask path outline
- mCanvasARGB.drawPath(maskPath, mPaintMaskShapeOutline);
+ mCanvasARGB.drawPath(mShapePath, mPaintMaskShapeOutline);
// Check if the result is almost transparent
return isTransparentBitmap(mBitmapARGB);
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 8f83648..0036bb9 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -18,28 +18,43 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.provider.Settings.System.ACCELEROMETER_ROTATION;
-import static android.provider.Settings.System.getUriFor;
+import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
+
+import static com.android.launcher3.Utilities.ATLEAST_NOUGAT;
import android.app.Activity;
-import android.content.ContentResolver;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.provider.Settings;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
/**
* Utility class to manage launcher rotation
*/
-public class RotationHelper extends ContentObserver {
+public class RotationHelper implements OnSharedPreferenceChangeListener {
+
+ public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
+
+ public static boolean getAllowRotationDefaultValue() {
+ if (ATLEAST_NOUGAT) {
+ // If the device was scaled, used the original dimensions to determine if rotation
+ // is allowed of not.
+ Resources res = Resources.getSystem();
+ int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
+ * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
+ return originalSmallestWidth >= 600;
+ }
+ return false;
+ }
public static final int REQUEST_NONE = 0;
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
private final Activity mActivity;
- private final ContentResolver mCr;
+ private final SharedPreferences mPrefs;
private final boolean mIgnoreAutoRotateSettings;
private boolean mAutoRotateEnabled;
@@ -60,23 +75,24 @@
private int mLastActivityFlags = -1;
public RotationHelper(Activity activity) {
- super(new Handler());
mActivity = activity;
// On large devices we do not handle auto-rotate differently.
mIgnoreAutoRotateSettings = mActivity.getResources().getBoolean(R.bool.allow_rotation);
if (!mIgnoreAutoRotateSettings) {
- mCr = mActivity.getContentResolver();
- mCr.registerContentObserver(getUriFor(ACCELEROMETER_ROTATION), false, this);
- mAutoRotateEnabled = Settings.System.getInt(mCr, ACCELEROMETER_ROTATION, 1) == 1;
+ mPrefs = Utilities.getPrefs(mActivity);
+ mPrefs.registerOnSharedPreferenceChangeListener(this);
+ mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ getAllowRotationDefaultValue());
} else {
- mCr = null;
+ mPrefs = null;
}
}
@Override
- public void onChange(boolean selfChange) {
- mAutoRotateEnabled = Settings.System.getInt(mCr, ACCELEROMETER_ROTATION, 1) == 1;
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
+ mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ getAllowRotationDefaultValue());
notifyChange();
}
@@ -104,8 +120,8 @@
public void destroy() {
if (!mDestroyed) {
mDestroyed = true;
- if (mCr != null) {
- mCr.unregisterContentObserver(this);
+ if (mPrefs != null) {
+ mPrefs.unregisterOnSharedPreferenceChangeListener(this);
}
}
}
@@ -121,19 +137,17 @@
SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED;
} else if (mCurrentStateRequest == REQUEST_LOCK) {
activityFlags = SCREEN_ORIENTATION_LOCKED;
- } else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE) {
+ } else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
+ || mAutoRotateEnabled) {
activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
- } else if (mAutoRotateEnabled) {
- // If auto rotation is on, lock to device orientation
- activityFlags = SCREEN_ORIENTATION_NOSENSOR;
} else {
// If auto rotation is off, allow rotation on the activity, in case the user is using
// forced rotation.
- activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
+ activityFlags = SCREEN_ORIENTATION_NOSENSOR;
}
if (activityFlags != mLastActivityFlags) {
mLastActivityFlags = activityFlags;
- mActivity.setRequestedOrientation(mLastActivityFlags);
+ mActivity.setRequestedOrientation(activityFlags);
}
}
}
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index f1195ed..4c7ce1f 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -279,7 +279,7 @@
@Override
public void onAnimationCancel(Animator animation) {
- if (mCurrentAnimation != null && animation == mCurrentAnimation.getOriginalTarget()) {
+ if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) {
Log.e(TAG, "Who dare cancel the animation when I am in control", new Exception());
clearState();
}