3030import android .os .AsyncTask ;
3131import android .os .Handler ;
3232import android .os .Process ;
33+ import android .os .UserHandle ;
3334import android .util .Log ;
3435import android .view .MotionEvent ;
3536import android .view .View ;
@@ -52,6 +53,8 @@ public class RecentTasksLoader implements View.OnTouchListener {
5253
5354 private Context mContext ;
5455 private RecentsPanelView mRecentsPanel ;
56+
57+ private Object mFirstTaskLock = new Object ();
5558 private TaskDescription mFirstTask ;
5659 private boolean mFirstTaskLoaded ;
5760
@@ -70,23 +73,16 @@ public class RecentTasksLoader implements View.OnTouchListener {
7073 private enum State { LOADING , LOADED , CANCELLED };
7174 private State mState = State .CANCELLED ;
7275
73- public TaskDescription getFirstTask () {
74- while (!mFirstTaskLoaded ) {
75- if (mState == State .CANCELLED ) {
76- loadTasksInBackground ();
77- }
78- try {
79- if (mState == State .LOADED ) {
80- break ;
81- }
82- Thread .sleep (5 );
83- } catch (InterruptedException e ) {
84- }
76+
77+ private static RecentTasksLoader sInstance ;
78+ public static RecentTasksLoader getInstance (Context context ) {
79+ if (sInstance == null ) {
80+ sInstance = new RecentTasksLoader (context );
8581 }
86- return mFirstTask ;
82+ return sInstance ;
8783 }
8884
89- public RecentTasksLoader (Context context ) {
85+ private RecentTasksLoader (Context context ) {
9086 mContext = context ;
9187 mHandler = new Handler ();
9288
@@ -295,15 +291,107 @@ private void cancelLoadingThumbnailsAndIcons() {
295291 mThumbnailLoader = null ;
296292 }
297293 mLoadedTasks = null ;
298- mFirstTask = null ;
299- mFirstTaskLoaded = false ;
300294 if (mRecentsPanel != null ) {
301295 mRecentsPanel .onTaskLoadingCancelled ();
302296 }
303297 mFirstScreenful = false ;
304298 mState = State .CANCELLED ;
305299 }
306300
301+ private void clearFirstTask () {
302+ synchronized (mFirstTaskLock ) {
303+ mFirstTask = null ;
304+ mFirstTaskLoaded = false ;
305+ }
306+ }
307+
308+ public void preloadFirstTask () {
309+ Thread bgLoad = new Thread () {
310+ public void run () {
311+ TaskDescription first = loadFirstTask ();
312+ synchronized (mFirstTaskLock ) {
313+ if (mCancelPreloadingFirstTask ) {
314+ clearFirstTask ();
315+ } else {
316+ mFirstTask = first ;
317+ mFirstTaskLoaded = true ;
318+ }
319+ mPreloadingFirstTask = false ;
320+ }
321+ }
322+ };
323+ synchronized (mFirstTaskLock ) {
324+ if (!mPreloadingFirstTask ) {
325+ clearFirstTask ();
326+ mPreloadingFirstTask = true ;
327+ bgLoad .start ();
328+ }
329+ }
330+ }
331+
332+ public void cancelPreloadingFirstTask () {
333+ synchronized (mFirstTaskLock ) {
334+ if (mPreloadingFirstTask ) {
335+ mCancelPreloadingFirstTask = true ;
336+ } else {
337+ clearFirstTask ();
338+ }
339+ }
340+ }
341+
342+ boolean mPreloadingFirstTask ;
343+ boolean mCancelPreloadingFirstTask ;
344+ public TaskDescription getFirstTask () {
345+ while (true ) {
346+ synchronized (mFirstTaskLock ) {
347+ if (mFirstTaskLoaded ) {
348+ return mFirstTask ;
349+ } else if (!mFirstTaskLoaded && !mPreloadingFirstTask ) {
350+ mFirstTask = loadFirstTask ();
351+ mFirstTaskLoaded = true ;
352+ return mFirstTask ;
353+ }
354+ }
355+ try {
356+ Thread .sleep (3 );
357+ } catch (InterruptedException e ) {
358+ }
359+ }
360+ }
361+
362+ public TaskDescription loadFirstTask () {
363+ final ActivityManager am = (ActivityManager ) mContext .getSystemService (Context .ACTIVITY_SERVICE );
364+
365+ final List <ActivityManager .RecentTaskInfo > recentTasks = am .getRecentTasksForUser (
366+ 1 , ActivityManager .RECENT_IGNORE_UNAVAILABLE , UserHandle .CURRENT .getIdentifier ());
367+ TaskDescription item = null ;
368+ if (recentTasks .size () > 0 ) {
369+ ActivityManager .RecentTaskInfo recentInfo = recentTasks .get (0 );
370+
371+ Intent intent = new Intent (recentInfo .baseIntent );
372+ if (recentInfo .origActivity != null ) {
373+ intent .setComponent (recentInfo .origActivity );
374+ }
375+
376+ // Don't load the current home activity.
377+ if (isCurrentHomeActivity (intent .getComponent (), null )) {
378+ return null ;
379+ }
380+
381+ // Don't load ourselves
382+ if (intent .getComponent ().getPackageName ().equals (mContext .getPackageName ())) {
383+ return null ;
384+ }
385+
386+ item = createTaskDescription (recentInfo .id ,
387+ recentInfo .persistentId , recentInfo .baseIntent ,
388+ recentInfo .origActivity , recentInfo .description );
389+ loadThumbnailAndIcon (item );
390+ return item ;
391+ }
392+ return null ;
393+ }
394+
307395 public void loadTasksInBackground () {
308396 loadTasksInBackground (false );
309397 }
@@ -367,9 +455,6 @@ protected Void doInBackground(Void... params) {
367455
368456 // Don't load the current home activity.
369457 if (isCurrentHomeActivity (intent .getComponent (), homeInfo )) {
370- if (index == 0 ) {
371- mFirstTaskLoaded = true ;
372- }
373458 continue ;
374459 }
375460
@@ -466,19 +551,13 @@ protected Void doInBackground(Void... params) {
466551 }
467552 loadThumbnailAndIcon (td );
468553
469- if (!mFirstTaskLoaded ) {
470- mFirstTask = td ;
471- mFirstTaskLoaded = true ;
472- }
473554 publishProgress (td );
474555 }
475556
476557 Process .setThreadPriority (origPri );
477558 return null ;
478559 }
479560 };
480- mFirstTask = null ;
481- mFirstTaskLoaded = false ;
482561 mThumbnailLoader .executeOnExecutor (AsyncTask .THREAD_POOL_EXECUTOR );
483562 }
484563}
0 commit comments