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

Commit 80343f64 authored by Michael Jurka's avatar Michael Jurka
Browse files

Fix recents animations for secondary users

Bug: 7361640

Change-Id: Ibd177bf01758fb8706b82dcf3bf234e052c38aa3
parent a1f739ea
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@
    <uses-permission android:name="android.permission.WRITE_DREAM_STATE" />

    <application
        android:name="com.android.systemui.SystemUIApplication"
        android:persistent="true"
        android:allowClearUserData="false"
        android:allowBackup="false"
@@ -118,6 +117,15 @@
          </intent-filter>
        </activity>

        <receiver
            android:name=".recent.RecentsPreloadReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.android.systemui.recent.action.PRELOAD" />
                <action android:name="com.android.systemui.recent.action.CANCEL_PRELOAD" />
            </intent-filter>
        </receiver>

        <!-- started from UsbDeviceSettingsManager -->
        <activity android:name=".usb.UsbConfirmActivity"
            android:exported="true"
+104 −25
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -52,6 +53,8 @@ public class RecentTasksLoader implements View.OnTouchListener {

    private Context mContext;
    private RecentsPanelView mRecentsPanel;

    private Object mFirstTaskLock = new Object();
    private TaskDescription mFirstTask;
    private boolean mFirstTaskLoaded;

@@ -70,23 +73,16 @@ public class RecentTasksLoader implements View.OnTouchListener {
    private enum State { LOADING, LOADED, CANCELLED };
    private State mState = State.CANCELLED;

    public TaskDescription getFirstTask() {
        while (!mFirstTaskLoaded) {
            if (mState == State.CANCELLED) {
                loadTasksInBackground();
            }
            try {
                if (mState == State.LOADED) {
                    break;
                }
                Thread.sleep(5);
            } catch (InterruptedException e) {

    private static RecentTasksLoader sInstance;
    public static RecentTasksLoader getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new RecentTasksLoader(context);
        }
        }
        return mFirstTask;
        return sInstance;
    }

    public RecentTasksLoader(Context context) {
    private RecentTasksLoader(Context context) {
        mContext = context;
        mHandler = new Handler();

@@ -295,8 +291,6 @@ public class RecentTasksLoader implements View.OnTouchListener {
            mThumbnailLoader = null;
        }
        mLoadedTasks = null;
        mFirstTask = null;
        mFirstTaskLoaded = false;
        if (mRecentsPanel != null) {
            mRecentsPanel.onTaskLoadingCancelled();
        }
@@ -304,6 +298,100 @@ public class RecentTasksLoader implements View.OnTouchListener {
        mState = State.CANCELLED;
    }

    private void clearFirstTask() {
        synchronized (mFirstTaskLock) {
            mFirstTask = null;
            mFirstTaskLoaded = false;
        }
    }

    public void preloadFirstTask() {
        Thread bgLoad = new Thread() {
            public void run() {
                TaskDescription first = loadFirstTask();
                synchronized(mFirstTaskLock) {
                    if (mCancelPreloadingFirstTask) {
                        clearFirstTask();
                    } else {
                        mFirstTask = first;
                        mFirstTaskLoaded = true;
                    }
                    mPreloadingFirstTask = false;
                }
            }
        };
        synchronized(mFirstTaskLock) {
            if (!mPreloadingFirstTask) {
                clearFirstTask();
                mPreloadingFirstTask = true;
                bgLoad.start();
            }
        }
    }

    public void cancelPreloadingFirstTask() {
        synchronized(mFirstTaskLock) {
            if (mPreloadingFirstTask) {
                mCancelPreloadingFirstTask = true;
            } else {
                clearFirstTask();
            }
        }
    }

    boolean mPreloadingFirstTask;
    boolean mCancelPreloadingFirstTask;
    public TaskDescription getFirstTask() {
        while(true) {
            synchronized(mFirstTaskLock) {
                if (mFirstTaskLoaded) {
                    return mFirstTask;
                } else if (!mFirstTaskLoaded && !mPreloadingFirstTask) {
                    mFirstTask = loadFirstTask();
                    mFirstTaskLoaded = true;
                    return mFirstTask;
                }
            }
            try {
                Thread.sleep(3);
            } catch (InterruptedException e) {
            }
        }
    }

    public TaskDescription loadFirstTask() {
        final ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);

        final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasksForUser(
                1, ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.CURRENT.getIdentifier());
        TaskDescription item = null;
        if (recentTasks.size() > 0) {
            ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(0);

            Intent intent = new Intent(recentInfo.baseIntent);
            if (recentInfo.origActivity != null) {
                intent.setComponent(recentInfo.origActivity);
            }

            // Don't load the current home activity.
            if (isCurrentHomeActivity(intent.getComponent(), null)) {
                return null;
            }

            // Don't load ourselves
            if (intent.getComponent().getPackageName().equals(mContext.getPackageName())) {
                return null;
            }

            item = createTaskDescription(recentInfo.id,
                    recentInfo.persistentId, recentInfo.baseIntent,
                    recentInfo.origActivity, recentInfo.description);
            loadThumbnailAndIcon(item);
            return item;
        }
        return null;
    }

    public void loadTasksInBackground() {
        loadTasksInBackground(false);
    }
@@ -367,9 +455,6 @@ public class RecentTasksLoader implements View.OnTouchListener {

                    // Don't load the current home activity.
                    if (isCurrentHomeActivity(intent.getComponent(), homeInfo)) {
                        if (index == 0) {
                            mFirstTaskLoaded = true;
                        }
                        continue;
                    }

@@ -466,10 +551,6 @@ public class RecentTasksLoader implements View.OnTouchListener {
                    }
                    loadThumbnailAndIcon(td);

                    if (!mFirstTaskLoaded) {
                        mFirstTask = td;
                        mFirstTaskLoaded = true;
                    }
                    publishProgress(td);
                }

@@ -477,8 +558,6 @@ public class RecentTasksLoader implements View.OnTouchListener {
                return null;
            }
        };
        mFirstTask = null;
        mFirstTaskLoaded = false;
        mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }
}
+28 −26
Original line number Diff line number Diff line
@@ -30,14 +30,18 @@ import android.view.View;
import android.view.WindowManager;

import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.statusbar.tablet.StatusBarPanel;

import java.util.List;

public class RecentsActivity extends Activity {
    public static final String TOGGLE_RECENTS_INTENT = "com.android.systemui.TOGGLE_RECENTS";
    public static final String CLOSE_RECENTS_INTENT = "com.android.systemui.CLOSE_RECENTS";
    public static final String TOGGLE_RECENTS_INTENT = "com.android.systemui.recent.action.TOGGLE_RECENTS";
    public static final String PRELOAD_INTENT = "com.android.systemui.recent.action.PRELOAD";
    public static final String CANCEL_PRELOAD_INTENT = "com.android.systemui.recent.CANCEL_PRELOAD";
    public static final String CLOSE_RECENTS_INTENT = "com.android.systemui.recent.action.CLOSE";
    public static final String WINDOW_ANIMATION_START_INTENT = "com.android.systemui.recent.action.WINDOW_ANIMATION_START";
    public static final String PRELOAD_PERMISSION = "com.android.systemui.recent.permission.PRELOAD";
    public static final String WAITING_FOR_WINDOW_ANIMATION_PARAM = "com.android.systemui.recent.WAITING_FOR_WINDOW_ANIMATION";
    private static final String WAS_SHOWING = "was_showing";

    private RecentsPanelView mRecentsPanel;
@@ -48,18 +52,20 @@ public class RecentsActivity extends Activity {
    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (CLOSE_RECENTS_INTENT.equals(intent.getAction())) {
                if (mRecentsPanel != null && mRecentsPanel.isShowing()) {
                    if (mShowing && !mForeground) {
                        // Captures the case right before we transition to another activity
                        mRecentsPanel.show(false);
                    }
                }
            } else if (WINDOW_ANIMATION_START_INTENT.equals(intent.getAction())) {
                if (mRecentsPanel != null) {
                    mRecentsPanel.onWindowAnimationStart();
                }
            }
    };

    public static interface WindowAnimationStartListener {
        void onWindowAnimationStart();
        }
    };

    public class TouchOutsideListener implements View.OnTouchListener {
        private StatusBarPanel mPanel;
@@ -164,25 +170,23 @@ public class RecentsActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        final SystemUIApplication app = (SystemUIApplication) getApplication();
        final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();

        setContentView(R.layout.status_bar_recent_panel);
        mRecentsPanel = (RecentsPanelView) findViewById(R.id.recents_root);
        mRecentsPanel.setOnTouchListener(new TouchOutsideListener(mRecentsPanel));
        mRecentsPanel.setRecentTasksLoader(recentTasksLoader);

        final RecentTasksLoader recentTasksLoader = RecentTasksLoader.getInstance(this);
        recentTasksLoader.setRecentsPanel(mRecentsPanel, mRecentsPanel);
        mRecentsPanel.setMinSwipeAlpha(
                getResources().getInteger(R.integer.config_recent_item_min_alpha) / 100f);

        if (savedInstanceState == null ||
                savedInstanceState.getBoolean(WAS_SHOWING)) {
            handleIntent(getIntent());
            handleIntent(getIntent(), (savedInstanceState == null));
        }
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(CLOSE_RECENTS_INTENT);
        mIntentFilter.addAction(WINDOW_ANIMATION_START_INTENT);
        registerReceiver(mIntentReceiver, mIntentFilter);
        app.setWindowAnimationStartListener(mRecentsPanel);
        super.onCreate(savedInstanceState);
    }

@@ -193,20 +197,17 @@ public class RecentsActivity extends Activity {

    @Override
    protected void onDestroy() {
        final SystemUIApplication app = (SystemUIApplication) getApplication();
        final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();
        recentTasksLoader.setRecentsPanel(null, mRecentsPanel);
        RecentTasksLoader.getInstance(this).setRecentsPanel(null, mRecentsPanel);
        unregisterReceiver(mIntentReceiver);
        app.setWindowAnimationStartListener(null);
        super.onDestroy();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        handleIntent(intent);
        handleIntent(intent, true);
    }

    private void handleIntent(Intent intent) {
    private void handleIntent(Intent intent, boolean checkWaitingForAnimationParam) {
        super.onNewIntent(intent);

        if (TOGGLE_RECENTS_INTENT.equals(intent.getAction())) {
@@ -214,10 +215,11 @@ public class RecentsActivity extends Activity {
                if (mRecentsPanel.isShowing()) {
                    dismissAndGoBack();
                } else {
                    final SystemUIApplication app = (SystemUIApplication) getApplication();
                    final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();
                    final RecentTasksLoader recentTasksLoader = RecentTasksLoader.getInstance(this);
                    boolean waitingForWindowAnimation = checkWaitingForAnimationParam &&
                            intent.getBooleanExtra(WAITING_FOR_WINDOW_ANIMATION_PARAM, false);
                    mRecentsPanel.show(true, recentTasksLoader.getLoadedTasks(),
                            recentTasksLoader.isFirstScreenful());
                            recentTasksLoader.isFirstScreenful(), waitingForWindowAnimation);
                }
            }
        }
+10 −12
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ import android.widget.PopupMenu;
import android.widget.TextView;

import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.tablet.StatusBarPanel;
@@ -68,7 +67,7 @@ import com.android.systemui.statusbar.tablet.TabletStatusBar;
import java.util.ArrayList;

public class RecentsPanelView extends FrameLayout implements OnItemClickListener, RecentsCallback,
        StatusBarPanel, Animator.AnimatorListener, RecentsActivity.WindowAnimationStartListener {
        StatusBarPanel, Animator.AnimatorListener {
    static final String TAG = "RecentsPanelView";
    static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
    private PopupMenu mPopup;
@@ -81,6 +80,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
    private boolean mWaitingToShow;
    private int mNumItemsWaitingForThumbnailsAndIcons;
    private ViewHolder mItemToAnimateInWhenWindowAnimationIsFinished;
    private boolean mWaitingForWindowAnimation;

    private RecentTasksLoader mRecentTasksLoader;
    private ArrayList<TaskDescription> mRecentTaskDescriptions;
@@ -147,13 +147,9 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
                    (ImageView) convertView.findViewById(R.id.app_thumbnail_image);
            // If we set the default thumbnail now, we avoid an onLayout when we update
            // the thumbnail later (if they both have the same dimensions)
            if (mRecentTasksLoader != null) {
            updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
            }
            holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
            if (mRecentTasksLoader != null) {
            holder.iconView.setImageBitmap(mRecentTasksLoader.getDefaultIcon());
            }
            holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
            holder.calloutLine = convertView.findViewById(R.id.recents_callout_line);
            holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
@@ -183,8 +179,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
            }
            if (index == 0) {
                final Activity activity = (Activity) RecentsPanelView.this.getContext();
                final SystemUIApplication app = (SystemUIApplication) activity.getApplication();
                if (app.isWaitingForWindowAnimationStart()) {
                if (mWaitingForWindowAnimation) {
                    if (mItemToAnimateInWhenWindowAnimationIsFinished != null) {
                        for (View v :
                            new View[] { holder.iconView, holder.labelView, holder.calloutLine }) {
@@ -247,6 +242,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
                defStyle, 0);

        mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
        mRecentTasksLoader = RecentTasksLoader.getInstance(context);
        a.recycle();
    }

@@ -280,11 +276,12 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
    }

    public void show(boolean show) {
        show(show, null, false);
        show(show, null, false, false);
    }

    public void show(boolean show, ArrayList<TaskDescription> recentTaskDescriptions,
            boolean firstScreenful) {
            boolean firstScreenful, boolean waitingForWindowAnimation) {
        mWaitingForWindowAnimation = waitingForWindowAnimation;
        if (show) {
            mWaitingToShow = true;
            refreshRecentTasksList(recentTaskDescriptions, firstScreenful);
@@ -542,6 +539,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
                }
            }
            mItemToAnimateInWhenWindowAnimationIsFinished = null;
            mWaitingForWindowAnimation = false;
        }
    }

+32 −0
Original line number Diff line number Diff line
@@ -14,46 +14,19 @@
 * limitations under the License.
 */

package com.android.systemui;
package com.android.systemui.recent;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.recent.RecentsActivity;

public class SystemUIApplication extends Application {
    private RecentTasksLoader mRecentTasksLoader;
    private boolean mWaitingForWinAnimStart;
    private RecentsActivity.WindowAnimationStartListener mWinAnimStartListener;

    public RecentTasksLoader getRecentTasksLoader() {
        if (mRecentTasksLoader == null) {
            mRecentTasksLoader = new RecentTasksLoader(this);
        }
        return mRecentTasksLoader;
    }

    public void setWaitingForWinAnimStart(boolean waiting) {
        mWaitingForWinAnimStart = waiting;
    }

    public void setWindowAnimationStartListener(
            RecentsActivity.WindowAnimationStartListener startListener) {
        mWinAnimStartListener = startListener;
public class RecentsPreloadReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (RecentsActivity.PRELOAD_INTENT.equals(intent.getAction())) {
            RecentTasksLoader.getInstance(context).preloadRecentTasksList();
        } else if (RecentsActivity.CANCEL_PRELOAD_INTENT.equals(intent.getAction())){
            RecentTasksLoader.getInstance(context).cancelPreloadingRecentTasksList();
        }

    public RecentsActivity.WindowAnimationStartListener getWindowAnimationListener() {
        return mWinAnimStartListener;
    }

    public void onWindowAnimationStart() {
        if (mWinAnimStartListener != null) {
            mWinAnimStartListener.onWindowAnimationStart();
        }
        mWaitingForWinAnimStart = false;
    }

    public boolean isWaitingForWindowAnimationStart() {
        return mWaitingForWinAnimStart;
    }
}
Loading