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; 51c35e670d5386eb6388eb4e65746b950265312e7aWinson Chungimport android.os.Handler; 52c35e670d5386eb6388eb4e65746b950265312e7aWinson Chungimport android.os.HandlerThread; 53ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport android.os.ParcelFileDescriptor; 544f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.os.RemoteException; 55d16c565a607de754379fe699a4def21bd0e3de2fWinson Chungimport android.os.SystemProperties; 564f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.os.UserHandle; 57165ce066b701ba0153000f0692bfc7032655d17dJorim Jaggiimport android.os.UserManager; 5856e09b42a0f1670970872bef611a8036904ad6bfJason Monkimport android.provider.Settings; 59b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.util.Log; 60e1e20e11a758ee82753e8052773664823ca74746Winson Chungimport android.util.MutableBoolean; 61f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.util.Pair; 62d16c565a607de754379fe699a4def21bd0e3de2fWinson Chungimport android.util.SparseArray; 63d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.Display; 64d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.DisplayInfo; 65d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.SurfaceControl; 66d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.WindowManager; 67ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chungimport android.view.accessibility.AccessibilityManager; 68165ce066b701ba0153000f0692bfc7032655d17dJorim Jaggi 69165ce066b701ba0153000f0692bfc7032655d17dJorim Jaggiimport com.android.internal.app.AssistUtils; 70af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chungimport com.android.systemui.Prefs; 714e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chungimport com.android.systemui.R; 72ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.Constants; 732cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chungimport com.android.systemui.recents.Recents; 74af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chungimport com.android.systemui.recents.RecentsAppWidgetHost; 75a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 76ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.io.IOException; 77a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport java.util.ArrayList; 78918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chungimport java.util.Iterator; 79a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport java.util.List; 805e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chungimport java.util.Random; 81a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 82a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung/** 83a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * Acts as a shim around the real system services that we need to access data from, and provides 84a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * a point of injection when testing UI. 85a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung */ 86a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungpublic class SystemServicesProxy { 87b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung final static String TAG = "SystemServicesProxy"; 88b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung 89aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn final static BitmapFactory.Options sBitmapOptions; 90c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung final static HandlerThread sBgThread; 91c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung 92c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung static { 93c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung sBgThread = new HandlerThread("Recents-SystemServicesProxy", 94c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung android.os.Process.THREAD_PRIORITY_BACKGROUND); 95c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung sBgThread.start(); 96c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung sBitmapOptions = new BitmapFactory.Options(); 97c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung sBitmapOptions.inMutable = true; 98c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung } 99aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn 100ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung AccessibilityManager mAccm; 101a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ActivityManager mAm; 1021f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung IActivityManager mIam; 103f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung AppWidgetManager mAwm; 104a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung PackageManager mPm; 1054f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani IPackageManager mIpm; 106165ce066b701ba0153000f0692bfc7032655d17dJorim Jaggi AssistUtils mAssistUtils; 107d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung WindowManager mWm; 108d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung Display mDisplay; 109918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung String mRecentsPackage; 110da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung ComponentName mAssistComponent; 111a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 112c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung Handler mBgThreadHandler; 113c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung 114a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung Bitmap mDummyIcon; 11585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int mDummyThumbnailWidth; 11685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int mDummyThumbnailHeight; 117b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung Paint mBgProtectionPaint; 118b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung Canvas mBgProtectionCanvas; 119a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 120a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Private constructor */ 121a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public SystemServicesProxy(Context context) { 122ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung mAccm = AccessibilityManager.getInstance(context); 123a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 1241f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung mIam = ActivityManagerNative.getDefault(); 125f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mAwm = AppWidgetManager.getInstance(context); 126a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mPm = context.getPackageManager(); 1274f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani mIpm = AppGlobals.getPackageManager(); 128165ce066b701ba0153000f0692bfc7032655d17dJorim Jaggi mAssistUtils = new AssistUtils(context); 129d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 130d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mDisplay = mWm.getDefaultDisplay(); 131918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung mRecentsPackage = context.getPackageName(); 132c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung mBgThreadHandler = new Handler(sBgThread.getLooper()); 133a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 13485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Get the dummy thumbnail width/heights 13585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung Resources res = context.getResources(); 13685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int wId = com.android.internal.R.dimen.thumbnail_width; 13785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung int hId = com.android.internal.R.dimen.thumbnail_height; 13885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mDummyThumbnailWidth = res.getDimensionPixelSize(wId); 13985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mDummyThumbnailHeight = res.getDimensionPixelSize(hId); 14085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 141b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // Create the protection paints 142b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint = new Paint(); 143b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)); 144b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint.setColor(0xFFffffff); 145b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas = new Canvas(); 146b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung 147da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung // Resolve the assist intent 148165ce066b701ba0153000f0692bfc7032655d17dJorim Jaggi mAssistComponent = mAssistUtils.getAssistComponentForUser(UserHandle.myUserId()); 149da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung 150a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 151a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // Create a dummy icon 1522f2ca08baa072376b3dfd60506625496aa05903fWinson Chung mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); 1536736905dc0e10689f7c63f6da43b31325caf966aWinson Chung mDummyIcon.eraseColor(0xFF999999); 154a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 155a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 156a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 157a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns a list of the recents tasks */ 1589cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId, 1599cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung boolean isTopTaskHome) { 160a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return null; 161a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 162a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then create some recent tasks 163a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 164a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ArrayList<ActivityManager.RecentTaskInfo> tasks = 165a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung new ArrayList<ActivityManager.RecentTaskInfo>(); 166918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung int count = Math.min(numLatestTasks, Constants.DebugFlags.App.SystemServicesProxyMockTaskCount); 167a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung for (int i = 0; i < count; i++) { 168a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // Create a dummy component name 169a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung int packageIndex = i % Constants.DebugFlags.App.SystemServicesProxyMockPackageCount; 170a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ComponentName cn = new ComponentName("com.android.test" + packageIndex, 171a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung "com.android.test" + i + ".Activity"); 172a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung String description = "" + i + " - " + 173a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung Long.toString(Math.abs(new Random().nextLong()), 36); 174a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // Create the recent task info 175a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 176a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung rti.id = rti.persistentId = i; 177a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung rti.baseIntent = new Intent(); 178a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung rti.baseIntent.setComponent(cn); 179a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung rti.description = description; 180ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung rti.firstActiveTime = rti.lastActiveTime = i; 1815e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung if (i % 2 == 0) { 182a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung rti.taskDescription = new ActivityManager.TaskDescription(description, 18310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung Bitmap.createBitmap(mDummyIcon), 18410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung 0xFF000000 | (0xFFFFFF & new Random().nextInt())); 185a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung } else { 186a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung rti.taskDescription = new ActivityManager.TaskDescription(); 1875e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung } 188a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung tasks.add(rti); 189a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 190a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return tasks; 191a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 192a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 193918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // Remove home/recents/excluded tasks 194918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung int minNumTasksToQuery = 10; 195918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks); 196918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung List<ActivityManager.RecentTaskInfo> tasks = mAm.getRecentTasksForUser(numTasksToQuery, 197a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS | 198a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung ActivityManager.RECENT_IGNORE_UNAVAILABLE | 199918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung ActivityManager.RECENT_INCLUDE_PROFILES | 200918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung ActivityManager.RECENT_WITH_EXCLUDED, userId); 2014298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung 2024298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung // Break early if we can't get a valid set of tasks 2034298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung if (tasks == null) { 204e1e20e11a758ee82753e8052773664823ca74746Winson Chung return new ArrayList<>(); 2054298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung } 2064298b43592966b9b620866bb3da1ab3f9ed2e668Winson Chung 207918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung boolean isFirstValidTask = true; 208918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator(); 209918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung while (iter.hasNext()) { 210918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung ActivityManager.RecentTaskInfo t = iter.next(); 211918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung 212918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // NOTE: The order of these checks happens in the expected order of the traversal of the 213918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // tasks 214918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung 215918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung // Check the first non-recents task, include this task even if it is marked as excluded 2169cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung // from recents if we are currently in the app. In other words, only remove excluded 2179cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung // tasks if it is not the first active task. 218918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung boolean isExcluded = (t.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 219918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung == Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; 2209cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung if (isExcluded && (isTopTaskHome || !isFirstValidTask)) { 221918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung iter.remove(); 222918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung continue; 223918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung } 224918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung isFirstValidTask = false; 225918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung } 226918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung 227918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung return tasks.subList(0, Math.min(tasks.size(), numLatestTasks)); 228a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 229a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 230a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns a list of the running tasks */ 2312cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung private List<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) { 232a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return null; 233a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return mAm.getRunningTasks(numTasks); 234a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 235a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 2362cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung /** Returns the top task. */ 2372cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung public ActivityManager.RunningTaskInfo getTopMostTask() { 2382cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung List<ActivityManager.RunningTaskInfo> tasks = getRunningTasks(1); 23965c294036bd3a01af0755519d37ef7e9f64b9fb9Winson Chung if (tasks != null && !tasks.isEmpty()) { 2402cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return tasks.get(0); 2412cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2422cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return null; 2432cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2442cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 2452cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung /** Returns whether the recents is currently running */ 2462cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask, 247e1e20e11a758ee82753e8052773664823ca74746Winson Chung MutableBoolean isHomeTopMost) { 2482cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (topTask != null) { 2492cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung ComponentName topActivity = topTask.topActivity; 2502cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 2512cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung // Check if the front most activity is recents 2522cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (topActivity.getPackageName().equals(Recents.sRecentsPackage) && 2532cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung topActivity.getClassName().equals(Recents.sRecentsActivity)) { 2542cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (isHomeTopMost != null) { 255e1e20e11a758ee82753e8052773664823ca74746Winson Chung isHomeTopMost.value = false; 2562cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2572cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return true; 2582cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2592cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 2602cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung if (isHomeTopMost != null) { 261e1e20e11a758ee82753e8052773664823ca74746Winson Chung isHomeTopMost.value = isInHomeStack(topTask.id); 2622cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2632cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2642cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung return false; 2652cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung } 2662cf8b221fca18dbee3703388ae7970491c86ec7fWinson Chung 267ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne /** Get the bounds of a stack / task. */ 268ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne public Rect getTaskBounds(int stackId) { 269ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne ActivityManager.StackInfo info = getAllStackInfos().get(stackId); 270ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne if (info != null) 2718aa7d161a11965cd75eace74e1bcf15421bbea18Skuhne return info.bounds; 272ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne return new Rect(); 273d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 274d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 275ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne /** Resize a given task. */ 276ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne public void resizeTask(int taskId, Rect bounds) { 277d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung if (mIam == null) return; 278d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 279d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung try { 280ece738b5bc532d90bbdc42d0b5b63701c773a6f9Skuhne mIam.resizeTask(taskId, bounds); 281d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } catch (RemoteException e) { 282d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung e.printStackTrace(); 283d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 284d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 285d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 286d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** Returns the stack info for all stacks. */ 287d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung public SparseArray<ActivityManager.StackInfo> getAllStackInfos() { 288d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung if (mIam == null) return new SparseArray<ActivityManager.StackInfo>(); 289d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 290d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung try { 291d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung SparseArray<ActivityManager.StackInfo> stacks = 292d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung new SparseArray<ActivityManager.StackInfo>(); 293d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung List<ActivityManager.StackInfo> infos = mIam.getAllStackInfos(); 294d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung int stackCount = infos.size(); 295d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung for (int i = 0; i < stackCount; i++) { 296d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung ActivityManager.StackInfo info = infos.get(i); 297d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung stacks.put(info.stackId, info); 298d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 299d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return stacks; 300d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } catch (RemoteException e) { 301d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung e.printStackTrace(); 302d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return new SparseArray<ActivityManager.StackInfo>(); 303d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 304d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 305d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 306d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** Returns the focused stack id. */ 307d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung public int getFocusedStack() { 308d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung if (mIam == null) return -1; 309d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 310d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung try { 311d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return mIam.getFocusedStackId(); 312d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } catch (RemoteException e) { 313d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung e.printStackTrace(); 314d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return -1; 315d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 316d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 317d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 318a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns whether the specified task is in the home stack */ 319a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public boolean isInHomeStack(int taskId) { 320a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return false; 321a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 322a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then just return false 323a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 324a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return false; 325a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 326a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 327a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return mAm.isInHomeStack(taskId); 328a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 329a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 330a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns the top task thumbnail for the given task id */ 331a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public Bitmap getTaskThumbnail(int taskId) { 332a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return null; 333a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 334a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then just return a dummy thumbnail 335a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 33685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight, 33785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung Bitmap.Config.ARGB_8888); 3386736905dc0e10689f7c63f6da43b31325caf966aWinson Chung thumbnail.eraseColor(0xff333333); 339a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return thumbnail; 340a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 341a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 342ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Bitmap thumbnail = SystemServicesProxy.getThumbnail(mAm, taskId); 343b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung if (thumbnail != null) { 344a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung thumbnail.setHasAlpha(false); 345b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top 346b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // left pixel, then assume the whole thumbnail is transparent. Generally, proper 347b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung // screenshots are always composed onto a bitmap that has no alpha. 348b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung if (Color.alpha(thumbnail.getPixel(0, 0)) == 0) { 349b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas.setBitmap(thumbnail); 350b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas.drawRect(0, 0, thumbnail.getWidth(), thumbnail.getHeight(), 351b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionPaint); 352b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung mBgProtectionCanvas.setBitmap(null); 353b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung Log.e(TAG, "Invalid screenshot detected from getTaskThumbnail()"); 354b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung } 355b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung } 356b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung return thumbnail; 357a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 358a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 359ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 360ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Returns a task thumbnail from the activity manager 361ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 362ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public static Bitmap getThumbnail(ActivityManager activityManager, int taskId) { 363ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ActivityManager.TaskThumbnail taskThumbnail = activityManager.getTaskThumbnail(taskId); 36485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (taskThumbnail == null) return null; 36585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 366ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Bitmap thumbnail = taskThumbnail.mainThumbnail; 367ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ParcelFileDescriptor descriptor = taskThumbnail.thumbnailFileDescriptor; 368ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (thumbnail == null && descriptor != null) { 369aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn thumbnail = BitmapFactory.decodeFileDescriptor(descriptor.getFileDescriptor(), 370aec68bb89fe614181a20eb97340149406218ce2fDianne Hackborn null, sBitmapOptions); 371ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 372ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (descriptor != null) { 373ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung try { 374ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung descriptor.close(); 375ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } catch (IOException e) { 376ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 377ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 378ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return thumbnail; 379ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 380ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 381d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** Moves a task to the front with the specified activity options. */ 382a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public void moveTaskToFront(int taskId, ActivityOptions opts) { 383a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return; 384a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return; 385a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 386a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (opts != null) { 387a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME, 388a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung opts.toBundle()); 389a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } else { 390a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME); 391a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 392a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 393a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 394d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale /** Removes the task */ 395c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung public void removeTask(final int taskId) { 396a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mAm == null) return; 397a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return; 398a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 399d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale // Remove the task. 400c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung mBgThreadHandler.post(new Runnable() { 401c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung @Override 402c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung public void run() { 403c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung mAm.removeTask(taskId); 404c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung } 405c35e670d5386eb6388eb4e65746b950265312e7aWinson Chung }); 406a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 407a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 4084f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani /** 4094f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * Returns the activity info for a given component name. 410d54b578e47fb410c776bb3a4272c2c523153f657Wale Ogunwale * 411f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * @param cn The component name of the activity. 4124f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * @param userId The userId of the user that this is for. 4134f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani */ 4144f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani public ActivityInfo getActivityInfo(ComponentName cn, int userId) { 4154f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani if (mIpm == null) return null; 416814086db674d8eb298541b7e601e29c5c68e2074Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo(); 417a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 418a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung try { 4194f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani return mIpm.getActivityInfo(cn, PackageManager.GET_META_DATA, userId); 4204f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani } catch (RemoteException e) { 421a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung e.printStackTrace(); 422a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return null; 423a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 424a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 425a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 426f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** 427f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * Returns the activity info for a given component name. 428f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * 429f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * @param cn The component name of the activity. 430f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung */ 431f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung public ActivityInfo getActivityInfo(ComponentName cn) { 432f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (mPm == null) return null; 433814086db674d8eb298541b7e601e29c5c68e2074Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo(); 434f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 435f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung try { 436f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA); 437f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } catch (PackageManager.NameNotFoundException e) { 438f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung e.printStackTrace(); 439f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return null; 440f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 441f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 442f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 443a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung /** Returns the activity label */ 444a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung public String getActivityLabel(ActivityInfo info) { 445a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (mPm == null) return null; 446a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 447a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then return a mock label 448a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 449a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return "Recent Task"; 450a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 451a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 452a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung return info.loadLabel(mPm).toString(); 453a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 454a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 455b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz /** Returns the application label */ 456b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz public String getApplicationLabel(Intent baseIntent, int userId) { 457b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (mPm == null) return null; 458b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 459b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz // If we are mocking, then return a mock label 460b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 461b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return "Recent Task"; 462b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 463b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 464b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz ResolveInfo ri = mPm.resolveActivityAsUser(baseIntent, 0, userId); 465b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz CharSequence label = (ri != null) ? ri.loadLabel(mPm) : null; 466b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return (label != null) ? label.toString() : null; 467b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 468b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 469b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz /** Returns the content description for a given task */ 470b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz public String getContentDescription(Intent baseIntent, int userId, String activityLabel, 471b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz Resources res) { 472b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz String applicationLabel = getApplicationLabel(baseIntent, userId); 473b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (applicationLabel == null) { 474b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return getBadgedLabel(activityLabel, userId); 475b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 476b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId); 477b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return applicationLabel.equals(activityLabel) ? badgedApplicationLabel 478b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz : res.getString(R.string.accessibility_recents_task_header, 479b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz badgedApplicationLabel, activityLabel); 480b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 481b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 4824f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani /** 4834f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * Returns the activity icon for the ActivityInfo for a user, badging if 4844f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani * necessary. 4854f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani */ 4864f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani public Drawable getActivityIcon(ActivityInfo info, int userId) { 487c7d62f02b8acfd0a6b31f8544ec2c07e780fe4bbSvetoslav if (mPm == null) return null; 488a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 489a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung // If we are mocking, then return a mock label 490a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) { 4912f2ca08baa072376b3dfd60506625496aa05903fWinson Chung return new ColorDrawable(0xFF666666); 492a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 493a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung 4944f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani Drawable icon = info.loadIcon(mPm); 4956507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee return getBadgedIcon(icon, userId); 4966507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee } 4976507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee 4986507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee /** 4996507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee * Returns the given icon for a user, badging if necessary. 5006507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee */ 5016507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee public Drawable getBadgedIcon(Drawable icon, int userId) { 5024f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani if (userId != UserHandle.myUserId()) { 503fdf169cbea5c59c6f74c25c6c529d8a19c6cb78cAmith Yamasani icon = mPm.getUserBadgedIcon(icon, new UserHandle(userId)); 5044f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani } 5054f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani return icon; 506a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung } 507ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung 508b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz /** 509b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz * Returns the given label for a user, badging if necessary. 510b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz */ 511b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz public String getBadgedLabel(String label, int userId) { 512b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz if (userId != UserHandle.myUserId()) { 513b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz label = mPm.getUserBadgedLabel(label, new UserHandle(userId)).toString(); 514b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 515b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz return label; 516b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz } 517b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz 518bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung /** Returns the package name of the home activity. */ 519bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung public String getHomeActivityPackageName() { 520bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (mPm == null) return null; 521bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (Constants.DebugFlags.App.EnableSystemServicesProxy) return null; 522bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 523bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); 524bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung ComponentName defaultHomeActivity = mPm.getHomeActivities(homeActivities); 525bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (defaultHomeActivity != null) { 526bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return defaultHomeActivity.getPackageName(); 527bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } else if (homeActivities.size() == 1) { 528bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung ResolveInfo info = homeActivities.get(0); 529bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (info.activityInfo != null) { 530bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return info.activityInfo.packageName; 531bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 532bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 533bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return null; 534bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 535bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 5362002cf5b463737e7f615f1469cb20d324c283544Winson Chung /** 5372002cf5b463737e7f615f1469cb20d324c283544Winson Chung * Returns whether the foreground user is the owner. 5382002cf5b463737e7f615f1469cb20d324c283544Winson Chung */ 5392002cf5b463737e7f615f1469cb20d324c283544Winson Chung public boolean isForegroundUserOwner() { 5402002cf5b463737e7f615f1469cb20d324c283544Winson Chung if (mAm == null) return false; 5412002cf5b463737e7f615f1469cb20d324c283544Winson Chung 5422002cf5b463737e7f615f1469cb20d324c283544Winson Chung return mAm.getCurrentUser() == UserHandle.USER_OWNER; 5432002cf5b463737e7f615f1469cb20d324c283544Winson Chung } 5442002cf5b463737e7f615f1469cb20d324c283544Winson Chung 545ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung /** 546af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung * Returns the current search widget id. 547ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung */ 548af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung public int getSearchAppWidgetId(Context context) { 549af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung return Prefs.getInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID, -1); 550af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung } 551af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung 552af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung /** 553af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung * Returns the current search widget info, binding a new one if necessary. 554af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung */ 555af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung public AppWidgetProviderInfo getOrBindSearchAppWidget(Context context, AppWidgetHost host) { 556af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung int searchWidgetId = Prefs.getInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID, -1); 557af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung AppWidgetProviderInfo searchWidgetInfo = mAwm.getAppWidgetInfo(searchWidgetId); 558af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung AppWidgetProviderInfo resolvedSearchWidgetInfo = resolveSearchAppWidget(); 559af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung 560af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung // Return the search widget info if it hasn't changed 561af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung if (searchWidgetInfo != null && resolvedSearchWidgetInfo != null && 562af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung searchWidgetInfo.provider.equals(resolvedSearchWidgetInfo.provider)) { 563af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung if (Prefs.getString(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE, null) == null) { 564af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung Prefs.putString(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE, 565af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung searchWidgetInfo.provider.getPackageName()); 566af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung } 567af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung return searchWidgetInfo; 568af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung } 569af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung 570af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung // Delete the old widget 571af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung if (searchWidgetId != -1) { 572af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung host.deleteAppWidgetId(searchWidgetId); 573af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung } 574af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung 575af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung // And rebind a new search widget 576af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung if (resolvedSearchWidgetInfo != null) { 577af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung Pair<Integer, AppWidgetProviderInfo> widgetInfo = bindSearchAppWidget(host, 578af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung resolvedSearchWidgetInfo); 579af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung if (widgetInfo != null) { 580af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung Prefs.putInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID, widgetInfo.first); 581af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung Prefs.putString(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE, 582af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung widgetInfo.second.provider.getPackageName()); 583af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung return widgetInfo.second; 584af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung } 585af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung } 586af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung 587af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung // If we fall through here, then there is no resolved search widget, so clear the state 588af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung Prefs.remove(context, Prefs.Key.SEARCH_APP_WIDGET_ID); 589af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung Prefs.remove(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE); 590af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung return null; 591af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung } 592ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung 593af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung /** 594af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung * Returns the first Recents widget from the same package as the global assist activity. 595af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung */ 596af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung private AppWidgetProviderInfo resolveSearchAppWidget() { 597165ce066b701ba0153000f0692bfc7032655d17dJorim Jaggi if (mAssistComponent == null) return null; 598da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung List<AppWidgetProviderInfo> widgets = mAwm.getInstalledProviders( 599ee0b12161ab8563378e33e9d694d15ed1a757a26Winson Chung AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX); 600f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung for (AppWidgetProviderInfo info : widgets) { 601da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung if (info.provider.getPackageName().equals(mAssistComponent.getPackageName())) { 602bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return info; 603f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 604f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 605bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung return null; 606bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung } 607bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 608bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung /** 609bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung * Resolves and binds the search app widget that is to appear in the recents. 610bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung */ 611af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung private Pair<Integer, AppWidgetProviderInfo> bindSearchAppWidget(AppWidgetHost host, 612af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung AppWidgetProviderInfo resolvedSearchWidgetInfo) { 613bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (mAwm == null) return null; 614bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung if (mAssistComponent == null) return null; 615bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung 616f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Allocate a new widget id and try and bind the app widget (if that fails, then just skip) 617f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung int searchWidgetId = host.allocateAppWidgetId(); 618f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung Bundle opts = new Bundle(); 619f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, 620ee0b12161ab8563378e33e9d694d15ed1a757a26Winson Chung AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX); 621af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, resolvedSearchWidgetInfo.provider, opts)) { 622044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung host.deleteAppWidgetId(searchWidgetId); 623f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung return null; 624f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 625af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung return new Pair<>(searchWidgetId, resolvedSearchWidgetInfo); 626ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung } 627d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung 628d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung /** 629ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung * Returns whether touch exploration is currently enabled. 630ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung */ 631ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung public boolean isTouchExplorationEnabled() { 632ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung if (mAccm == null) return false; 633ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung 634ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung return mAccm.isEnabled() && mAccm.isTouchExplorationEnabled(); 635ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung } 636ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung 637ee44595bd53c4f3f6a2eeb664ea96a268636c041Winson Chung /** 63856e09b42a0f1670970872bef611a8036904ad6bfJason Monk * Returns a global setting. 63956e09b42a0f1670970872bef611a8036904ad6bfJason Monk */ 64056e09b42a0f1670970872bef611a8036904ad6bfJason Monk public int getGlobalSetting(Context context, String setting) { 64156e09b42a0f1670970872bef611a8036904ad6bfJason Monk ContentResolver cr = context.getContentResolver(); 64256e09b42a0f1670970872bef611a8036904ad6bfJason Monk return Settings.Global.getInt(cr, setting, 0); 64356e09b42a0f1670970872bef611a8036904ad6bfJason Monk } 64456e09b42a0f1670970872bef611a8036904ad6bfJason Monk 64556e09b42a0f1670970872bef611a8036904ad6bfJason Monk /** 64656e09b42a0f1670970872bef611a8036904ad6bfJason Monk * Returns a system setting. 64756e09b42a0f1670970872bef611a8036904ad6bfJason Monk */ 64856e09b42a0f1670970872bef611a8036904ad6bfJason Monk public int getSystemSetting(Context context, String setting) { 64956e09b42a0f1670970872bef611a8036904ad6bfJason Monk ContentResolver cr = context.getContentResolver(); 65056e09b42a0f1670970872bef611a8036904ad6bfJason Monk return Settings.System.getInt(cr, setting, 0); 65156e09b42a0f1670970872bef611a8036904ad6bfJason Monk } 65256e09b42a0f1670970872bef611a8036904ad6bfJason Monk 65356e09b42a0f1670970872bef611a8036904ad6bfJason Monk /** 654d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung * Returns a system property. 655d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung */ 656d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung public String getSystemProperty(String key) { 657d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung return SystemProperties.get(key); 658d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung } 659d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung 660d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** 661ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Returns the window rect. 662ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 663ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public Rect getWindowRect() { 664ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Rect windowRect = new Rect(); 665ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (mWm == null) return windowRect; 666ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 667dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung Point p = new Point(); 668dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mWm.getDefaultDisplay().getRealSize(p); 669dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung windowRect.set(0, 0, p.x, p.y); 670ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return windowRect; 671ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 672ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 6734e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung /** Starts an activity from recents. */ 6744e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung public boolean startActivityFromRecents(Context context, int taskId, String taskName, 6754e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung ActivityOptions options) { 676dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner if (mIam != null) { 677dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner try { 678dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner mIam.startActivityFromRecents(taskId, options == null ? null : options.toBundle()); 6794e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung return true; 6804e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung } catch (Exception e) { 6814e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung Console.logError(context, 6824e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung context.getString(R.string.recents_launch_error_message, taskName)); 683dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner } 684dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner } 6854e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung return false; 686dc00cbe2c15eef5141656311a6d05c753d7c6db6Craig Mautner } 687044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung 688044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung /** Starts an in-place animation on the front most application windows. */ 689044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) { 690044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung if (mIam == null) return; 691044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung 692044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung try { 693044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung mIam.startInPlaceAnimationOnFrontMostApplication(opts); 694044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung } catch (Exception e) { 695044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung e.printStackTrace(); 696044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung } 697044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung } 698740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung 699740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung /** Registers a task stack listener with the system. */ 700740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung public void registerTaskStackListener(ITaskStackListener listener) { 701740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung if (mIam == null) return; 702740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung 703740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung try { 704740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung mIam.registerTaskStackListener(listener); 705740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung } catch (Exception e) { 706740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung e.printStackTrace(); 707740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung } 708740c3ac782675d190941b2ab1905e56f246c1b11Winson Chung } 709a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung} 710