FileDocCategorySizeDatePackage
SystemServicesProxy.javaAPI DocAndroid 5.1 API21748Thu Mar 12 22:22:42 GMT 2015com.android.systemui.recents.misc

SystemServicesProxy

public class SystemServicesProxy extends Object
Acts as a shim around the real system services that we need to access data from, and provides a point of injection when testing UI.

Fields Summary
static final String
TAG
static final BitmapFactory.Options
sBitmapOptions
android.view.accessibility.AccessibilityManager
mAccm
android.app.ActivityManager
mAm
android.app.IActivityManager
mIam
android.appwidget.AppWidgetManager
mAwm
android.content.pm.PackageManager
mPm
android.content.pm.IPackageManager
mIpm
android.app.SearchManager
mSm
android.view.WindowManager
mWm
android.view.Display
mDisplay
String
mRecentsPackage
android.content.ComponentName
mAssistComponent
android.graphics.Bitmap
mDummyIcon
int
mDummyThumbnailWidth
int
mDummyThumbnailHeight
android.graphics.Paint
mBgProtectionPaint
android.graphics.Canvas
mBgProtectionCanvas
Constructors Summary
public SystemServicesProxy(android.content.Context context)
Private constructor


     
        sBitmapOptions = new BitmapFactory.Options();
        sBitmapOptions.inMutable = true;
    
        mAccm = AccessibilityManager.getInstance(context);
        mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        mIam = ActivityManagerNative.getDefault();
        mAwm = AppWidgetManager.getInstance(context);
        mPm = context.getPackageManager();
        mIpm = AppGlobals.getPackageManager();
        mSm = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
        mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        mDisplay = mWm.getDefaultDisplay();
        mRecentsPackage = context.getPackageName();

        // Get the dummy thumbnail width/heights
        Resources res = context.getResources();
        int wId = com.android.internal.R.dimen.thumbnail_width;
        int hId = com.android.internal.R.dimen.thumbnail_height;
        mDummyThumbnailWidth = res.getDimensionPixelSize(wId);
        mDummyThumbnailHeight = res.getDimensionPixelSize(hId);

        // Create the protection paints
        mBgProtectionPaint = new Paint();
        mBgProtectionPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
        mBgProtectionPaint.setColor(0xFFffffff);
        mBgProtectionCanvas = new Canvas();

        // Resolve the assist intent
        Intent assist = mSm.getAssistIntent(context, false);
        if (assist != null) {
            mAssistComponent = assist.getComponent();
        }

        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
            // Create a dummy icon
            mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
            mDummyIcon.eraseColor(0xFF999999);
        }
    
Methods Summary
public android.util.PairbindSearchAppWidget(android.appwidget.AppWidgetHost host)
Resolves and binds the search app widget that is to appear in the recents.

        if (mAwm == null) return null;
        if (mAssistComponent == null) return null;

        // Find the first Recents widget from the same package as the global assist activity
        AppWidgetProviderInfo searchWidgetInfo = resolveSearchAppWidget();

        // Return early if there is no search widget
        if (searchWidgetInfo == null) return null;

        // Allocate a new widget id and try and bind the app widget (if that fails, then just skip)
        int searchWidgetId = host.allocateAppWidgetId();
        Bundle opts = new Bundle();
        opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
                AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
        if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, searchWidgetInfo.provider, opts)) {
            host.deleteAppWidgetId(searchWidgetId);
            return null;
        }
        return new Pair<Integer, AppWidgetProviderInfo>(searchWidgetId, searchWidgetInfo);
    
public android.graphics.drawable.DrawablegetActivityIcon(android.content.pm.ActivityInfo info, int userId)
Returns the activity icon for the ActivityInfo for a user, badging if necessary.

        if (mPm == null) return null;

        // If we are mocking, then return a mock label
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
            return new ColorDrawable(0xFF666666);
        }

        Drawable icon = info.loadIcon(mPm);
        return getBadgedIcon(icon, userId);
    
public android.content.pm.ActivityInfogetActivityInfo(android.content.ComponentName cn, int userId)
Returns the activity info for a given component name.

param
cn The component name of the activity.
param
userId The userId of the user that this is for.

        if (mIpm == null) return null;
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo();

        try {
            return mIpm.getActivityInfo(cn, PackageManager.GET_META_DATA, userId);
        } catch (RemoteException e) {
            e.printStackTrace();
            return null;
        }
    
public android.content.pm.ActivityInfogetActivityInfo(android.content.ComponentName cn)
Returns the activity info for a given component name.

param
cn The component name of the activity.

        if (mPm == null) return null;
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return new ActivityInfo();

        try {
            return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    
public java.lang.StringgetActivityLabel(android.content.pm.ActivityInfo info)
Returns the activity label

        if (mPm == null) return null;

        // If we are mocking, then return a mock label
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
            return "Recent Task";
        }

        return info.loadLabel(mPm).toString();
    
public android.appwidget.AppWidgetProviderInfogetAppWidgetInfo(int appWidgetId)
Returns the app widget info for the specified app widget id.

        if (mAwm == null) return null;

        return mAwm.getAppWidgetInfo(appWidgetId);
    
public android.graphics.drawable.DrawablegetBadgedIcon(android.graphics.drawable.Drawable icon, int userId)
Returns the given icon for a user, badging if necessary.

        if (userId != UserHandle.myUserId()) {
            icon = mPm.getUserBadgedIcon(icon, new UserHandle(userId));
        }
        return icon;
    
public intgetGlobalSetting(android.content.Context context, java.lang.String setting)
Returns a global setting.

        ContentResolver cr = context.getContentResolver();
        return Settings.Global.getInt(cr, setting, 0);
    
public java.lang.StringgetHomeActivityPackageName()
Returns the package name of the home activity.

        if (mPm == null) return null;
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return null;

        ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
        ComponentName defaultHomeActivity = mPm.getHomeActivities(homeActivities);
        if (defaultHomeActivity != null) {
            return defaultHomeActivity.getPackageName();
        } else if (homeActivities.size() == 1) {
            ResolveInfo info = homeActivities.get(0);
            if (info.activityInfo != null) {
                return info.activityInfo.packageName;
            }
        }
        return null;
    
public java.util.ListgetRecentTasks(int numLatestTasks, int userId, boolean isTopTaskHome)
Returns a list of the recents tasks

        if (mAm == null) return null;

        // If we are mocking, then create some recent tasks
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
            ArrayList<ActivityManager.RecentTaskInfo> tasks =
                    new ArrayList<ActivityManager.RecentTaskInfo>();
            int count = Math.min(numLatestTasks, Constants.DebugFlags.App.SystemServicesProxyMockTaskCount);
            for (int i = 0; i < count; i++) {
                // Create a dummy component name
                int packageIndex = i % Constants.DebugFlags.App.SystemServicesProxyMockPackageCount;
                ComponentName cn = new ComponentName("com.android.test" + packageIndex,
                        "com.android.test" + i + ".Activity");
                String description = "" + i + " - " +
                        Long.toString(Math.abs(new Random().nextLong()), 36);
                // Create the recent task info
                ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
                rti.id = rti.persistentId = i;
                rti.baseIntent = new Intent();
                rti.baseIntent.setComponent(cn);
                rti.description = description;
                rti.firstActiveTime = rti.lastActiveTime = i;
                if (i % 2 == 0) {
                    rti.taskDescription = new ActivityManager.TaskDescription(description,
                        Bitmap.createBitmap(mDummyIcon),
                        0xFF000000 | (0xFFFFFF & new Random().nextInt()));
                } else {
                    rti.taskDescription = new ActivityManager.TaskDescription();
                }
                tasks.add(rti);
            }
            return tasks;
        }

        // Remove home/recents/excluded tasks
        int minNumTasksToQuery = 10;
        int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks);
        List<ActivityManager.RecentTaskInfo> tasks = mAm.getRecentTasksForUser(numTasksToQuery,
                ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
                ActivityManager.RECENT_IGNORE_UNAVAILABLE |
                ActivityManager.RECENT_INCLUDE_PROFILES |
                ActivityManager.RECENT_WITH_EXCLUDED, userId);

        // Break early if we can't get a valid set of tasks
        if (tasks == null) {
            return new ArrayList<ActivityManager.RecentTaskInfo>();
        }

        boolean isFirstValidTask = true;
        Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
        while (iter.hasNext()) {
            ActivityManager.RecentTaskInfo t = iter.next();

            // NOTE: The order of these checks happens in the expected order of the traversal of the
            // tasks

            // Check the first non-recents task, include this task even if it is marked as excluded
            // from recents if we are currently in the app.  In other words, only remove excluded
            // tasks if it is not the first active task.
            boolean isExcluded = (t.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                    == Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
            if (isExcluded && (isTopTaskHome || !isFirstValidTask)) {
                iter.remove();
                continue;
            }
            isFirstValidTask = false;
        }

        return tasks.subList(0, Math.min(tasks.size(), numLatestTasks));
    
public java.util.ListgetRunningTasks(int numTasks)
Returns a list of the running tasks

        if (mAm == null) return null;
        return mAm.getRunningTasks(numTasks);
    
public intgetSystemSetting(android.content.Context context, java.lang.String setting)
Returns a system setting.

        ContentResolver cr = context.getContentResolver();
        return Settings.System.getInt(cr, setting, 0);
    
public android.graphics.BitmapgetTaskThumbnail(int taskId)
Returns the top task thumbnail for the given task id

        if (mAm == null) return null;

        // If we are mocking, then just return a dummy thumbnail
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
            Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight,
                    Bitmap.Config.ARGB_8888);
            thumbnail.eraseColor(0xff333333);
            return thumbnail;
        }

        Bitmap thumbnail = SystemServicesProxy.getThumbnail(mAm, taskId);
        if (thumbnail != null) {
            thumbnail.setHasAlpha(false);
            // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top
            // left pixel, then assume the whole thumbnail is transparent. Generally, proper
            // screenshots are always composed onto a bitmap that has no alpha.
            if (Color.alpha(thumbnail.getPixel(0, 0)) == 0) {
                mBgProtectionCanvas.setBitmap(thumbnail);
                mBgProtectionCanvas.drawRect(0, 0, thumbnail.getWidth(), thumbnail.getHeight(),
                        mBgProtectionPaint);
                mBgProtectionCanvas.setBitmap(null);
                Log.e(TAG, "Invalid screenshot detected from getTaskThumbnail()");
            }
        }
        return thumbnail;
    
public static android.graphics.BitmapgetThumbnail(android.app.ActivityManager activityManager, int taskId)
Returns a task thumbnail from the activity manager

        ActivityManager.TaskThumbnail taskThumbnail = activityManager.getTaskThumbnail(taskId);
        if (taskThumbnail == null) return null;

        Bitmap thumbnail = taskThumbnail.mainThumbnail;
        ParcelFileDescriptor descriptor = taskThumbnail.thumbnailFileDescriptor;
        if (thumbnail == null && descriptor != null) {
            thumbnail = BitmapFactory.decodeFileDescriptor(descriptor.getFileDescriptor(),
                    null, sBitmapOptions);
        }
        if (descriptor != null) {
            try {
                descriptor.close();
            } catch (IOException e) {
            }
        }
        return thumbnail;
    
public ActivityManager.RunningTaskInfogetTopMostTask()
Returns the top task.

        List<ActivityManager.RunningTaskInfo> tasks = getRunningTasks(1);
        if (!tasks.isEmpty()) {
            return tasks.get(0);
        }
        return null;
    
public android.graphics.RectgetWindowRect()
Returns the window rect.

        Rect windowRect = new Rect();
        if (mWm == null) return windowRect;

        Point p = new Point();
        mWm.getDefaultDisplay().getRealSize(p);
        windowRect.set(0, 0, p.x, p.y);
        return windowRect;
    
public booleanisForegroundUserOwner()
Returns whether the foreground user is the owner.

        if (mAm == null) return false;

        return mAm.getCurrentUser() == UserHandle.USER_OWNER;
    
public booleanisInHomeStack(int taskId)
Returns whether the specified task is in the home stack

        if (mAm == null) return false;

        // If we are mocking, then just return false
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
            return false;
        }

        return mAm.isInHomeStack(taskId);
    
public booleanisRecentsTopMost(ActivityManager.RunningTaskInfo topTask, java.util.concurrent.atomic.AtomicBoolean isHomeTopMost)
Returns whether the recents is currently running

        if (topTask != null) {
            ComponentName topActivity = topTask.topActivity;

            // Check if the front most activity is recents
            if (topActivity.getPackageName().equals(AlternateRecentsComponent.sRecentsPackage) &&
                    topActivity.getClassName().equals(AlternateRecentsComponent.sRecentsActivity)) {
                if (isHomeTopMost != null) {
                    isHomeTopMost.set(false);
                }
                return true;
            }

            if (isHomeTopMost != null) {
                isHomeTopMost.set(isInHomeStack(topTask.id));
            }
        }
        return false;
    
public booleanisTouchExplorationEnabled()
Returns whether touch exploration is currently enabled.

        if (mAccm == null) return false;

        return mAccm.isEnabled() && mAccm.isTouchExplorationEnabled();
    
public voidmoveTaskToFront(int taskId, android.app.ActivityOptions opts)
Moves a task to the front with the specified activity options

        if (mAm == null) return;
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;

        if (opts != null) {
            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME,
                    opts.toBundle());
        } else {
            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME);
        }
    
public voidregisterTaskStackListener(android.app.ITaskStackListener listener)
Registers a task stack listener with the system.

        if (mIam == null) return;

        try {
            mIam.registerTaskStackListener(listener);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
public voidremoveTask(int taskId)
Removes the task

        if (mAm == null) return;
        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;

        // Remove the task.
        mAm.removeTask(taskId);
    
public android.appwidget.AppWidgetProviderInforesolveSearchAppWidget()
Resolves and returns the first Recents widget from the same package as the global assist activity.

        if (mAwm == null) return null;
        if (mAssistComponent == null) return null;

        // Find the first Recents widget from the same package as the global assist activity
        List<AppWidgetProviderInfo> widgets = mAwm.getInstalledProviders(
                AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
        for (AppWidgetProviderInfo info : widgets) {
            if (info.provider.getPackageName().equals(mAssistComponent.getPackageName())) {
                return info;
            }
        }
        return null;
    
public booleanstartActivityFromRecents(android.content.Context context, int taskId, java.lang.String taskName, android.app.ActivityOptions options)
Starts an activity from recents.

        if (mIam != null) {
            try {
                mIam.startActivityFromRecents(taskId, options == null ? null : options.toBundle());
                return true;
            } catch (Exception e) {
                Console.logError(context,
                        context.getString(R.string.recents_launch_error_message, taskName));
            }
        }
        return false;
    
public voidstartInPlaceAnimationOnFrontMostApplication(android.app.ActivityOptions opts)
Starts an in-place animation on the front most application windows.

        if (mIam == null) return;

        try {
            mIam.startInPlaceAnimationOnFrontMostApplication(opts);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
public android.graphics.BitmaptakeAppScreenshot()
Takes a screenshot of the current app.

        return takeScreenshot();
    
public android.graphics.BitmaptakeScreenshot()
Takes a screenshot of the current surface.

        DisplayInfo di = new DisplayInfo();
        mDisplay.getDisplayInfo(di);
        return SurfaceControl.screenshot(di.getNaturalWidth(), di.getNaturalHeight());
    
public voidunbindSearchAppWidget(android.appwidget.AppWidgetHost host, int appWidgetId)
Destroys the specified app widget.

        if (mAwm == null) return;

        // Delete the app widget
        host.deleteAppWidgetId(appWidgetId);