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

Commit b5b9ad68 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Fading in the first screen, when launcher loads for the first time

Bug: 29007436
Bug: 27705838
Change-Id: I95891d0bad19a67985b689bb96d6068dcd85004a
parent a2454ad2
Loading
Loading
Loading
Loading
+31 −1
Original line number Original line Diff line number Diff line
@@ -465,7 +465,11 @@ public class Launcher extends Activity
            } else {
            } else {
                // We only load the page synchronously if the user rotates (or triggers a
                // We only load the page synchronously if the user rotates (or triggers a
                // configuration change) while launcher is in the foreground
                // configuration change) while launcher is in the foreground
                mModel.startLoader(mWorkspace.getRestorePage());
                if (!mModel.startLoader(mWorkspace.getRestorePage())) {
                    // If we are not binding synchronously, show a fade in animation when
                    // the first page bind completes.
                    mDragLayer.setAlpha(0);
                }
            }
            }
        }
        }


@@ -4003,6 +4007,32 @@ public class Launcher extends Activity
        }
        }
    }
    }


    @Override
    public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
        Runnable r = new Runnable() {
            public void run() {
                finishFirstPageBind(executor);
            }
        };
        if (waitUntilResume(r)) {
            return;
        }

        Runnable onComplete = new Runnable() {
            @Override
            public void run() {
                if (executor != null) {
                    executor.onLoadAnimationCompleted();
                }
            }
        };
        if (mDragLayer.getAlpha() < 1) {
            mDragLayer.animate().alpha(1).withEndAction(onComplete).start();
        } else {
            onComplete.run();
        }
    }

    /**
    /**
     * Callback saying that there aren't any more items to bind.
     * Callback saying that there aren't any more items to bind.
     *
     *
+39 −18
Original line number Original line Diff line number Diff line
@@ -195,6 +195,7 @@ public class LauncherModel extends BroadcastReceiver
        public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end,
        public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end,
                              boolean forceAnimateIcons);
                              boolean forceAnimateIcons);
        public void bindScreens(ArrayList<Long> orderedScreenIds);
        public void bindScreens(ArrayList<Long> orderedScreenIds);
        public void finishFirstPageBind(ViewOnDrawExecutor executor);
        public void finishBindingItems();
        public void finishBindingItems();
        public void bindAppWidget(LauncherAppWidgetInfo info);
        public void bindAppWidget(LauncherAppWidgetInfo info);
        public void bindAllApplications(ArrayList<AppInfo> apps);
        public void bindAllApplications(ArrayList<AppInfo> apps);
@@ -1282,7 +1283,11 @@ public class LauncherModel extends BroadcastReceiver
        return (mCallbacks != null && mCallbacks.get() == callbacks);
        return (mCallbacks != null && mCallbacks.get() == callbacks);
    }
    }


    public void startLoader(int synchronousBindPage) {
    /**
     * Starts the loader. Tries to bind {@params synchronousBindPage} synchronously if possible.
     * @return true if the page could be bound synchronously.
     */
    public boolean startLoader(int synchronousBindPage) {
        // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
        // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
        InstallShortcutReceiver.enableInstallQueue();
        InstallShortcutReceiver.enableInstallQueue();
        synchronized (mLock) {
        synchronized (mLock) {
@@ -1302,12 +1307,14 @@ public class LauncherModel extends BroadcastReceiver
                if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE && mAllAppsLoaded
                if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE && mAllAppsLoaded
                        && mWorkspaceLoaded && mDeepShortcutsLoaded && !mIsLoaderTaskRunning) {
                        && mWorkspaceLoaded && mDeepShortcutsLoaded && !mIsLoaderTaskRunning) {
                    mLoaderTask.runBindSynchronousPage(synchronousBindPage);
                    mLoaderTask.runBindSynchronousPage(synchronousBindPage);
                    return true;
                } else {
                } else {
                    sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                    sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                    sWorker.post(mLoaderTask);
                    sWorker.post(mLoaderTask);
                }
                }
            }
            }
        }
        }
        return false;
    }
    }


    public void stopLoader() {
    public void stopLoader() {
@@ -2508,17 +2515,19 @@ public class LauncherModel extends BroadcastReceiver
                orderedScreenIds.addAll(sBgWorkspaceScreens);
                orderedScreenIds.addAll(sBgWorkspaceScreens);
            }
            }


            final boolean isLoadingSynchronously =
            final int currentScreen;
                    synchronizeBindPage != PagedView.INVALID_RESTORE_PAGE;
            {
            int currScreen = isLoadingSynchronously ? synchronizeBindPage :
                int currScreen = synchronizeBindPage != PagedView.INVALID_RESTORE_PAGE
                oldCallbacks.getCurrentWorkspaceScreen();
                        ? synchronizeBindPage : oldCallbacks.getCurrentWorkspaceScreen();
                if (currScreen >= orderedScreenIds.size()) {
                if (currScreen >= orderedScreenIds.size()) {
                    // There may be no workspace screens (just hotseat items and an empty page).
                    // There may be no workspace screens (just hotseat items and an empty page).
                    currScreen = PagedView.INVALID_RESTORE_PAGE;
                    currScreen = PagedView.INVALID_RESTORE_PAGE;
                }
                }
            final int currentScreen = currScreen;
                currentScreen = currScreen;
            final long currentScreenId = currentScreen < 0
            }
                    ? INVALID_SCREEN_ID : orderedScreenIds.get(currentScreen);
            final boolean validFirstPage = currentScreen >= 0;
            final long currentScreenId =
                    validFirstPage ? orderedScreenIds.get(currentScreen) : INVALID_SCREEN_ID;


            // Separate the items that are on the current screen, and all the other remaining items
            // Separate the items that are on the current screen, and all the other remaining items
            ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
            ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
@@ -2551,12 +2560,24 @@ public class LauncherModel extends BroadcastReceiver
            // Load items on the current page.
            // Load items on the current page.
            bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, mainExecutor);
            bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, mainExecutor);


            // In case of isLoadingSynchronously, only bind the first screen, and defer binding the
            // In case of validFirstPage, only bind the first screen, and defer binding the
            // remaining screens after first onDraw is called. This ensures that the first screen
            // remaining screens after first onDraw (and an optional the fade animation whichever
            // is immediately visible (eg. during rotation)
            // happens later).
            // In case of !isLoadingSynchronously, bind all pages one after other.
            // This ensures that the first screen is immediately visible (eg. during rotation)
            final Executor deferredExecutor = isLoadingSynchronously ?
            // In case of !validFirstPage, bind all pages one after other.
                    new ViewOnDrawExecutor(mHandler) : mainExecutor;
            final Executor deferredExecutor =
                    validFirstPage ? new ViewOnDrawExecutor(mHandler) : mainExecutor;

            mainExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                    if (callbacks != null) {
                        callbacks.finishFirstPageBind(
                                validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null);
                    }
                }
            });


            bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, deferredExecutor);
            bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, deferredExecutor);


@@ -2590,7 +2611,7 @@ public class LauncherModel extends BroadcastReceiver
            };
            };
            deferredExecutor.execute(r);
            deferredExecutor.execute(r);


            if (isLoadingSynchronously) {
            if (validFirstPage) {
                r = new Runnable() {
                r = new Runnable() {
                    public void run() {
                    public void run() {
                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
+19 −3
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.launcher3.util;
package com.android.launcher3.util;


import android.util.Log;
import android.view.View;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewTreeObserver.OnDrawListener;
import android.view.ViewTreeObserver.OnDrawListener;
@@ -39,6 +40,9 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
    private View mAttachedView;
    private View mAttachedView;
    private boolean mCompleted;
    private boolean mCompleted;


    private boolean mLoadAnimationCompleted;
    private boolean mFirstDrawCompleted;

    public ViewOnDrawExecutor(DeferredHandler handler) {
    public ViewOnDrawExecutor(DeferredHandler handler) {
        mHandler = handler;
        mHandler = handler;
    }
    }
@@ -72,19 +76,31 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,


    @Override
    @Override
    public void onDraw() {
    public void onDraw() {
        mFirstDrawCompleted = true;
        mAttachedView.post(this);
        mAttachedView.post(this);
    }
    }


    public void onLoadAnimationCompleted() {
        mLoadAnimationCompleted = true;
        if (mAttachedView != null) {
            mAttachedView.post(this);
        }
    }

    @Override
    @Override
    public void run() {
    public void run() {
        // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
        if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
            for (final Runnable r : mTasks) {
            for (final Runnable r : mTasks) {
                mHandler.post(r);
                mHandler.post(r);
            }
            }
            markCompleted();
            markCompleted();
        }
        }
    }


    public void markCompleted() {
    public void markCompleted() {
        mTasks.clear();
        mTasks.clear();
        mCompleted = true;
        if (mAttachedView != null) {
        if (mAttachedView != null) {
            mAttachedView.getViewTreeObserver().removeOnDrawListener(this);
            mAttachedView.getViewTreeObserver().removeOnDrawListener(this);
            mAttachedView.removeOnAttachStateChangeListener(this);
            mAttachedView.removeOnAttachStateChangeListener(this);