Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dcfa7976 authored by Winson Chung's avatar Winson Chung
Browse files

Intermediate refactoring to move towards in-app view transitions.

- Fixing bug where we weren't toggling to the right task when using affiliations
- Refactoring task rect calculation to allow full screen task view to be laid out for transitions
- Refactoring the view bounds animations into a separate class
- Refactoring the footer view (for lock-to-task) out of TaskView
- Refactoring some transform code out of TaskView
- Removing fullscreen overlay view
- Fixing case where extra invalidations and layouts were still happening in FixedSizeImageView
- Adding debug overlay to replace specific debug drawing code

Change-Id: Ibf98b6a0782a68cd84582203c807cece1ff3379f
parent 8d7f8a25
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@
            android:visibility="invisible"
            android:src="@drawable/recents_dismiss_light" />
    </com.android.systemui.recents.views.TaskBarView>
    <FrameLayout
    <com.android.systemui.recents.views.TaskFooterView
        android:id="@+id/lock_to_app"
        android:layout_width="match_parent"
        android:layout_height="@dimen/recents_task_view_lock_to_app_button_height"
@@ -82,7 +82,7 @@
            android:fontFamily="sans-serif-medium"
            android:singleLine="true"
            android:textAllCaps="true" />
    </FrameLayout>
    </com.android.systemui.recents.views.TaskFooterView>
</com.android.systemui.recents.views.TaskView>

+27 −9
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -70,10 +71,13 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta

    // Task launching
    RecentsConfiguration mConfig;
    Rect mWindowRect;
    Rect mTaskStackBounds;
    Rect mWindowRect = new Rect();
    Rect mTaskStackBounds = new Rect();
    Rect mSystemInsets = new Rect();
    TaskViewTransform mTmpTransform = new TaskViewTransform();
    int mStatusBarHeight;
    int mNavBarHeight;
    int mNavBarWidth;

    // Variables to keep track of if we need to start recents after binding
    View mStatusBarView;
@@ -81,15 +85,23 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
    long mLastToggleTime;

    public AlternateRecentsComponent(Context context) {
        Resources res = context.getResources();
        mContext = context;
        mSystemServicesProxy = new SystemServicesProxy(context);
        mHandler = new Handler();
        mConfig = RecentsConfiguration.reinitialize(context, mSystemServicesProxy);
        mWindowRect = mSystemServicesProxy.getWindowRect();
        mTaskStackBounds = new Rect();
        mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mTaskStackBounds);
        mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.status_bar_height);
        mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
        mNavBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
        mNavBarWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
        mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
                mNavBarWidth, mTaskStackBounds);
        if (mConfig.isLandscape && mConfig.transposeRecentsLayoutWithOrientation) {
            mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0);
        } else {
            mSystemInsets.set(0, mStatusBarHeight, 0, mNavBarHeight);
        }
    }

    public void onStart() {
@@ -150,7 +162,13 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
        mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
        mConfig.updateOnConfigurationChange();
        mWindowRect = mSystemServicesProxy.getWindowRect();
        mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mTaskStackBounds);
        mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
                mNavBarWidth, mTaskStackBounds);
        if (mConfig.isLandscape && mConfig.transposeRecentsLayoutWithOrientation) {
            mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0);
        } else {
            mSystemInsets.set(0, mStatusBarHeight, 0, mNavBarHeight);
        }
        sLastScreenshot = null;
    }

@@ -301,7 +319,9 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
        // Get the stack
        TaskStackView tsv = new TaskStackView(mContext, stack);
        TaskStackViewLayoutAlgorithm algo = tsv.getStackAlgorithm();
        tsv.computeRects(mTaskStackBounds.width(), mTaskStackBounds.height() - mStatusBarHeight, 0, 0);
        Rect taskStackBounds = new Rect(mTaskStackBounds);
        taskStackBounds.bottom -= mSystemInsets.bottom;
        tsv.computeRects(mWindowRect.width(), mWindowRect.height(), taskStackBounds);
        tsv.setStackScrollToInitialState();

        // Find the running task in the TaskStack
@@ -325,8 +345,6 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta

        // Get the transform for the running task
        mTmpTransform = algo.getStackTransform(task, tsv.getStackScroll(), mTmpTransform);
        mTmpTransform.rect.offset(mTaskStackBounds.left, mTaskStackBounds.top);
        mTmpTransform.rect.offset(0, mStatusBarHeight);
        return new Rect(mTmpTransform.rect);
    }

+58 −53
Original line number Diff line number Diff line
@@ -32,18 +32,20 @@ import android.os.UserHandle;
import android.util.Pair;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.android.systemui.R;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.DebugTrigger;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.SpaceNode;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.FullscreenTransitionOverlayView;
import com.android.systemui.recents.views.DebugOverlayView;
import com.android.systemui.recents.views.RecentsView;
import com.android.systemui.recents.views.SystemBarScrimViews;
import com.android.systemui.recents.views.ViewAnimation;
@@ -56,8 +58,7 @@ import java.util.ArrayList;
 * The main Recents activity that is started from AlternateRecentsComponent.
 */
public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks,
        RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks,
        FullscreenTransitionOverlayView.FullScreenTransitionViewCallbacks {
        RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks {

    // Actions and Extras sent from AlternateRecentsComponent
    final static String EXTRA_TRIGGERED_FROM_ALT_TAB = "extra_triggered_from_alt_tab";
@@ -73,17 +74,14 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
    SystemBarScrimViews mScrimViews;
    ViewStub mEmptyViewStub;
    View mEmptyView;
    ViewStub mFullscreenOverlayStub;
    FullscreenTransitionOverlayView mFullScreenOverlayView;
    DebugOverlayView mDebugOverlay;

    // Search AppWidget
    RecentsAppWidgetHost mAppWidgetHost;
    AppWidgetProviderInfo mSearchAppWidgetInfo;
    AppWidgetHostView mSearchAppWidgetHostView;


    // Runnables to finish the Recents activity
    FinishRecentsRunnable mFinishRunnable = new FinishRecentsRunnable();
    FinishRecentsRunnable mFinishLaunchHomeRunnable;

    /**
@@ -97,10 +95,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
        Intent mLaunchIntent;
        ActivityOptions mLaunchOpts;

        public FinishRecentsRunnable() {
            // Do nothing
        }

        /**
         * Creates a finish runnable that starts the specified intent, using the given
         * ActivityOptions.
@@ -151,8 +145,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
            } else if (action.equals(ACTION_START_ENTER_ANIMATION)) {
                // Try and start the enter animation (or restart it on configuration changed)
                ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null);
                mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
                        mFullScreenOverlayView, t));
                mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
                onEnterAnimationTriggered();
            }
        }
@@ -187,11 +180,12 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView

    /** Updates the set of recent tasks */
    void updateRecentsTasks(Intent launchIntent) {
        // Load all the tasks
        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
        SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
        ArrayList<TaskStack> stacks = root.getStacks();
        if (!stacks.isEmpty()) {
            mRecentsView.setBSP(root);
            mRecentsView.setTaskStacks(root.getStacks());
        }

        // Update the configuration based on the launch intent
@@ -207,6 +201,23 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
        mConfig.launchedToTaskId = launchIntent.getIntExtra(
                AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_TASK_ID, -1);

        // Mark the task that is the launch target
        int taskStackCount = stacks.size();
        if (mConfig.launchedToTaskId != -1) {
            for (int i = 0; i < taskStackCount; i++) {
                TaskStack stack = stacks.get(i);
                ArrayList<Task> tasks = stack.getTasks();
                int taskCount = tasks.size();
                for (int j = 0; j < taskCount; j++) {
                    Task t = tasks.get(j);
                    if (t.key.id == mConfig.launchedToTaskId) {
                        t.isLaunchTarget = true;
                        break;
                    }
                }
            }
        }

        // Update the top level view's visibilities
        if (mConfig.launchedWithNoRecentTasks) {
            if (mEmptyView == null) {
@@ -286,9 +297,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
    /** Dismisses recents if we are already visible and the intent is to toggle the recents view */
    boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) {
        if (mVisible) {
            // If we are mid-animation into Recents, reverse the animation now
            if (mFullScreenOverlayView != null &&
                mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) return true;
            // If we currently have filtered stacks, then unfilter those first
            if (checkFilteredStackState &&
                mRecentsView.unfilterFilteredStacks()) return true;
@@ -299,8 +307,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
                dismissRecentsToHomeRaw(true);
                return true;
            }
            // Otherwise, try and return to the first Task in the stack
            if (mRecentsView.launchFirstTask()) return true;
            // Otherwise, try and return to the Task that Recents was launched from
            if (mRecentsView.launchPreviousTask()) return true;
            // If none of the other cases apply, then just go Home
            dismissRecentsToHomeRaw(true);
            return true;
@@ -323,9 +331,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
    /** Dismisses Recents directly to Home if we currently aren't transitioning. */
    boolean dismissRecentsToHome(boolean animated) {
        if (mVisible) {
            // If we are mid-animation into Recents, reverse the animation now
            if (mFullScreenOverlayView != null &&
                mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) return true;
            // Return to Home
            dismissRecentsToHomeRaw(animated);
            return true;
@@ -363,8 +368,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
        mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
        mFullscreenOverlayStub = (ViewStub) findViewById(R.id.fullscreen_overlay_stub);
        mScrimViews = new SystemBarScrimViews(this, mConfig);
        inflateDebugOverlay();

        // Bind the search app widget when we first start up
        bindSearchBarAppWidget();
@@ -390,13 +395,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
            e.printStackTrace();
        }

        // Prepare the screenshot transition if necessary
        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
            mFullScreenOverlayView = (FullscreenTransitionOverlayView) mFullscreenOverlayStub.inflate();
            mFullScreenOverlayView.setCallbacks(this);
            mFullScreenOverlayView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
        }

        // Update if we are getting a configuration change
        if (savedInstanceState != null) {
            mConfig.updateOnConfigurationChange();
@@ -404,6 +402,19 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
        }
    }

    /** Inflates the debug overlay if debug mode is enabled. */
    void inflateDebugOverlay() {
        if (mConfig.debugModeEnabled && mDebugOverlay == null) {
            ViewGroup parent = (ViewGroup) findViewById(android.R.id.content).getRootView();
            mDebugOverlay = new DebugOverlayView(this);
            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT);
            parent.addView(mDebugOverlay, lp);
            mRecentsView.setDebugOverlay(mDebugOverlay);
        }
    }

    void onConfigurationChange() {
        // Update RecentsConfiguration
        mConfig = RecentsConfiguration.reinitialize(this,
@@ -411,8 +422,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView

        // Try and start the enter animation (or restart it on configuration changed)
        ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
        mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
                mFullScreenOverlayView, t));
        mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
        onEnterAnimationTriggered();
    }

@@ -421,13 +431,13 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
        super.onNewIntent(intent);
        setIntent(intent);

        // Clear any debug rects
        if (mDebugOverlay != null) {
            mDebugOverlay.clear();
        }

        // Update the recent tasks
        updateRecentsTasks(intent);

        // Prepare the screenshot transition if necessary
        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
            mFullScreenOverlayView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
        }
    }

    @Override
@@ -531,17 +541,25 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView

    /** Called when debug mode is triggered */
    public void onDebugModeTriggered() {

        if (mConfig.developerOptionsEnabled) {
            SharedPreferences settings = getSharedPreferences(getPackageName(), 0);
            if (settings.getBoolean(Constants.Values.App.Key_DebugModeEnabled, false)) {
                // Disable the debug mode
                settings.edit().remove(Constants.Values.App.Key_DebugModeEnabled).apply();
                mConfig.debugModeEnabled = false;
                inflateDebugOverlay();
                mDebugOverlay.disable();
            } else {
                // Enable the debug mode
                settings.edit().putBoolean(Constants.Values.App.Key_DebugModeEnabled, true).apply();
                mConfig.debugModeEnabled = true;
                inflateDebugOverlay();
                mDebugOverlay.enable();
            }
            Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion +
                    ") toggled, please restart Recents now", Toast.LENGTH_SHORT).show();
            Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion + ") " +
                (mConfig.debugModeEnabled ? "Enabled" : "Disabled") + ", please restart Recents now",
                Toast.LENGTH_SHORT).show();
        }
    }

@@ -551,19 +569,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
        mScrimViews.startEnterRecentsAnimation();
    }

    /**** FullscreenTransitionOverlayView.FullScreenTransitionViewCallbacks Implementation ****/

    @Override
    public void onEnterAnimationComplete() {
        // Reset the full screenshot transition view
        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
            mFullScreenOverlayView.reset();

            // Recycle the full screen screenshot
            AlternateRecentsComponent.consumeLastScreenshot();
        }
    }

    /**** RecentsView.RecentsViewCallbacks Implementation ****/

    @Override
+16 −18
Original line number Diff line number Diff line
@@ -309,19 +309,16 @@ public class RecentsConfiguration {
     * Returns the task stack bounds in the current orientation. These bounds do not account for
     * the system insets.
     */
    public void getTaskStackBounds(int width, int height, Rect taskStackBounds) {
        if (hasSearchBarAppWidget()) {
    public void getTaskStackBounds(int windowWidth, int windowHeight, int topInset, int rightInset,
                                   Rect taskStackBounds) {
        Rect searchBarBounds = new Rect();
            getSearchBarBounds(width, height, searchBarBounds);
        getSearchBarBounds(windowWidth, windowHeight, topInset, searchBarBounds);
        if (isLandscape && transposeRecentsLayoutWithOrientation) {
                // In landscape, the search bar appears on the left, so shift the task rect right
                taskStackBounds.set(searchBarBounds.width(), 0, width, height);
            } else {
                // In portrait, the search bar appears on the top, so shift the task rect below
                taskStackBounds.set(0, searchBarBounds.height(), width, height);
            }
            // In landscape, the search bar appears on the left
            taskStackBounds.set(searchBarBounds.right, topInset, windowWidth - rightInset, windowHeight);
        } else {
            taskStackBounds.set(0, 0, width, height);
            // In portrait, the search bar appears on the top (which already has the inset)
            taskStackBounds.set(0, searchBarBounds.bottom, windowWidth, windowHeight);
        }
    }

@@ -329,19 +326,20 @@ public class RecentsConfiguration {
     * Returns the search bar bounds in the current orientation.  These bounds do not account for
     * the system insets.
     */
    public void getSearchBarBounds(int width, int height, Rect searchBarSpaceBounds) {
    public void getSearchBarBounds(int windowWidth, int windowHeight, int topInset,
                                   Rect searchBarSpaceBounds) {
        // Return empty rects if search is not enabled
        if (!Constants.DebugFlags.App.EnableSearchLayout) {
            searchBarSpaceBounds.set(0, 0, 0, 0);
            return;
        int searchBarSize = searchBarSpaceHeightPx;
        if (!Constants.DebugFlags.App.EnableSearchLayout || !hasSearchBarAppWidget()) {
            searchBarSize = 0;
        }

        if (isLandscape && transposeRecentsLayoutWithOrientation) {
            // In landscape, the search bar appears on the left
            searchBarSpaceBounds.set(0, 0, searchBarSpaceHeightPx, height);
            searchBarSpaceBounds.set(0, topInset, searchBarSize, windowHeight);
        } else {
            // In portrait, the search bar appears on the top
            searchBarSpaceBounds.set(0, 0, width, searchBarSpaceHeightPx);
            searchBarSpaceBounds.set(0, topInset, windowWidth, topInset + searchBarSize);
        }
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
@@ -437,7 +438,9 @@ public class SystemServicesProxy {
        Rect windowRect = new Rect();
        if (mWm == null) return windowRect;

        mWm.getDefaultDisplay().getRectSize(windowRect);
        Point p = new Point();
        mWm.getDefaultDisplay().getRealSize(p);
        windowRect.set(0, 0, p.x, p.y);
        return windowRect;
    }

Loading