SystemServicesProxy.java revision 65c294036bd3a01af0755519d37ef7e9f64b9fb9
1a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung/* 2a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * Copyright (C) 2014 The Android Open Source Project 3a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * 4a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * you may not use this file except in compliance with the License. 6a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * You may obtain a copy of the License at 7a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * 8a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * 10a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * Unless required by applicable law or agreed to in writing, software 11a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * See the License for the specific language governing permissions and 14a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * limitations under the License. 15a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung */ 16a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 17ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungpackage com.android.systemui.recents.misc; 18a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 19a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.app.ActivityManager; 201f24c7e37bc794057a156a730c7e4b53b01212edWinson Chungimport android.app.ActivityManagerNative; 21a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.app.ActivityOptions; 224f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.app.AppGlobals; 23d16c565a607de754379fe699a4def21bd0e3de2fWinson Chungimport android.app.IActivityContainer; 241f24c7e37bc794057a156a730c7e4b53b01212edWinson Chungimport android.app.IActivityManager; 25740c3ac782675d190941b2ab1905e56f246c1b11Winson Chungimport android.app.ITaskStackListener; 26ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chungimport android.app.SearchManager; 27f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetHost; 28f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetManager; 29f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetProviderInfo; 30a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.ComponentName; 3156e09b42a0f1670970872bef611a8036904ad6bfJason Monkimport android.content.ContentResolver; 32a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.Context; 33a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.Intent; 34a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.pm.ActivityInfo; 354f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.content.pm.IPackageManager; 36a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.pm.PackageManager; 37bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chungimport android.content.pm.ResolveInfo; 3885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chungimport android.content.res.Resources; 39a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.graphics.Bitmap; 40ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport android.graphics.BitmapFactory; 41b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.Canvas; 42b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.Color; 43b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.Paint; 44dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chungimport android.graphics.Point; 45b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.PorterDuff; 46b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.PorterDuffXfermode; 47ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport android.graphics.Rect; 48a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.graphics.drawable.ColorDrawable; 49a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.graphics.drawable.Drawable; 50ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chungimport android.os.Bundle; 51ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport android.os.ParcelFileDescriptor; 524f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.os.RemoteException; 53d16c565a607de754379fe699a4def21bd0e3de2fWinson Chungimport android.os.SystemProperties; 544f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.os.UserHandle; 5556e09b42a0f1670970872bef611a8036904ad6bfJason Monkimport android.provider.Settings; 56b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.util.Log; 57f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.util.Pair; 58d16c565a607de754379fe699a4def21bd0e3de2fWinson Chungimport android.util.SparseArray; 59d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.Display; 60d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.DisplayInfo; 61d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.SurfaceControl; 62d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.WindowManager; 63ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chungimport android.view.accessibility.AccessibilityManager; 644e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chungimport com.android.systemui.R; 65ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.Constants; 662cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chungimport com.android.systemui.recents.Recents; 67a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 68ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.io.IOException; 69a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport java.util.ArrayList; 70d16c565a607de754379fe699a4def21bd0e3de2fWinson Chungimport java.util.Collections; 71d16c565a607de754379fe699a4def21bd0e3de2fWinson Chungimport java.util.Comparator; 72918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chungimport java.util.Iterator; 73a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport java.util.List; 745e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chungimport java.util.Random; 752cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chungimport java.util.concurrent.atomic.AtomicBoolean; 76a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 77a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung/** 78a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * Acts as a shim around the real system services that we need to access data from, and provides 79a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * a point of injection when testing UI. 80a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung */ 81a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungpublic class SystemServicesProxy { 82b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung final static String TAG = "SystemServicesProxy"; 83b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung 84aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn final static BitmapFactory.Options sBitmapOptions; 85aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn 86ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung AccessibilityManager mAccm; 87a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ActivityManager mAm; 881f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung IActivityManager mIam; 89f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung AppWidgetManager mAwm; 90a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung PackageManager mPm; 914f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani IPackageManager mIpm; 92ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung SearchManager mSm; 93d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung WindowManager mWm; 94d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung Display mDisplay; 95918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung String mRecentsPackage; 96da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung ComponentName mAssistComponent; 97a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 98a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung Bitmap mDummyIcon; 9985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int mDummyThumbnailWidth; 10085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int mDummyThumbnailHeight; 101b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung Paint mBgProtectionPaint; 102b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung Canvas mBgProtectionCanvas; 103a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 104aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn static { 105aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn sBitmapOptions = new BitmapFactory.Options(); 106aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn sBitmapOptions.inMutable = true; 107aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn } 108aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn 109a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Private constructor */ 110a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public SystemServicesProxy(Context context) { 111ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung mAccm = AccessibilityManager.getInstance(context); 112a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 1131f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung mIam = ActivityManagerNative.getDefault(); 114f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mAwm = AppWidgetManager.getInstance(context); 115a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mPm = context.getPackageManager(); 1164f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani mIpm = AppGlobals.getPackageManager(); 117ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung mSm = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE); 118d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 119d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mDisplay = mWm.getDefaultDisplay(); 120918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung mRecentsPackage = context.getPackageName(); 121a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 12285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Get the dummy thumbnail width/heights 12385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung Resources res = context.getResources(); 12485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int wId = com.android.internal.R.dimen.thumbnail_width; 12585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int hId = com.android.internal.R.dimen.thumbnail_height; 12685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mDummyThumbnailWidth = res.getDimensionPixelSize(wId); 12785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mDummyThumbnailHeight = res.getDimensionPixelSize(hId); 12885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 129b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // Create the protection paints 130b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint = new Paint(); 131b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)); 132b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint.setColor(0xFFffffff); 133b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas = new Canvas(); 134b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung 135da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung // Resolve the assist intent 136da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung Intent assist = mSm.getAssistIntent(context, false); 137da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung if (assist != null) { 138da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung mAssistComponent = assist.getComponent(); 139da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung } 140da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung 141a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 142a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // Create a dummy icon 1432f2ca08baa072376b3dfd60506625496aa05903fWinson Chung mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); 1446736905dc0e10689f7c63f6da43b31325caf966aWinson Chung mDummyIcon.eraseColor(0xFF999999); 145a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 146a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 147a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 148a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns a list of the recents tasks */ 1499cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId, 1509cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung boolean isTopTaskHome) { 151a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return null; 152a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 153a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then create some recent tasks 154a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 155a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ArrayList<ActivityManager.RecentTaskInfo> tasks = 156a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung new ArrayList<ActivityManager.RecentTaskInfo>(); 157918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung int count = Math.min(numLatestTasks, Constants.DebugFlags.App.SystemServicesProxyMockTaskCount); 158a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung for (int i = 0; i < count; i++) { 159a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // Create a dummy component name 160a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung int packageIndex = i % Constants.DebugFlags.App.SystemServicesProxyMockPackageCount; 161a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ComponentName cn = new ComponentName("com.android.test" + packageIndex, 162a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung "com.android.test" + i + ".Activity"); 163a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung String description = "" + i + " - " + 164a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung Long.toString(Math.abs(new Random().nextLong()), 36); 165a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // Create the recent task info 166a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 167a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung rti.id = rti.persistentId = i; 168a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung rti.baseIntent = new Intent(); 169a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung rti.baseIntent.setComponent(cn); 170a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung rti.description = description; 171ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung rti.firstActiveTime = rti.lastActiveTime = i; 1725e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung if (i % 2 == 0) { 173a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung rti.taskDescription = new ActivityManager.TaskDescription(description, 17410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung Bitmap.createBitmap(mDummyIcon), 17510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung 0xFF000000 | (0xFFFFFF & new Random().nextInt())); 176a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung } else { 177a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung rti.taskDescription = new ActivityManager.TaskDescription(); 1785e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung } 179a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung tasks.add(rti); 180a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 181a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return tasks; 182a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 183a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 184918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // Remove home/recents/excluded tasks 185918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung int minNumTasksToQuery = 10; 186918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks); 187918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung List<ActivityManager.RecentTaskInfo> tasks = mAm.getRecentTasksForUser(numTasksToQuery, 188a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS | 189a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ActivityManager.RECENT_IGNORE_UNAVAILABLE | 190918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung ActivityManager.RECENT_INCLUDE_PROFILES | 191918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung ActivityManager.RECENT_WITH_EXCLUDED, userId); 1924298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung 1934298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung // Break early if we can't get a valid set of tasks 1944298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung if (tasks == null) { 1954298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung return new ArrayList<ActivityManager.RecentTaskInfo>(); 1964298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung } 1974298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung 198918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung boolean isFirstValidTask = true; 199918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator(); 200918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung while (iter.hasNext()) { 201918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung ActivityManager.RecentTaskInfo t = iter.next(); 202918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung 203918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // NOTE: The order of these checks happens in the expected order of the traversal of the 204918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // tasks 205918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung 206918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // Check the first non-recents task, include this task even if it is marked as excluded 2079cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung // from recents if we are currently in the app. In other words, only remove excluded 2089cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung // tasks if it is not the first active task. 209918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung boolean isExcluded = (t.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 210918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung == Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; 2119cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung if (isExcluded && (isTopTaskHome || !isFirstValidTask)) { 212918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung iter.remove(); 213918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung continue; 214918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung } 215918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung isFirstValidTask = false; 216918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung } 217918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung 218918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung return tasks.subList(0, Math.min(tasks.size(), numLatestTasks)); 219a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 220a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 221a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns a list of the running tasks */ 2222cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung private List<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) { 223a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return null; 224a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return mAm.getRunningTasks(numTasks); 225a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 226a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 2272cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung /** Returns the top task. */ 2282cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung public ActivityManager.RunningTaskInfo getTopMostTask() { 2292cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung List<ActivityManager.RunningTaskInfo> tasks = getRunningTasks(1); 23065c294036bd3a01af0755519d37ef7e9f64b9fb9Winson Chung if (tasks != null && !tasks.isEmpty()) { 2312cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return tasks.get(0); 2322cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2332cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return null; 2342cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2352cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 2362cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung /** Returns whether the recents is currently running */ 2372cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask, 2382cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung AtomicBoolean isHomeTopMost) { 2392cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (topTask != null) { 2402cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung ComponentName topActivity = topTask.topActivity; 2412cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 2422cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung // Check if the front most activity is recents 2432cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (topActivity.getPackageName().equals(Recents.sRecentsPackage) && 2442cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung topActivity.getClassName().equals(Recents.sRecentsActivity)) { 2452cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (isHomeTopMost != null) { 2462cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung isHomeTopMost.set(false); 2472cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2482cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return true; 2492cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2502cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 2512cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (isHomeTopMost != null) { 2522cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung isHomeTopMost.set(isInHomeStack(topTask.id)); 2532cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2542cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2552cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return false; 2562cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2572cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 258ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne /** Get the bounds of a stack / task. */ 259ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne public Rect getTaskBounds(int stackId) { 260ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne ActivityManager.StackInfo info = getAllStackInfos().get(stackId); 261ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne if (info != null) 2628aa7d161a11965cd75eace74e1bcf15421bbea18Skuhne return info.bounds; 263ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne return new Rect(); 264d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 265d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 266ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne /** Resize a given task. */ 267ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne public void resizeTask(int taskId, Rect bounds) { 268d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung if (mIam == null) return; 269d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 270d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung try { 271ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne mIam.resizeTask(taskId, bounds); 272d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } catch (RemoteException e) { 273d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung e.printStackTrace(); 274d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 275d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 276d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 277d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** Returns the stack info for all stacks. */ 278d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung public SparseArray<ActivityManager.StackInfo> getAllStackInfos() { 279d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung if (mIam == null) return new SparseArray<ActivityManager.StackInfo>(); 280d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 281d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung try { 282d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung SparseArray<ActivityManager.StackInfo> stacks = 283d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung new SparseArray<ActivityManager.StackInfo>(); 284d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung List<ActivityManager.StackInfo> infos = mIam.getAllStackInfos(); 285d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung int stackCount = infos.size(); 286d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung for (int i = 0; i < stackCount; i++) { 287d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung ActivityManager.StackInfo info = infos.get(i); 288d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung stacks.put(info.stackId, info); 289d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 290d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return stacks; 291d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } catch (RemoteException e) { 292d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung e.printStackTrace(); 293d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return new SparseArray<ActivityManager.StackInfo>(); 294d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 295d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 296d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 297d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** Returns the focused stack id. */ 298d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung public int getFocusedStack() { 299d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung if (mIam == null) return -1; 300d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 301d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung try { 302d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return mIam.getFocusedStackId(); 303d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } catch (RemoteException e) { 304d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung e.printStackTrace(); 305d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return -1; 306d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 307d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 308d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 309a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns whether the specified task is in the home stack */ 310a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public boolean isInHomeStack(int taskId) { 311a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return false; 312a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 313a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then just return false 314a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 315a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return false; 316a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 317a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 318a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return mAm.isInHomeStack(taskId); 319a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 320a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 321a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns the top task thumbnail for the given task id */ 322a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public Bitmap getTaskThumbnail(int taskId) { 323a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return null; 324a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 325a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then just return a dummy thumbnail 326a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 32785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight, 32885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung Bitmap.Config.ARGB_8888); 3296736905dc0e10689f7c63f6da43b31325caf966aWinson Chung thumbnail.eraseColor(0xff333333); 330a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return thumbnail; 331a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 332a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 333ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Bitmap thumbnail = SystemServicesProxy.getThumbnail(mAm, taskId); 334b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung if (thumbnail != null) { 335a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung thumbnail.setHasAlpha(false); 336b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top 337b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // left pixel, then assume the whole thumbnail is transparent. Generally, proper 338b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // screenshots are always composed onto a bitmap that has no alpha. 339b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung if (Color.alpha(thumbnail.getPixel(0, 0)) == 0) { 340b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas.setBitmap(thumbnail); 341b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas.drawRect(0, 0, thumbnail.getWidth(), thumbnail.getHeight(), 342b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint); 343b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas.setBitmap(null); 344b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung Log.e(TAG, "Invalid screenshot detected from getTaskThumbnail()"); 345b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung } 346b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung } 347b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung return thumbnail; 348a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 349a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 350ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 351ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Returns a task thumbnail from the activity manager 352ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 353ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public static Bitmap getThumbnail(ActivityManager activityManager, int taskId) { 354ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ActivityManager.TaskThumbnail taskThumbnail = activityManager.getTaskThumbnail(taskId); 35585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (taskThumbnail == null) return null; 35685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 357ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Bitmap thumbnail = taskThumbnail.mainThumbnail; 358ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ParcelFileDescriptor descriptor = taskThumbnail.thumbnailFileDescriptor; 359ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (thumbnail == null && descriptor != null) { 360aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn thumbnail = BitmapFactory.decodeFileDescriptor(descriptor.getFileDescriptor(), 361aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn null, sBitmapOptions); 362ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 363ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (descriptor != null) { 364ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung try { 365ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung descriptor.close(); 366ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } catch (IOException e) { 367ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 368ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 369ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return thumbnail; 370ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 371ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 372d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** Moves a task to the front with the specified activity options. */ 373a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public void moveTaskToFront(int taskId, ActivityOptions opts) { 374a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return; 375a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return; 376a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 377a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (opts != null) { 378a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME, 379a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung opts.toBundle()); 380a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } else { 381a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME); 382a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 383a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 384a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 385d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale /** Removes the task */ 386d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale public void removeTask(int taskId) { 387a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return; 388a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return; 389a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 390d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale // Remove the task. 391d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale mAm.removeTask(taskId); 392a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 393a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 3944f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani /** 3954f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * Returns the activity info for a given component name. 396d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale * 397f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * @param cn The component name of the activity. 3984f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * @param userId The userId of the user that this is for. 3994f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani */ 4004f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani public ActivityInfo getActivityInfo(ComponentName cn, int userId) { 4014f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani if (mIpm == null) return null; 402814086db674d8eb298541b7e601e29c5c68e2074Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo(); 403a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 404a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung try { 4054f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani return mIpm.getActivityInfo(cn, PackageManager.GET_META_DATA, userId); 4064f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani } catch (RemoteException e) { 407a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung e.printStackTrace(); 408a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return null; 409a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 410a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 411a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 412f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** 413f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * Returns the activity info for a given component name. 414f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * 415f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * @param cn The component name of the activity. 416f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung */ 417f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung public ActivityInfo getActivityInfo(ComponentName cn) { 418f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (mPm == null) return null; 419814086db674d8eb298541b7e601e29c5c68e2074Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo(); 420f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 421f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung try { 422f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA); 423f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } catch (PackageManager.NameNotFoundException e) { 424f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung e.printStackTrace(); 425f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return null; 426f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 427f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 428f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 429a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns the activity label */ 430a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public String getActivityLabel(ActivityInfo info) { 431a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mPm == null) return null; 432a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 433a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then return a mock label 434a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 435a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return "Recent Task"; 436a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 437a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 438a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return info.loadLabel(mPm).toString(); 439a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 440a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 441b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz /** Returns the application label */ 442b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz public String getApplicationLabel(Intent baseIntent, int userId) { 443b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (mPm == null) return null; 444b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 445b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz // If we are mocking, then return a mock label 446b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 447b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return "Recent Task"; 448b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 449b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 450b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz ResolveInfo ri = mPm.resolveActivityAsUser(baseIntent, 0, userId); 451b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz CharSequence label = (ri != null) ? ri.loadLabel(mPm) : null; 452b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return (label != null) ? label.toString() : null; 453b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 454b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 455b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz /** Returns the content description for a given task */ 456b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz public String getContentDescription(Intent baseIntent, int userId, String activityLabel, 457b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz Resources res) { 458b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz String applicationLabel = getApplicationLabel(baseIntent, userId); 459b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (applicationLabel == null) { 460b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return getBadgedLabel(activityLabel, userId); 461b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 462b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId); 463b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return applicationLabel.equals(activityLabel) ? badgedApplicationLabel 464b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz : res.getString(R.string.accessibility_recents_task_header, 465b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz badgedApplicationLabel, activityLabel); 466b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 467b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 4684f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani /** 4694f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * Returns the activity icon for the ActivityInfo for a user, badging if 4704f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * necessary. 4714f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani */ 4724f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani public Drawable getActivityIcon(ActivityInfo info, int userId) { 473c7d62f02b8acfd0a6b31f8544ec2c07e780fe4bbSvetoslav if (mPm == null) return null; 474a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 475a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then return a mock label 476a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 4772f2ca08baa072376b3dfd60506625496aa05903fWinson Chung return new ColorDrawable(0xFF666666); 478a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 479a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 4804f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani Drawable icon = info.loadIcon(mPm); 4816507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee return getBadgedIcon(icon, userId); 4826507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee } 4836507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee 4846507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee /** 4856507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee * Returns the given icon for a user, badging if necessary. 4866507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee */ 4876507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee public Drawable getBadgedIcon(Drawable icon, int userId) { 4884f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani if (userId != UserHandle.myUserId()) { 489fdf169cbea5c59c6f74c25c6c529d8a19c6cb78cAmith Yamasani icon = mPm.getUserBadgedIcon(icon, new UserHandle(userId)); 4904f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani } 4914f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani return icon; 492a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 493ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung 494b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz /** 495b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz * Returns the given label for a user, badging if necessary. 496b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz */ 497b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz public String getBadgedLabel(String label, int userId) { 498b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (userId != UserHandle.myUserId()) { 499b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz label = mPm.getUserBadgedLabel(label, new UserHandle(userId)).toString(); 500b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 501b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return label; 502b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 503b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 504bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung /** Returns the package name of the home activity. */ 505bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung public String getHomeActivityPackageName() { 506bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (mPm == null) return null; 507bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return null; 508bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 509bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); 510bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung ComponentName defaultHomeActivity = mPm.getHomeActivities(homeActivities); 511bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (defaultHomeActivity != null) { 512bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return defaultHomeActivity.getPackageName(); 513bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } else if (homeActivities.size() == 1) { 514bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung ResolveInfo info = homeActivities.get(0); 515bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (info.activityInfo != null) { 516bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return info.activityInfo.packageName; 517bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 518bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 519bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return null; 520bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 521bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 5222002cf5b463737e7f615f1469cb20d324c283544Winson Chung /** 5232002cf5b463737e7f615f1469cb20d324c283544Winson Chung * Returns whether the foreground user is the owner. 5242002cf5b463737e7f615f1469cb20d324c283544Winson Chung */ 5252002cf5b463737e7f615f1469cb20d324c283544Winson Chung public boolean isForegroundUserOwner() { 5262002cf5b463737e7f615f1469cb20d324c283544Winson Chung if (mAm == null) return false; 5272002cf5b463737e7f615f1469cb20d324c283544Winson Chung 5282002cf5b463737e7f615f1469cb20d324c283544Winson Chung return mAm.getCurrentUser() == UserHandle.USER_OWNER; 5292002cf5b463737e7f615f1469cb20d324c283544Winson Chung } 5302002cf5b463737e7f615f1469cb20d324c283544Winson Chung 531ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung /** 532bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung * Resolves and returns the first Recents widget from the same package as the global 533bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung * assist activity. 534ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung */ 535bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung public AppWidgetProviderInfo resolveSearchAppWidget() { 536f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (mAwm == null) return null; 537da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung if (mAssistComponent == null) return null; 538ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung 539da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung // Find the first Recents widget from the same package as the global assist activity 540da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung List<AppWidgetProviderInfo> widgets = mAwm.getInstalledProviders( 541ee0b12161ab8563378e33e9d694d15ed1a757a26Winson Chung AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX); 542f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung for (AppWidgetProviderInfo info : widgets) { 543da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung if (info.provider.getPackageName().equals(mAssistComponent.getPackageName())) { 544bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return info; 545f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 546f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 547bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return null; 548bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 549bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 550bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung /** 551bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung * Resolves and binds the search app widget that is to appear in the recents. 552bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung */ 553bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung public Pair<Integer, AppWidgetProviderInfo> bindSearchAppWidget(AppWidgetHost host) { 554bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (mAwm == null) return null; 555bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (mAssistComponent == null) return null; 556bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 557bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung // Find the first Recents widget from the same package as the global assist activity 558bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung AppWidgetProviderInfo searchWidgetInfo = resolveSearchAppWidget(); 559f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 560f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Return early if there is no search widget 561f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (searchWidgetInfo == null) return null; 562f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 563f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Allocate a new widget id and try and bind the app widget (if that fails, then just skip) 564f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung int searchWidgetId = host.allocateAppWidgetId(); 565f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung Bundle opts = new Bundle(); 566f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, 567ee0b12161ab8563378e33e9d694d15ed1a757a26Winson Chung AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX); 568f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, searchWidgetInfo.provider, opts)) { 569044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung host.deleteAppWidgetId(searchWidgetId); 570f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return null; 571f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 572f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return new Pair<Integer, AppWidgetProviderInfo>(searchWidgetId, searchWidgetInfo); 573f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 574f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 575f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** 576f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * Returns the app widget info for the specified app widget id. 577f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung */ 578f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) { 579f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (mAwm == null) return null; 580f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 581f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return mAwm.getAppWidgetInfo(appWidgetId); 582f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 583f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 584f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** 585f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * Destroys the specified app widget. 586f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung */ 587f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung public void unbindSearchAppWidget(AppWidgetHost host, int appWidgetId) { 588f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (mAwm == null) return; 589f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 590f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Delete the app widget 591f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung host.deleteAppWidgetId(appWidgetId); 592ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung } 593d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung 594d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung /** 595ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung * Returns whether touch exploration is currently enabled. 596ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung */ 597ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung public boolean isTouchExplorationEnabled() { 598ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung if (mAccm == null) return false; 599ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung 600ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung return mAccm.isEnabled() && mAccm.isTouchExplorationEnabled(); 601ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung } 602ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung 603ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung /** 60456e09b42a0f1670970872bef611a8036904ad6bfJason Monk * Returns a global setting. 60556e09b42a0f1670970872bef611a8036904ad6bfJason Monk */ 60656e09b42a0f1670970872bef611a8036904ad6bfJason Monk public int getGlobalSetting(Context context, String setting) { 60756e09b42a0f1670970872bef611a8036904ad6bfJason Monk ContentResolver cr = context.getContentResolver(); 60856e09b42a0f1670970872bef611a8036904ad6bfJason Monk return Settings.Global.getInt(cr, setting, 0); 60956e09b42a0f1670970872bef611a8036904ad6bfJason Monk } 61056e09b42a0f1670970872bef611a8036904ad6bfJason Monk 61156e09b42a0f1670970872bef611a8036904ad6bfJason Monk /** 61256e09b42a0f1670970872bef611a8036904ad6bfJason Monk * Returns a system setting. 61356e09b42a0f1670970872bef611a8036904ad6bfJason Monk */ 61456e09b42a0f1670970872bef611a8036904ad6bfJason Monk public int getSystemSetting(Context context, String setting) { 61556e09b42a0f1670970872bef611a8036904ad6bfJason Monk ContentResolver cr = context.getContentResolver(); 61656e09b42a0f1670970872bef611a8036904ad6bfJason Monk return Settings.System.getInt(cr, setting, 0); 61756e09b42a0f1670970872bef611a8036904ad6bfJason Monk } 61856e09b42a0f1670970872bef611a8036904ad6bfJason Monk 61956e09b42a0f1670970872bef611a8036904ad6bfJason Monk /** 620d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung * Returns a system property. 621d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung */ 622d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung public String getSystemProperty(String key) { 623d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return SystemProperties.get(key); 624d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 625d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 626d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** 627ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Returns the window rect. 628ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 629ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public Rect getWindowRect() { 630ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Rect windowRect = new Rect(); 631ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (mWm == null) return windowRect; 632ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 633dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung Point p = new Point(); 634dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mWm.getDefaultDisplay().getRealSize(p); 635dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung windowRect.set(0, 0, p.x, p.y); 636ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return windowRect; 637ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 638ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 639ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 640d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung * Takes a screenshot of the current surface. 641d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung */ 642d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung public Bitmap takeScreenshot() { 643d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung DisplayInfo di = new DisplayInfo(); 644d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mDisplay.getDisplayInfo(di); 645d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung return SurfaceControl.screenshot(di.getNaturalWidth(), di.getNaturalHeight()); 646d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung } 647ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 648ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 649ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Takes a screenshot of the current app. 650ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 651ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public Bitmap takeAppScreenshot() { 652ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return takeScreenshot(); 653ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 654dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner 6554e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung /** Starts an activity from recents. */ 6564e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung public boolean startActivityFromRecents(Context context, int taskId, String taskName, 6574e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung ActivityOptions options) { 658dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner if (mIam != null) { 659dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner try { 660dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner mIam.startActivityFromRecents(taskId, options == null ? null : options.toBundle()); 6614e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung return true; 6624e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung } catch (Exception e) { 6634e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung Console.logError(context, 6644e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung context.getString(R.string.recents_launch_error_message, taskName)); 665dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner } 666dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner } 6674e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung return false; 668dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner } 669044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung 670044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung /** Starts an in-place animation on the front most application windows. */ 671044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) { 672044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung if (mIam == null) return; 673044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung 674044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung try { 675044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung mIam.startInPlaceAnimationOnFrontMostApplication(opts); 676044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung } catch (Exception e) { 677044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung e.printStackTrace(); 678044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung } 679044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung } 680740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung 681740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung /** Registers a task stack listener with the system. */ 682740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung public void registerTaskStackListener(ITaskStackListener listener) { 683740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung if (mIam == null) return; 684740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung 685740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung try { 686740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung mIam.registerTaskStackListener(listener); 687740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung } catch (Exception e) { 688740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung e.printStackTrace(); 689740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung } 690740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung } 691a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung} 692