Merge "Properly color taskbar nav buttons when slide-in view is shown." into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/FloatingTaskIntentResolver.java b/quickstep/src/com/android/launcher3/taskbar/FloatingTaskIntentResolver.java
index c62493c..5f4d239 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FloatingTaskIntentResolver.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FloatingTaskIntentResolver.java
@@ -68,7 +68,7 @@
             return null;
         }
         ComponentName component = new ComponentName(packageName, activityName);
-        Intent intent = new Intent(action).setComponent(component);
+        Intent intent = new Intent(action).setComponent(component).setPackage(packageName);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         Log.d(TAG, "createIntent returning: " + intent);
         return intent;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 1316ddd..192ac62 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -895,7 +895,7 @@
         // load in, and then proceed to OverviewSplitSelect.
         if (isInState(OVERVIEW_SPLIT_SELECT)) {
             SplitSelectStateController splitSelectStateController =
-                    ((RecentsView) getOverviewPanel()).getSplitPlaceholder();
+                    ((RecentsView) getOverviewPanel()).getSplitSelectController();
             // Launcher will restart in Overview and then transition to OverviewSplitSelect.
             outState.putIBinder(PENDING_SPLIT_SELECT_INFO, ObjectWrapper.wrap(
                     new PendingSplitSelectInfo(
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 24bb393..f3630c1 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1140,13 +1140,6 @@
             boolean isCancel) {
         long duration = MAX_SWIPE_DURATION;
         float currentShift = mCurrentShift.value;
-        boolean recentsVisible = mRecentsView != null
-                && (mRecentsView.getWindowVisibility() == View.VISIBLE);
-        if (!recentsVisible) {
-            // We've hit a case where Launcher is been stopped mid-gesture, in this case, force
-            // a LAST_TASK end target
-            isCancel = true;
-        }
         final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
                 isFling, isCancel);
         // Set the state, but don't notify until the animation completes
@@ -1226,7 +1219,7 @@
 
         // Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
         // or resumeLastTask().
-        if (recentsVisible) {
+        if (mRecentsView != null) {
             ActiveGestureLog.INSTANCE.trackEvent(ActiveGestureErrorDetector.GestureEvent
                     .SET_ON_PAGE_TRANSITION_END_CALLBACK);
             mRecentsView.setOnPageTransitionEndCallback(
@@ -2070,7 +2063,6 @@
             if (handleTaskAppeared(appearedTaskTargets)) {
                 mRecentsAnimationController.finish(false /* toRecents */,
                         null /* onFinishComplete */);
-                mActivityInterface.onLaunchTaskSuccess();
                 ActiveGestureLog.INSTANCE.addLog(
                         /* event= */ "finishRecentsAnimation",
                         /* extras= */ false,
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 315a91e..226b173 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -183,14 +183,6 @@
 
     public abstract void onLaunchTaskFailed();
 
-    public void onLaunchTaskSuccess() {
-        ACTIVITY_TYPE activity = getCreatedActivity();
-        if (activity == null) {
-            return;
-        }
-        activity.getStateManager().moveToRestState();
-    }
-
     /**
      * Closes any overlays.
      */
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 57a26ee..875b72c 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -240,8 +240,11 @@
                 interactionHandler.onGestureCancelled();
                 cmd.removeListener(this);
 
-                RecentsView createdRecents =
-                        activityInterface.getCreatedActivity().getOverviewPanel();
+                T createdActivity = activityInterface.getCreatedActivity();
+                if (createdActivity == null) {
+                    return;
+                }
+                RecentsView createdRecents = createdActivity.getOverviewPanel();
                 if (createdRecents != null) {
                     createdRecents.onRecentsAnimationComplete();
                 }
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index bf88702..1a02f03 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -124,7 +124,7 @@
 
         RecentsView recentsView = launcher.getOverviewPanel();
         mOrientationHandler = recentsView.getPagedOrientationHandler();
-        mStagePosition = recentsView.getSplitPlaceholder().getActiveSplitStagePosition();
+        mStagePosition = recentsView.getSplitSelectController().getActiveSplitStagePosition();
         mSplitPlaceholderView.setIcon(icon,
                 mContext.getResources().getDimensionPixelSize(R.dimen.split_placeholder_icon_size));
         mSplitPlaceholderView.getIconView().setRotation(mOrientationHandler.getDegreesRotated());
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 5bc7f18..3a5f606 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -191,7 +191,7 @@
         // Callbacks run from remote animation when recents animation not currently running
         InteractionJankMonitorWrapper.begin(this,
                 InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Enter form GroupedTaskView");
-        recentsView.getSplitPlaceholder().launchTasks(this /*groupedTaskView*/,
+        recentsView.getSplitSelectController().launchTasks(this /*groupedTaskView*/,
                 success -> {
                     endCallback.executeAllAndDestroy();
                     InteractionJankMonitorWrapper.end(
@@ -206,7 +206,7 @@
 
     @Override
     public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) {
-        getRecentsView().getSplitPlaceholder().launchTasks(mTask.key.id, mSecondaryTask.key.id,
+        getRecentsView().getSplitSelectController().launchTasks(mTask.key.id, mSecondaryTask.key.id,
                 STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList, getSplitRatio());
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b00794f..96607a0 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -912,7 +912,7 @@
         mSplitSelectStateController = splitController;
     }
 
-    public SplitSelectStateController getSplitPlaceholder() {
+    public SplitSelectStateController getSplitSelectController() {
         return mSplitSelectStateController;
     }
 
@@ -4272,7 +4272,7 @@
      * Note that the translation can be its primary or secondary dimension.
      */
     public float getSplitSelectTranslation() {
-        int splitPosition = getSplitPlaceholder().getActiveSplitStagePosition();
+        int splitPosition = getSplitSelectController().getActiveSplitStagePosition();
         if (!shouldShiftThumbnailsForSplitSelect()) {
             return 0f;
         }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 5df03cc..a81f95f 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -95,6 +95,7 @@
 import com.android.quickstep.TaskViewUtils;
 import com.android.quickstep.util.CancellableTask;
 import com.android.quickstep.util.RecentsOrientedState;
+import com.android.quickstep.util.SplitSelectStateController;
 import com.android.quickstep.util.TaskCornerRadius;
 import com.android.quickstep.util.TransformParams;
 import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
@@ -561,6 +562,18 @@
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
+        RecentsView recentsView = getRecentsView();
+        if (recentsView == null || mTask == null) {
+            return false;
+        }
+        SplitSelectStateController splitSelectStateController =
+                recentsView.getSplitSelectController();
+        if (splitSelectStateController.isSplitSelectActive() &&
+                splitSelectStateController.getInitialTaskId() == mTask.key.id) {
+            // Prevent taps on the this taskview if it's being animated into split select state
+            return false;
+        }
+
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
             mLastTouchDownPosition.set(ev.getX(), ev.getY());
         }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5e2187e..a6831aa 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -480,7 +480,6 @@
         mAppWidgetHost = createAppWidgetHost();
         mAppWidgetHost.startListening();
 
-        inflateRootView(R.layout.launcher);
         setupViews();
         crossFadeWithPreviousAppearance();
         mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);
@@ -1259,6 +1258,7 @@
      * Finds all the views we need and configure them properly.
      */
     protected void setupViews() {
+        inflateRootView(R.layout.launcher);
         mDragLayer = findViewById(R.id.drag_layer);
         mFocusHandler = mDragLayer.getFocusIndicatorHelper();
         mWorkspace = mDragLayer.findViewById(R.id.workspace);
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 3983f40..f082542 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -88,6 +88,9 @@
     public static final float PULL_MULTIPLIER = .02f;
     public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
 
+    // Render the header protection at all times to debug clipping issues.
+    private static final boolean DEBUG_HEADER_PROTECTION = false;
+
     private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final Rect mInsets = new Rect();
 
@@ -129,7 +132,6 @@
     private final int mScrimColor;
     private final int mHeaderProtectionColor;
     protected final float mHeaderThreshold;
-    private int mHeaderBottomAdjustment;
     private ScrimView mScrimView;
     private int mHeaderColor;
     private int mTabsProtectionAlpha;
@@ -142,8 +144,6 @@
         mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
         mHeaderThreshold = getResources().getDimensionPixelSize(
                 R.dimen.dynamic_grid_cell_border_spacing);
-        mHeaderBottomAdjustment = getResources().getDimensionPixelSize(
-                R.dimen.all_apps_header_bottom_adjustment);
         mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor);
 
         mWorkManager = new WorkProfileManager(
@@ -728,17 +728,29 @@
         if (!mHeader.isHeaderProtectionSupported()) {
             return;
         }
-        mHeaderPaint.setColor(mHeaderColor);
-        mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
+        if (DEBUG_HEADER_PROTECTION) {
+            mHeaderPaint.setColor(Color.MAGENTA);
+            mHeaderPaint.setAlpha(255);
+        } else {
+            mHeaderPaint.setColor(mHeaderColor);
+            mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
+        }
         if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
             int bottom = getHeaderBottom();
+            FloatingHeaderView headerView = getFloatingHeaderView();
             if (!mUsingTabs) {
-                bottom += getFloatingHeaderView().getPaddingBottom() - mHeaderBottomAdjustment;
+                // Add protection which is otherwise added when tabs scroll up.
+                bottom += headerView.getTabsAdditionalPaddingTop();
             }
             canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint);
-            int tabsHeight = getFloatingHeaderView().getPeripheralProtectionHeight();
+            int tabsHeight = headerView.getPeripheralProtectionHeight();
             if (mTabsProtectionAlpha > 0 && tabsHeight != 0) {
-                mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
+                if (DEBUG_HEADER_PROTECTION) {
+                    mHeaderPaint.setColor(Color.BLUE);
+                    mHeaderPaint.setAlpha(255);
+                } else {
+                    mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
+                }
                 canvas.drawRect(0, bottom, canvas.getWidth(), bottom + tabsHeight, mHeaderPaint);
             }
         }
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 1ef5498..1cbb0f9 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -277,7 +277,7 @@
         }
     }
 
-    public int getMaxTranslation() {
+    int getMaxTranslation() {
         if (mMaxTranslation == 0 && (mTabsHidden || mFloatingRowsCollapsed)) {
             return getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_bottom_padding);
         } else if (mMaxTranslation > 0 && mTabsHidden) {
@@ -334,7 +334,8 @@
 
         int clipTop = getPaddingTop() - mTabsAdditionalPaddingTop;
         if (mTabsHidden) {
-            clipTop += getPaddingBottom() - mTabsAdditionalPaddingBottom;
+            // Add back spacing that is otherwise covered by the tabs.
+            clipTop += mTabsAdditionalPaddingTop;
         }
         mRVClip.top = mTabsHidden || mFloatingRowsCollapsed ? clipTop : 0;
         mHeaderClip.top = clipTop;
@@ -405,6 +406,10 @@
         return mFloatingRowsHeight;
     }
 
+    int getTabsAdditionalPaddingTop() {
+        return mTabsAdditionalPaddingTop;
+    }
+
     int getTabsAdditionalPaddingBottom() {
         return mTabsAdditionalPaddingBottom;
     }
@@ -473,7 +478,7 @@
     /**
      * Returns visible height of FloatingHeaderView contents requiring header protection
      */
-    public int getPeripheralProtectionHeight() {
+    int getPeripheralProtectionHeight() {
         if (!mHeaderProtectionSupported) {
             return 0;
         }
diff --git a/src/com/android/launcher3/allapps/SearchTransitionController.java b/src/com/android/launcher3/allapps/SearchTransitionController.java
index da8902d..8fc7965 100644
--- a/src/com/android/launcher3/allapps/SearchTransitionController.java
+++ b/src/com/android/launcher3/allapps/SearchTransitionController.java
@@ -23,7 +23,7 @@
 import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
 import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.INSTANT;
 import static com.android.launcher3.anim.Interpolators.clampToProgress;
 
 import android.animation.ObjectAnimator;
@@ -41,10 +41,10 @@
 public class SearchTransitionController {
 
     // Interpolator when the user taps the QSB while already in All Apps.
-    private static final Interpolator DEFAULT_INTERPOLATOR_WITHIN_ALL_APPS = DEACCEL_1_7;
+    private static final Interpolator INTERPOLATOR_WITHIN_ALL_APPS = DEACCEL_1_7;
     // Interpolator when the user taps the QSB from home screen, so transition to all apps is
     // happening simultaneously.
-    private static final Interpolator DEFAULT_INTERPOLATOR_TRANSITIONING_TO_ALL_APPS = LINEAR;
+    private static final Interpolator INTERPOLATOR_TRANSITIONING_TO_ALL_APPS = INSTANT;
 
     /**
      * These values represent points on the [0, 1] animation progress spectrum. They are used to
@@ -104,9 +104,11 @@
         boolean inAllApps = Launcher.getLauncher(
                 mAllAppsContainerView.getContext()).getStateManager().isInStableState(
                 LauncherState.ALL_APPS);
+        if (!inAllApps) {
+            duration = 0;  // Don't want to animate when coming from QSB.
+        }
         mSearchToAzAnimator.setDuration(duration).setInterpolator(
-                inAllApps ? DEFAULT_INTERPOLATOR_WITHIN_ALL_APPS
-                        : DEFAULT_INTERPOLATOR_TRANSITIONING_TO_ALL_APPS);
+                inAllApps ? INTERPOLATOR_WITHIN_ALL_APPS : INTERPOLATOR_TRANSITIONING_TO_ALL_APPS);
         mSearchToAzAnimator.addListener(forEndCallback(() -> mSearchToAzAnimator = null));
         if (!goingToSearch) {
             mSearchToAzAnimator.addListener(forSuccessCallback(() -> {
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index a589448..15fb77c 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -97,12 +97,10 @@
                 bottomMargin += dp.hotseatQsbHeight;
             }
 
-            if (!dp.isGestureMode) {
-                if (dp.isTaskbarPresent) {
-                    bottomMargin += dp.taskbarSize;
-                } else {
-                    bottomMargin += insets.bottom;
-                }
+            if (!dp.isGestureMode && dp.isTaskbarPresent) {
+                bottomMargin += dp.taskbarSize;
+            } else {
+                bottomMargin += insets.bottom;
             }
 
             lp.bottomMargin = bottomMargin;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 406496b..4a47e98 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -94,9 +94,6 @@
             getDebugFlag("ENABLE_FLOATING_SEARCH_BAR", false,
                     "Keep All Apps search bar at the bottom (but above keyboard if open)");
 
-    public static final BooleanFlag ENABLE_QUICK_SEARCH = new DeviceFlag("ENABLE_QUICK_SEARCH",
-            true, "Use quick search behavior.");
-
     public static final BooleanFlag ENABLE_HIDE_HEADER = new DeviceFlag("ENABLE_HIDE_HEADER",
             true, "Hide header on keyboard before typing in all apps");
 
@@ -281,14 +278,6 @@
             "FOLDABLE_WORKSPACE_REORDER", true,
             "In foldables, when reordering the icons and widgets, is now going to use both sides");
 
-    public static final BooleanFlag SHOW_SEARCH_EDUCARD_QSB = new DeviceFlag(
-            "SHOW_SEARCH_EDUCARD_QSB", false, "Shows Search Educard for QSB entry in OneSearch.");
-
-    public static final BooleanFlag ENABLE_IME_LATENCY_LOGGER = getDebugFlag(
-            "ENABLE_IME_LATENCY_LOGGER", false,
-            "Enable option to log the keyboard latency for both atomic and controlled keyboard "
-                    + "animations on an EditText");
-
     public static final BooleanFlag ENABLE_WIDGET_PICKER_DEPTH = new DeviceFlag(
             "ENABLE_WIDGET_PICKER_DEPTH", false, "Enable changing depth in widget picker.");
 
@@ -297,6 +286,9 @@
             "Enable showing the new 'delightful pagination'"
                     + " which is a brand new animation for folder pagination");
 
+    public static final BooleanFlag POPUP_MATERIAL_U = new DeviceFlag(
+            "POPUP_MATERIAL_U", false, "Switch popup UX to use material U");
+
     public static void initialize(Context context) {
         synchronized (sDebugFlags) {
             for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 32237e2..22627b4 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -744,8 +744,9 @@
             HOT(2),
             TIMEOUT(3),
             FAIL(4),
-            COLD_USERWAITING(5);
-
+            COLD_USERWAITING(5),
+            ATOMIC(6),
+            CONTROLLED(7);
             private final int mId;
 
             LatencyType(int id) {
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index 1798536..fb51bf0 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -56,13 +56,16 @@
     private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150;
     private static final int ENTER_ANIMATION_DURATION = 400;
 
-    private static final int DOT_ACTIVE_ALPHA = 255;
-    private static final int DOT_INACTIVE_ALPHA = 128;
+    private static final int PAGE_INDICATOR_ALPHA = 255;
+    private static final int DOT_ALPHA = 128;
     private static final int DOT_GAP_FACTOR = 3;
+    private static final float DOT_GAP_FACTOR_FLOAT = 3.8f;
 
     // This value approximately overshoots to 1.5 times the original size.
     private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f;
 
+    private static final float INDICATOR_ROTATION = 180f;
+
     private static final RectF sTempRect = new RectF();
 
     private static final Property<PageIndicatorDots, Float> CURRENT_POSITION
@@ -121,7 +124,12 @@
         mPaginationPaint.setStyle(Style.FILL);
         mPaginationPaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor));
         mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2;
-        mCircleGap = DOT_GAP_FACTOR * mDotRadius;
+
+        if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) {
+            mCircleGap = DOT_GAP_FACTOR_FLOAT * mDotRadius;
+        } else {
+            mCircleGap = DOT_GAP_FACTOR * mDotRadius;
+        }
         mPageIndicatorSize = getResources().getDimension(
                 R.dimen.page_indicator_current_page_indicator_size);
         if (!SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) {
@@ -274,7 +282,7 @@
                 circleGap = -circleGap;
             }
             for (int i = 0; i < mEntryAnimationRadiusFactors.length; i++) {
-                mPaginationPaint.setAlpha(i == mActivePage ? DOT_ACTIVE_ALPHA : DOT_INACTIVE_ALPHA);
+                mPaginationPaint.setAlpha(i == mActivePage ? PAGE_INDICATOR_ALPHA : DOT_ALPHA);
                 if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) {
                     canvas.drawCircle(x, y, getRadius(x) * mEntryAnimationRadiusFactors[i],
                             mPaginationPaint);
@@ -285,7 +293,8 @@
                 x += circleGap;
             }
         } else {
-            mPaginationPaint.setAlpha(DOT_INACTIVE_ALPHA);
+            // Here we draw the dots
+            mPaginationPaint.setAlpha(DOT_ALPHA);
             for (int i = 0; i < mNumPages; i++) {
                 if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) {
                     canvas.drawCircle(x, y, getRadius(x), mPaginationPaint);
@@ -295,10 +304,20 @@
                 x += circleGap;
             }
 
-            mPaginationPaint.setAlpha(DOT_ACTIVE_ALPHA);
-
+            // Here we draw the current page indicator
+            mPaginationPaint.setAlpha(PAGE_INDICATOR_ALPHA);
             if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) {
-                canvas.drawRect(getActiveRect(), mPaginationPaint);
+                RectF currRect = getActiveRect();
+                int scrollPerPage = getScrollPerPage();
+
+                // This IF is to avoid division by 0
+                if (scrollPerPage != 0) {
+                    int delta = mCurrentScroll % scrollPerPage;
+                    canvas.rotate((INDICATOR_ROTATION * delta) / scrollPerPage,
+                            currRect.centerX(), currRect.centerY());
+                }
+
+                canvas.drawRect(currRect, mPaginationPaint);
             } else {
                 canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint);
             }
@@ -376,10 +395,17 @@
     }
 
     /**
+     * Returns an int that is the amount we need to scroll per page
+     */
+    private int getScrollPerPage() {
+        return mNumPages > 1 ? mTotalScroll / (mNumPages - 1) : 0;
+    }
+
+    /**
      * The current scroll adjusted for the distance the indicator needs to travel on the screen
      */
     private float getIndicatorScrollDistance() {
-        float scrollPerPage = mNumPages > 1 ? mTotalScroll / (mNumPages - 1) : 0;
+        int scrollPerPage = getScrollPerPage();
         return scrollPerPage != 0 ? ((float) mCurrentScroll / scrollPerPage) * mCircleGap : 0;
     }