SystemServicesProxy.java revision 56e09b42a0f1670970872bef611a8036904ad6bf
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;
231f24c7e37bc794057a156a730c7e4b53b01212edWinson Chungimport android.app.IActivityManager;
24ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chungimport android.app.SearchManager;
25f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetHost;
26f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetManager;
27f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetProviderInfo;
28a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.ComponentName;
2956e09b42a0f1670970872bef611a8036904ad6bfJason Monkimport android.content.ContentResolver;
30a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.Context;
31a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.Intent;
32a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.pm.ActivityInfo;
334f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.content.pm.IPackageManager;
34a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.content.pm.PackageManager;
3585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chungimport android.content.res.Resources;
36a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.graphics.Bitmap;
37ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport android.graphics.BitmapFactory;
38b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.Canvas;
39b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.Color;
40b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.Paint;
41b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.PorterDuff;
42b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.graphics.PorterDuffXfermode;
43ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport android.graphics.Rect;
44a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.graphics.drawable.ColorDrawable;
45a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport android.graphics.drawable.Drawable;
46ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chungimport android.os.Bundle;
47ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport android.os.ParcelFileDescriptor;
484f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.os.RemoteException;
494f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.os.UserHandle;
504f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasaniimport android.os.UserManager;
5156e09b42a0f1670970872bef611a8036904ad6bfJason Monkimport android.provider.Settings;
52b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chungimport android.util.Log;
53f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.util.Pair;
54d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.Display;
55d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.DisplayInfo;
56d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.SurfaceControl;
57d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.WindowManager;
58ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.Constants;
59a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
60ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.io.IOException;
61a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport java.util.ArrayList;
62918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chungimport java.util.Iterator;
63a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungimport java.util.List;
645e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chungimport java.util.Random;
65a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
66a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung/**
67a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * Acts as a shim around the real system services that we need to access data from, and provides
68a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung * a point of injection when testing UI.
69a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung */
70a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chungpublic class SystemServicesProxy {
71b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung    final static String TAG = "SystemServicesProxy";
72b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung
73a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    ActivityManager mAm;
741f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung    IActivityManager mIam;
75f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    AppWidgetManager mAwm;
76a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    PackageManager mPm;
774f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani    IPackageManager mIpm;
784f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani    UserManager mUm;
79ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung    SearchManager mSm;
80d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    WindowManager mWm;
81d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    Display mDisplay;
82918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung    String mRecentsPackage;
83da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung    ComponentName mAssistComponent;
84a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
85a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    Bitmap mDummyIcon;
8685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    int mDummyThumbnailWidth;
8785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    int mDummyThumbnailHeight;
88b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung    Paint mBgProtectionPaint;
89b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung    Canvas mBgProtectionCanvas;
90a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
91a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Private constructor */
92a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    public SystemServicesProxy(Context context) {
93a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
941f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung        mIam = ActivityManagerNative.getDefault();
95f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        mAwm = AppWidgetManager.getInstance(context);
96a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        mPm = context.getPackageManager();
974f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
984f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        mIpm = AppGlobals.getPackageManager();
99ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung        mSm = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
100d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
101d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mDisplay = mWm.getDefaultDisplay();
102918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        mRecentsPackage = context.getPackageName();
103a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
10485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        // Get the dummy thumbnail width/heights
10585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        Resources res = context.getResources();
10685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        int wId = com.android.internal.R.dimen.thumbnail_width;
10785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        int hId = com.android.internal.R.dimen.thumbnail_height;
10885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        mDummyThumbnailWidth = res.getDimensionPixelSize(wId);
10985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        mDummyThumbnailHeight = res.getDimensionPixelSize(hId);
11085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung
111b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        // Create the protection paints
112b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        mBgProtectionPaint = new Paint();
113b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        mBgProtectionPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
114b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        mBgProtectionPaint.setColor(0xFFffffff);
115b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        mBgProtectionCanvas = new Canvas();
116b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung
117da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung        // Resolve the assist intent
118da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung        Intent assist = mSm.getAssistIntent(context, false);
119da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung        if (assist != null) {
120da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung            mAssistComponent = assist.getComponent();
121da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung        }
122da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung
123a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
124a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            // Create a dummy icon
1252f2ca08baa072376b3dfd60506625496aa05903fWinson Chung            mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
1266736905dc0e10689f7c63f6da43b31325caf966aWinson Chung            mDummyIcon.eraseColor(0xFF999999);
127a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
128a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
129a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
130a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Returns a list of the recents tasks */
131918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId) {
132a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (mAm == null) return null;
133a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
134a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        // If we are mocking, then create some recent tasks
135a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
136a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            ArrayList<ActivityManager.RecentTaskInfo> tasks =
137a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                    new ArrayList<ActivityManager.RecentTaskInfo>();
138918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            int count = Math.min(numLatestTasks, Constants.DebugFlags.App.SystemServicesProxyMockTaskCount);
139a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            for (int i = 0; i < count; i++) {
140a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                // Create a dummy component name
141a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                int packageIndex = i % Constants.DebugFlags.App.SystemServicesProxyMockPackageCount;
142a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                ComponentName cn = new ComponentName("com.android.test" + packageIndex,
143a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                        "com.android.test" + i + ".Activity");
144a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung                String description = "" + i + " - " +
145a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung                        Long.toString(Math.abs(new Random().nextLong()), 36);
146a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                // Create the recent task info
147a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
148a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                rti.id = rti.persistentId = i;
149a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                rti.baseIntent = new Intent();
150a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                rti.baseIntent.setComponent(cn);
151a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung                rti.description = description;
152ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung                rti.firstActiveTime = rti.lastActiveTime = i;
1535e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung                if (i % 2 == 0) {
154a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung                    rti.taskDescription = new ActivityManager.TaskDescription(description,
15510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                        Bitmap.createBitmap(mDummyIcon),
15610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                        0xFF000000 | (0xFFFFFF & new Random().nextInt()));
157a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung                } else {
158a449dc033b79775b8945d9cc5a035a6deb145065Winson Chung                    rti.taskDescription = new ActivityManager.TaskDescription();
1595e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung                }
160a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                tasks.add(rti);
161a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            }
162a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            return tasks;
163a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
164a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
165918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        // Remove home/recents/excluded tasks
166918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        int minNumTasksToQuery = 10;
167918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks);
168918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        List<ActivityManager.RecentTaskInfo> tasks = mAm.getRecentTasksForUser(numTasksToQuery,
169a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                ActivityManager.RECENT_IGNORE_UNAVAILABLE |
170918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                ActivityManager.RECENT_INCLUDE_PROFILES |
171918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                ActivityManager.RECENT_WITH_EXCLUDED, userId);
172918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        boolean isFirstValidTask = true;
173918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
174918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        while (iter.hasNext()) {
175918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            ActivityManager.RecentTaskInfo t = iter.next();
176918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung
177918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            // NOTE: The order of these checks happens in the expected order of the traversal of the
178918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            // tasks
179918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung
180918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            // Skip tasks from this Recents package
181918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            if (t.baseIntent.getComponent().getPackageName().equals(mRecentsPackage)) {
182918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                iter.remove();
183918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                continue;
184918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            }
185918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            // Check the first non-recents task, include this task even if it is marked as excluded
186918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            // from recents.  In other words, only remove excluded tasks if it is not the first task
187918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            boolean isExcluded = (t.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
188918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                    == Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
189918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            if (isExcluded && !isFirstValidTask) {
190918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                iter.remove();
191918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                continue;
192918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            }
193918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            isFirstValidTask = false;
194918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            // Skip tasks in the home stack
195918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            if (isInHomeStack(t.persistentId)) {
196918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                iter.remove();
197918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung                continue;
198918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung            }
199918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        }
200918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung
201918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung        return tasks.subList(0, Math.min(tasks.size(), numLatestTasks));
202a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
203a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
204a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Returns a list of the running tasks */
205a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    public List<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) {
206a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (mAm == null) return null;
207a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        return mAm.getRunningTasks(numTasks);
208a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
209a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
210a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Returns whether the specified task is in the home stack */
211a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    public boolean isInHomeStack(int taskId) {
212a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (mAm == null) return false;
213a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
214a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        // If we are mocking, then just return false
215a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
216a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            return false;
217a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
218a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
219a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        return mAm.isInHomeStack(taskId);
220a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
221a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
222a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Returns the top task thumbnail for the given task id */
223a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    public Bitmap getTaskThumbnail(int taskId) {
224a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (mAm == null) return null;
225a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
226a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        // If we are mocking, then just return a dummy thumbnail
227a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
22885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight,
22985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    Bitmap.Config.ARGB_8888);
2306736905dc0e10689f7c63f6da43b31325caf966aWinson Chung            thumbnail.eraseColor(0xff333333);
231a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            return thumbnail;
232a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
233a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
234ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        Bitmap thumbnail = SystemServicesProxy.getThumbnail(mAm, taskId);
235b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        if (thumbnail != null) {
236b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung            // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top
237b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung            // left pixel, then assume the whole thumbnail is transparent. Generally, proper
238b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung            // screenshots are always composed onto a bitmap that has no alpha.
239b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung            if (Color.alpha(thumbnail.getPixel(0, 0)) == 0) {
240b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung                mBgProtectionCanvas.setBitmap(thumbnail);
241b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung                mBgProtectionCanvas.drawRect(0, 0, thumbnail.getWidth(), thumbnail.getHeight(),
242b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung                        mBgProtectionPaint);
243b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung                mBgProtectionCanvas.setBitmap(null);
244b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung                Log.e(TAG, "Invalid screenshot detected from getTaskThumbnail()");
245b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung            }
246b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        }
247b5ddfc375616bf7dbe9f4ff85ad124f02cc5990fWinson Chung        return thumbnail;
248a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
249a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
250ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    /**
251ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung     * Returns a task thumbnail from the activity manager
252ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung     */
253ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    public static Bitmap getThumbnail(ActivityManager activityManager, int taskId) {
254ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        ActivityManager.TaskThumbnail taskThumbnail = activityManager.getTaskThumbnail(taskId);
25585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        if (taskThumbnail == null) return null;
25685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung
257ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        Bitmap thumbnail = taskThumbnail.mainThumbnail;
258ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        ParcelFileDescriptor descriptor = taskThumbnail.thumbnailFileDescriptor;
259ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        if (thumbnail == null && descriptor != null) {
260ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            thumbnail = BitmapFactory.decodeFileDescriptor(descriptor.getFileDescriptor());
261ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        }
262ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        if (descriptor != null) {
263ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            try {
264ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung                descriptor.close();
265ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            } catch (IOException e) {
266ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            }
267ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        }
268ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        return thumbnail;
269ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    }
270ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung
271a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Moves a task to the front with the specified activity options */
272a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    public void moveTaskToFront(int taskId, ActivityOptions opts) {
273a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (mAm == null) return;
274a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
275a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
276a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (opts != null) {
277a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME,
278a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung                    opts.toBundle());
279a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        } else {
280a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME);
281a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
282a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
283a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
284a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Removes the task and kills the process */
2855393dff555641f5666573952498e27c90fd3edcaWinson Chung    public void removeTask(int taskId, boolean isDocument) {
286a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (mAm == null) return;
287a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
288a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
2895393dff555641f5666573952498e27c90fd3edcaWinson Chung        // Remove the task, and only kill the process if it is not a document
2905393dff555641f5666573952498e27c90fd3edcaWinson Chung        mAm.removeTask(taskId, isDocument ? 0 : ActivityManager.REMOVE_TASK_KILL_PROCESS);
291a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
292a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
2934f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani    /**
2944f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani     * Returns the activity info for a given component name.
2954f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani     *
296f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     * @param cn The component name of the activity.
2974f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani     * @param userId The userId of the user that this is for.
2984f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani     */
2994f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani    public ActivityInfo getActivityInfo(ComponentName cn, int userId) {
3004f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        if (mIpm == null) return null;
301814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo();
302a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
303a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        try {
3044f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            return mIpm.getActivityInfo(cn, PackageManager.GET_META_DATA, userId);
3054f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        } catch (RemoteException e) {
306a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            e.printStackTrace();
307a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            return null;
308a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
309a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
310a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
311f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /**
312f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     * Returns the activity info for a given component name.
313f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     *
314f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     * @param cn The component name of the activity.
315f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     */
316f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    public ActivityInfo getActivityInfo(ComponentName cn) {
317f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        if (mPm == null) return null;
318814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo();
319f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
320f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        try {
321f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA);
322f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        } catch (PackageManager.NameNotFoundException e) {
323f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            e.printStackTrace();
324f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            return null;
325f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
326f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
327f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
328a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    /** Returns the activity label */
329a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    public String getActivityLabel(ActivityInfo info) {
330a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (mPm == null) return null;
331a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
332a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        // If we are mocking, then return a mock label
333a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
334a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung            return "Recent Task";
335a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
336a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
337a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        return info.loadLabel(mPm).toString();
338a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
339a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
3404f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani    /**
3414f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani     * Returns the activity icon for the ActivityInfo for a user, badging if
3424f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani     * necessary.
3434f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani     */
3444f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani    public Drawable getActivityIcon(ActivityInfo info, int userId) {
3454f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        if (mPm == null || mUm == null) return null;
346a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
347a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        // If we are mocking, then return a mock label
348a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
3492f2ca08baa072376b3dfd60506625496aa05903fWinson Chung            return new ColorDrawable(0xFF666666);
350a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        }
351a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung
3524f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        Drawable icon = info.loadIcon(mPm);
3536507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee        return getBadgedIcon(icon, userId);
3546507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee    }
3556507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee
3566507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee    /**
3576507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee     * Returns the given icon for a user, badging if necessary.
3586507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee     */
3596507f2e03a90244e08fb62f9b55653ba3230d0b7Robin Lee    public Drawable getBadgedIcon(Drawable icon, int userId) {
3604f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        if (userId != UserHandle.myUserId()) {
3614f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            icon = mUm.getBadgedDrawableForUser(icon, new UserHandle(userId));
3624f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        }
3634f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        return icon;
364a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung    }
365ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung
366ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung    /**
367f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     * Resolves and binds the search app widget that is to appear in the recents.
368ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung     */
369f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    public Pair<Integer, AppWidgetProviderInfo> bindSearchAppWidget(AppWidgetHost host) {
370f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        if (mAwm == null) return null;
371da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung        if (mAssistComponent == null) return null;
372ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung
373da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung        // Find the first Recents widget from the same package as the global assist activity
374da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung        List<AppWidgetProviderInfo> widgets = mAwm.getInstalledProviders(
375da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung                AppWidgetProviderInfo.WIDGET_CATEGORY_RECENTS);
376f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        AppWidgetProviderInfo searchWidgetInfo = null;
377f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        for (AppWidgetProviderInfo info : widgets) {
378da5b84c8d38d8322b5bb7d22653625bb51734a4eWinson Chung            if (info.provider.getPackageName().equals(mAssistComponent.getPackageName())) {
379f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                searchWidgetInfo = info;
380f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                break;
381f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
382f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
383f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
384f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Return early if there is no search widget
385f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        if (searchWidgetInfo == null) return null;
386f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
387f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Allocate a new widget id and try and bind the app widget (if that fails, then just skip)
388f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        int searchWidgetId = host.allocateAppWidgetId();
389f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        Bundle opts = new Bundle();
390f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
391f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                AppWidgetProviderInfo.WIDGET_CATEGORY_RECENTS);
392f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, searchWidgetInfo.provider, opts)) {
393f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            return null;
394f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
395f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        return new Pair<Integer, AppWidgetProviderInfo>(searchWidgetId, searchWidgetInfo);
396f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
397f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
398f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /**
399f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     * Returns the app widget info for the specified app widget id.
400f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     */
401f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
402f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        if (mAwm == null) return null;
403f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
404f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        return mAwm.getAppWidgetInfo(appWidgetId);
405f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
406f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
407f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /**
408f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     * Destroys the specified app widget.
409f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung     */
410f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    public void unbindSearchAppWidget(AppWidgetHost host, int appWidgetId) {
411f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        if (mAwm == null) return;
412f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
413f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Delete the app widget
414f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        host.deleteAppWidgetId(appWidgetId);
415ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung    }
416d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
417d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    /**
41856e09b42a0f1670970872bef611a8036904ad6bfJason Monk     * Returns a global setting.
41956e09b42a0f1670970872bef611a8036904ad6bfJason Monk     */
42056e09b42a0f1670970872bef611a8036904ad6bfJason Monk    public int getGlobalSetting(Context context, String setting) {
42156e09b42a0f1670970872bef611a8036904ad6bfJason Monk        ContentResolver cr = context.getContentResolver();
42256e09b42a0f1670970872bef611a8036904ad6bfJason Monk        return Settings.Global.getInt(cr, setting, 0);
42356e09b42a0f1670970872bef611a8036904ad6bfJason Monk    }
42456e09b42a0f1670970872bef611a8036904ad6bfJason Monk
42556e09b42a0f1670970872bef611a8036904ad6bfJason Monk    /**
42656e09b42a0f1670970872bef611a8036904ad6bfJason Monk     * Returns a system setting.
42756e09b42a0f1670970872bef611a8036904ad6bfJason Monk     */
42856e09b42a0f1670970872bef611a8036904ad6bfJason Monk    public int getSystemSetting(Context context, String setting) {
42956e09b42a0f1670970872bef611a8036904ad6bfJason Monk        ContentResolver cr = context.getContentResolver();
43056e09b42a0f1670970872bef611a8036904ad6bfJason Monk        return Settings.System.getInt(cr, setting, 0);
43156e09b42a0f1670970872bef611a8036904ad6bfJason Monk    }
43256e09b42a0f1670970872bef611a8036904ad6bfJason Monk
43356e09b42a0f1670970872bef611a8036904ad6bfJason Monk    /**
434ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung     * Returns the window rect.
435ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung     */
436ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    public Rect getWindowRect() {
437ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        Rect windowRect = new Rect();
438ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        if (mWm == null) return windowRect;
439ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung
440ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        mWm.getDefaultDisplay().getRectSize(windowRect);
441ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        return windowRect;
442ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    }
443ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung
444ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    /**
4451f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung     * Locks the current task.
4461f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung     */
4471f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung    public void lockCurrentTask() {
4481f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung        if (mIam == null) return;
4491f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung
4501f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung        try {
4511f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung            mIam.startLockTaskModeOnCurrent();
4521f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung        } catch (RemoteException e) {}
4531f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung    }
4541f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung
4551f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung    /**
456d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung     * Takes a screenshot of the current surface.
457d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung     */
458d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    public Bitmap takeScreenshot() {
459d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        DisplayInfo di = new DisplayInfo();
460d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mDisplay.getDisplayInfo(di);
461d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        return SurfaceControl.screenshot(di.getNaturalWidth(), di.getNaturalHeight());
462d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    }
463ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung
464ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    /**
465ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung     * Takes a screenshot of the current app.
466ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung     */
467ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    public Bitmap takeAppScreenshot() {
468ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        return takeScreenshot();
469ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    }
470a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung}
471