Search in sources :

Example 51 with Point

use of android.graphics.Point in project platform_frameworks_base by android.

the class Screenshooter method takeScreenshot.

/**
     * Takes a screenshot.
     *
     * @return The screenshot bitmap on success, null otherwise.
     */
static Bitmap takeScreenshot() {
    Display display = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
    Point displaySize = new Point();
    display.getRealSize(displaySize);
    final int displayWidth = displaySize.x;
    final int displayHeight = displaySize.y;
    final float screenshotWidth;
    final float screenshotHeight;
    final int rotation = display.getRotation();
    switch(rotation) {
        case ROTATION_FREEZE_0:
            {
                screenshotWidth = displayWidth;
                screenshotHeight = displayHeight;
            }
            break;
        case ROTATION_FREEZE_90:
            {
                screenshotWidth = displayHeight;
                screenshotHeight = displayWidth;
            }
            break;
        case ROTATION_FREEZE_180:
            {
                screenshotWidth = displayWidth;
                screenshotHeight = displayHeight;
            }
            break;
        case ROTATION_FREEZE_270:
            {
                screenshotWidth = displayHeight;
                screenshotHeight = displayWidth;
            }
            break;
        default:
            {
                throw new IllegalArgumentException("Invalid rotation: " + rotation);
            }
    }
    Log.d(TAG, "Taking screenshot of dimensions " + displayWidth + " x " + displayHeight);
    // Take the screenshot
    Bitmap screenShot = SurfaceControl.screenshot((int) screenshotWidth, (int) screenshotHeight);
    if (screenShot == null) {
        Log.e(TAG, "Failed to take screenshot of dimensions " + screenshotWidth + " x " + screenshotHeight);
        return null;
    }
    // Rotate the screenshot to the current orientation
    if (rotation != ROTATION_FREEZE_0) {
        Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(unrotatedScreenShot);
        canvas.translate(unrotatedScreenShot.getWidth() / 2, unrotatedScreenShot.getHeight() / 2);
        canvas.rotate(getDegreesForRotation(rotation));
        canvas.translate(-screenshotWidth / 2, -screenshotHeight / 2);
        canvas.drawBitmap(screenShot, 0, 0, null);
        canvas.setBitmap(null);
        screenShot.recycle();
        screenShot = unrotatedScreenShot;
    }
    // Optimization
    screenShot.setHasAlpha(false);
    return screenShot;
}
Also used : Bitmap(android.graphics.Bitmap) Canvas(android.graphics.Canvas) Point(android.graphics.Point) Point(android.graphics.Point) Display(android.view.Display)

Example 52 with Point

use of android.graphics.Point in project platform_frameworks_base by android.

the class TaskCardView method getStartingCardThumbnailRectForStartPosition.

private static Rect getStartingCardThumbnailRectForStartPosition(Context context, boolean hasFocus) {
    Resources res = context.getResources();
    int width = res.getDimensionPixelOffset(R.dimen.recents_tv_card_width);
    int totalSpacing = res.getDimensionPixelOffset(R.dimen.recents_tv_gird_card_spacing) * 2;
    if (hasFocus) {
        totalSpacing += res.getDimensionPixelOffset(R.dimen.recents_tv_gird_focused_card_delta);
    }
    int height = res.getDimensionPixelOffset(R.dimen.recents_tv_screenshot_height);
    int topMargin = res.getDimensionPixelOffset(R.dimen.recents_tv_gird_row_top_margin);
    int headerHeight = res.getDimensionPixelOffset(R.dimen.recents_tv_card_extra_badge_size) + res.getDimensionPixelOffset(R.dimen.recents_tv_icon_padding_bottom);
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int screenWidth = size.x;
    return new Rect(screenWidth / 2 + width / 2 + totalSpacing, topMargin + headerHeight, screenWidth / 2 + width / 2 + totalSpacing + width, topMargin + headerHeight + height);
}
Also used : Rect(android.graphics.Rect) Resources(android.content.res.Resources) Point(android.graphics.Point) Point(android.graphics.Point) WindowManager(android.view.WindowManager) Display(android.view.Display)

Example 53 with Point

use of android.graphics.Point in project platform_frameworks_base by android.

the class TouchExplorer method computeClickLocation.

private int computeClickLocation(Point outLocation) {
    MotionEvent lastExploreEvent = mInjectedPointerTracker.getLastInjectedHoverEventForClick();
    if (lastExploreEvent != null) {
        final int lastExplorePointerIndex = lastExploreEvent.getActionIndex();
        outLocation.x = (int) lastExploreEvent.getX(lastExplorePointerIndex);
        outLocation.y = (int) lastExploreEvent.getY(lastExplorePointerIndex);
        if (!mAms.accessibilityFocusOnlyInActiveWindow() || mLastTouchedWindowId == mAms.getActiveWindowId()) {
            if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) {
                return CLICK_LOCATION_ACCESSIBILITY_FOCUS;
            } else {
                return CLICK_LOCATION_LAST_TOUCH_EXPLORED;
            }
        }
    }
    if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) {
        return CLICK_LOCATION_ACCESSIBILITY_FOCUS;
    }
    return CLICK_LOCATION_NONE;
}
Also used : Point(android.graphics.Point) MotionEvent(android.view.MotionEvent)

Example 54 with Point

use of android.graphics.Point in project platform_frameworks_base by android.

the class ActivityManagerService method addAppTask.

@Override
public int addAppTask(IBinder activityToken, Intent intent, ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
    final int callingUid = Binder.getCallingUid();
    final long callingIdent = Binder.clearCallingIdentity();
    try {
        synchronized (this) {
            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
            if (r == null) {
                throw new IllegalArgumentException("Activity does not exist; token=" + activityToken);
            }
            ComponentName comp = intent.getComponent();
            if (comp == null) {
                throw new IllegalArgumentException("Intent " + intent + " must specify explicit component");
            }
            if (thumbnail.getWidth() != mThumbnailWidth || thumbnail.getHeight() != mThumbnailHeight) {
                throw new IllegalArgumentException("Bad thumbnail size: got " + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " + mThumbnailWidth + "x" + mThumbnailHeight);
            }
            if (intent.getSelector() != null) {
                intent.setSelector(null);
            }
            if (intent.getSourceBounds() != null) {
                intent.setSourceBounds(null);
            }
            if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
                if ((intent.getFlags() & Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
                    // The caller has added this as an auto-remove task...  that makes no
                    // sense, so turn off auto-remove.
                    intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
                }
            }
            if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
                mLastAddedTaskActivity = null;
            }
            ActivityInfo ainfo = mLastAddedTaskActivity;
            if (ainfo == null) {
                ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(comp, 0, UserHandle.getUserId(callingUid));
                if (ainfo.applicationInfo.uid != callingUid) {
                    throw new SecurityException("Can't add task for another application: target uid=" + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
                }
            }
            // Use the full screen as the context for the task thumbnail
            final Point displaySize = new Point();
            final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
            r.task.stack.getDisplaySize(displaySize);
            thumbnailInfo.taskWidth = displaySize.x;
            thumbnailInfo.taskHeight = displaySize.y;
            thumbnailInfo.screenOrientation = mConfiguration.orientation;
            TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent, description, thumbnailInfo);
            int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
            if (trimIdx >= 0) {
                // means it would be added at the end of the list but then just removed.
                return INVALID_TASK_ID;
            }
            final int N = mRecentTasks.size();
            if (N >= (ActivityManager.getMaxRecentTasksStatic() - 1)) {
                final TaskRecord tr = mRecentTasks.remove(N - 1);
                tr.removedFromRecents();
            }
            task.inRecents = true;
            mRecentTasks.add(task);
            r.task.stack.addTask(task, false, "addAppTask");
            task.setLastThumbnailLocked(thumbnail);
            task.freeLastThumbnail();
            return task.taskId;
        }
    } finally {
        Binder.restoreCallingIdentity(callingIdent);
    }
}
Also used : ActivityInfo(android.content.pm.ActivityInfo) ComponentName(android.content.ComponentName) Point(android.graphics.Point) Point(android.graphics.Point) TaskThumbnailInfo(android.app.ActivityManager.TaskThumbnailInfo)

Example 55 with Point

use of android.graphics.Point in project platform_frameworks_base by android.

the class ActivityManagerService method computeOomAdjLocked.

private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now) {
    if (mAdjSeq == app.adjSeq) {
        // This adjustment has already been computed.
        return app.curRawAdj;
    }
    if (app.thread == null) {
        app.adjSeq = mAdjSeq;
        app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
        app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
        return (app.curAdj = app.curRawAdj = ProcessList.CACHED_APP_MAX_ADJ);
    }
    app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
    app.adjSource = null;
    app.adjTarget = null;
    app.empty = false;
    app.cached = false;
    final int activitiesSize = app.activities.size();
    if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
        // The max adjustment doesn't allow this app to be anything
        // below foreground, so it is not worth doing work for it.
        app.adjType = "fixed";
        app.adjSeq = mAdjSeq;
        app.curRawAdj = app.maxAdj;
        app.foregroundActivities = false;
        app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
        // System processes can do UI, and when they do we want to have
        // them trim their memory after the user leaves the UI.  To
        // facilitate this, here we need to determine whether or not it
        // is currently showing UI.
        app.systemNoUi = true;
        if (app == TOP_APP) {
            app.systemNoUi = false;
            app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
            app.adjType = "pers-top-activity";
        } else if (app.hasTopUi) {
            app.systemNoUi = false;
            app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
            app.adjType = "pers-top-ui";
        } else if (activitiesSize > 0) {
            for (int j = 0; j < activitiesSize; j++) {
                final ActivityRecord r = app.activities.get(j);
                if (r.visible) {
                    app.systemNoUi = false;
                }
            }
        }
        if (!app.systemNoUi) {
            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
        }
        return (app.curAdj = app.maxAdj);
    }
    app.systemNoUi = false;
    final int PROCESS_STATE_CUR_TOP = mTopProcessState;
    // Determine the importance of the process, starting with most
    // important to least, and assign an appropriate OOM adjustment.
    int adj;
    int schedGroup;
    int procState;
    boolean foregroundActivities = false;
    final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
    if (app == TOP_APP) {
        // The last app on the list is the foreground app.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
        app.adjType = "top-activity";
        foregroundActivities = true;
        procState = PROCESS_STATE_CUR_TOP;
    } else if (app.instrumentationClass != null) {
        // Don't want to kill running instrumentation.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.adjType = "instrumentation";
        procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
    } else if (isReceivingBroadcastLocked(app, queues)) {
        // An app that is currently receiving a broadcast also
        // counts as being in the foreground for OOM killer purposes.
        // It's placed in a sched group based on the nature of the
        // broadcast as reflected by which queue it's active in.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = (queues.contains(mFgBroadcastQueue)) ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
        app.adjType = "broadcast";
        procState = ActivityManager.PROCESS_STATE_RECEIVER;
    } else if (app.executingServices.size() > 0) {
        // An app that is currently executing a service callback also
        // counts as being in the foreground.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = app.execServicesFg ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
        app.adjType = "exec-service";
        procState = ActivityManager.PROCESS_STATE_SERVICE;
    //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
    } else {
        // As far as we know the process is empty.  We may change our mind later.
        schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
        // At this point we don't actually know the adjustment.  Use the cached adj
        // value that the caller wants us to.
        adj = cachedAdj;
        procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
        app.cached = true;
        app.empty = true;
        app.adjType = "cch-empty";
    }
    // Examine all activities if not already foreground.
    if (!foregroundActivities && activitiesSize > 0) {
        int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
        for (int j = 0; j < activitiesSize; j++) {
            final ActivityRecord r = app.activities.get(j);
            if (r.app != app) {
                Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app + " instead of expected " + app);
                if (r.app == null || (r.app.uid == app.uid)) {
                    // Only fix things up when they look sane
                    r.app = app;
                } else {
                    continue;
                }
            }
            if (r.visible) {
                // App has a visible activity; only upgrade adjustment.
                if (adj > ProcessList.VISIBLE_APP_ADJ) {
                    adj = ProcessList.VISIBLE_APP_ADJ;
                    app.adjType = "visible";
                }
                if (procState > PROCESS_STATE_CUR_TOP) {
                    procState = PROCESS_STATE_CUR_TOP;
                }
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                app.cached = false;
                app.empty = false;
                foregroundActivities = true;
                if (r.task != null && minLayer > 0) {
                    final int layer = r.task.mLayerRank;
                    if (layer >= 0 && minLayer > layer) {
                        minLayer = layer;
                    }
                }
                break;
            } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
                if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                    app.adjType = "pausing";
                }
                if (procState > PROCESS_STATE_CUR_TOP) {
                    procState = PROCESS_STATE_CUR_TOP;
                }
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                app.cached = false;
                app.empty = false;
                foregroundActivities = true;
            } else if (r.state == ActivityState.STOPPING) {
                if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                    app.adjType = "stopping";
                }
                // processes and they should soon all go into the cached state.
                if (!r.finishing) {
                    if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
                        procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
                    }
                }
                app.cached = false;
                app.empty = false;
                foregroundActivities = true;
            } else {
                if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                    procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
                    app.adjType = "cch-act";
                }
            }
        }
        if (adj == ProcessList.VISIBLE_APP_ADJ) {
            adj += minLayer;
        }
    }
    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
        if (app.foregroundServices) {
            // The user is aware of this app, so make it visible.
            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
            app.cached = false;
            app.adjType = "fg-service";
            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        } else if (app.forcingToForeground != null) {
            // The user is aware of this app, so make it visible.
            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
            app.cached = false;
            app.adjType = "force-fg";
            app.adjSource = app.forcingToForeground;
            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        }
    }
    if (app == mHeavyWeightProcess) {
        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
            // We don't want to kill the current heavy-weight process.
            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "heavy";
        }
        if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
            procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
        }
    }
    if (app == mHomeProcess) {
        if (adj > ProcessList.HOME_APP_ADJ) {
            // This process is hosting what we currently consider to be the
            // home app, so we don't want to let it go into the background.
            adj = ProcessList.HOME_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "home";
        }
        if (procState > ActivityManager.PROCESS_STATE_HOME) {
            procState = ActivityManager.PROCESS_STATE_HOME;
        }
    }
    if (app == mPreviousProcess && app.activities.size() > 0) {
        if (adj > ProcessList.PREVIOUS_APP_ADJ) {
            // This was the previous process that showed UI to the user.
            // We want to try to keep it around more aggressively, to give
            // a good experience around switching between two apps.
            adj = ProcessList.PREVIOUS_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "previous";
        }
        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
        }
    }
    if (false)
        Slog.i(TAG, "OOM " + app + ": initial adj=" + adj + " reason=" + app.adjType);
    // By default, we use the computed adjustment.  It may be changed if
    // there are applications dependent on our services or providers, but
    // this gives us a baseline and makes sure we don't get into an
    // infinite recursion.
    app.adjSeq = mAdjSeq;
    app.curRawAdj = adj;
    app.hasStartedServices = false;
    if (mBackupTarget != null && app == mBackupTarget.app) {
        // If possible we want to avoid killing apps while they're being backed up
        if (adj > ProcessList.BACKUP_APP_ADJ) {
            if (DEBUG_BACKUP)
                Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
            adj = ProcessList.BACKUP_APP_ADJ;
            if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
                procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
            }
            app.adjType = "backup";
            app.cached = false;
        }
        if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
            procState = ActivityManager.PROCESS_STATE_BACKUP;
        }
    }
    boolean mayBeTop = false;
    for (int is = app.services.size() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); is--) {
        ServiceRecord s = app.services.valueAt(is);
        if (s.startRequested) {
            app.hasStartedServices = true;
            if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
                procState = ActivityManager.PROCESS_STATE_SERVICE;
            }
            if (app.hasShownUi && app != mHomeProcess) {
                // debug and understand what is going on.
                if (adj > ProcessList.SERVICE_ADJ) {
                    app.adjType = "cch-started-ui-services";
                }
            } else {
                if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
                    // of the background processes.
                    if (adj > ProcessList.SERVICE_ADJ) {
                        adj = ProcessList.SERVICE_ADJ;
                        app.adjType = "started-services";
                        app.cached = false;
                    }
                }
                // even though the service no longer has an impact.
                if (adj > ProcessList.SERVICE_ADJ) {
                    app.adjType = "cch-started-services";
                }
            }
        }
        for (int conni = s.connections.size() - 1; conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); conni--) {
            ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
            for (int i = 0; i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); i++) {
                // XXX should compute this based on the max of
                // all connected clients.
                ConnectionRecord cr = clist.get(i);
                if (cr.binding.client == app) {
                    // Binding to ourself is not interesting.
                    continue;
                }
                if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
                    ProcessRecord client = cr.binding.client;
                    int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
                    int clientProcState = client.curProcState;
                    if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                        // If the other app is cached for any reason, for purposes here
                        // we are going to consider it empty.  The specific cached state
                        // doesn't propagate except under certain conditions.
                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
                    }
                    String adjType = null;
                    if ((cr.flags & Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
                        // this guy more like a started service.
                        if (app.hasShownUi && app != mHomeProcess) {
                            // debug and understand what is going on.
                            if (adj > clientAdj) {
                                adjType = "cch-bound-ui-services";
                            }
                            app.cached = false;
                            clientAdj = adj;
                            clientProcState = procState;
                        } else {
                            if (now >= (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
                                // to help debug and undertand what is going on.
                                if (adj > clientAdj) {
                                    adjType = "cch-bound-services";
                                }
                                clientAdj = adj;
                            }
                        }
                    }
                    if (adj > clientAdj) {
                        // memory.
                        if (app.hasShownUi && app != mHomeProcess && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                            adjType = "cch-bound-ui-services";
                        } else {
                            if ((cr.flags & (Context.BIND_ABOVE_CLIENT | Context.BIND_IMPORTANT)) != 0) {
                                adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
                            } else if ((cr.flags & Context.BIND_NOT_VISIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                            } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
                                adj = clientAdj;
                            } else {
                                if (adj > ProcessList.VISIBLE_APP_ADJ) {
                                    adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
                                }
                            }
                            if (!client.cached) {
                                app.cached = false;
                            }
                            adjType = "service";
                        }
                    }
                    if ((cr.flags & Context.BIND_NOT_FOREGROUND) == 0) {
                        // foreground work.
                        if (client.curSchedGroup > schedGroup) {
                            if ((cr.flags & Context.BIND_IMPORTANT) != 0) {
                                schedGroup = client.curSchedGroup;
                            } else {
                                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                            }
                        }
                        if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
                            if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
                                // Special handling of clients who are in the top state.
                                // We *may* want to consider this process to be in the
                                // top state as well, but only if there is not another
                                // reason for it to be running.  Being on the top is a
                                // special state, meaning you are specifically running
                                // for the current top app.  If the process is already
                                // running in the background for some other reason, it
                                // is more important to continue considering it to be
                                // in the background state.
                                mayBeTop = true;
                                clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
                            } else {
                                // give them the best state after that.
                                if ((cr.flags & Context.BIND_FOREGROUND_SERVICE) != 0) {
                                    clientProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                                } else if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE && (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) != 0) {
                                    clientProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                                } else {
                                    clientProcState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
                                }
                            }
                        }
                    } else {
                        if (clientProcState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
                            clientProcState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
                        }
                    }
                    if (procState > clientProcState) {
                        procState = clientProcState;
                    }
                    if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND && (cr.flags & Context.BIND_SHOWING_UI) != 0) {
                        app.pendingUiClean = true;
                    }
                    if (adjType != null) {
                        app.adjType = adjType;
                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE;
                        app.adjSource = cr.binding.client;
                        app.adjSourceProcState = clientProcState;
                        app.adjTarget = s.name;
                    }
                }
                if ((cr.flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
                    app.treatLikeActivity = true;
                }
                final ActivityRecord a = cr.activity;
                if ((cr.flags & Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
                    if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible || a.state == ActivityState.RESUMED || a.state == ActivityState.PAUSING)) {
                        adj = ProcessList.FOREGROUND_APP_ADJ;
                        if ((cr.flags & Context.BIND_NOT_FOREGROUND) == 0) {
                            if ((cr.flags & Context.BIND_IMPORTANT) != 0) {
                                schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
                            } else {
                                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                            }
                        }
                        app.cached = false;
                        app.adjType = "service";
                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE;
                        app.adjSource = a;
                        app.adjSourceProcState = procState;
                        app.adjTarget = s.name;
                    }
                }
            }
        }
    }
    for (int provi = app.pubProviders.size() - 1; provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); provi--) {
        ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
        for (int i = cpr.connections.size() - 1; i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); i--) {
            ContentProviderConnection conn = cpr.connections.get(i);
            ProcessRecord client = conn.client;
            if (client == app) {
                // Being our own client is not interesting.
                continue;
            }
            int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
            int clientProcState = client.curProcState;
            if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                // If the other app is cached for any reason, for purposes here
                // we are going to consider it empty.
                clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
            }
            if (adj > clientAdj) {
                if (app.hasShownUi && app != mHomeProcess && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                    app.adjType = "cch-ui-provider";
                } else {
                    adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
                    app.adjType = "provider";
                }
                app.cached &= client.cached;
                app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_PROVIDER_IN_USE;
                app.adjSource = client;
                app.adjSourceProcState = clientProcState;
                app.adjTarget = cpr.name;
            }
            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
                    // Special handling of clients who are in the top state.
                    // We *may* want to consider this process to be in the
                    // top state as well, but only if there is not another
                    // reason for it to be running.  Being on the top is a
                    // special state, meaning you are specifically running
                    // for the current top app.  If the process is already
                    // running in the background for some other reason, it
                    // is more important to continue considering it to be
                    // in the background state.
                    mayBeTop = true;
                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
                } else {
                    // Special handling for above-top states (persistent
                    // processes).  These should not bring the current process
                    // into the top state, since they are not on top.  Instead
                    // give them the best state after that.
                    clientProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                }
            }
            if (procState > clientProcState) {
                procState = clientProcState;
            }
            if (client.curSchedGroup > schedGroup) {
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
            }
        }
        // FOREGROUND_APP_ADJ.
        if (cpr.hasExternalProcessHandles()) {
            if (adj > ProcessList.FOREGROUND_APP_ADJ) {
                adj = ProcessList.FOREGROUND_APP_ADJ;
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                app.cached = false;
                app.adjType = "provider";
                app.adjTarget = cpr.name;
            }
            if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
            }
        }
    }
    if (app.lastProviderTime > 0 && (app.lastProviderTime + CONTENT_PROVIDER_RETAIN_TIME) > now) {
        if (adj > ProcessList.PREVIOUS_APP_ADJ) {
            adj = ProcessList.PREVIOUS_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "provider";
        }
        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
        }
    }
    if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
        // to the top state.
        switch(procState) {
            case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
            case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
            case ActivityManager.PROCESS_STATE_SERVICE:
                // These all are longer-term states, so pull them up to the top
                // of the background states, but not all the way to the top state.
                procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                break;
            default:
                // Otherwise, top is a better choice, so take it.
                procState = ActivityManager.PROCESS_STATE_TOP;
                break;
        }
    }
    if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
        if (app.hasClientActivities) {
            // This is a cached process, but with client activities.  Mark it so.
            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
            app.adjType = "cch-client-act";
        } else if (app.treatLikeActivity) {
            // This is a cached process, but somebody wants us to treat it like it has
            // an activity, okay!
            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
            app.adjType = "cch-as-act";
        }
    }
    if (adj == ProcessList.SERVICE_ADJ) {
        if (doingAll) {
            app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs / 3);
            mNewNumServiceProcs++;
            //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
            if (!app.serviceb) {
                // keep launcher over it.
                if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
                    app.serviceHighRam = true;
                    app.serviceb = true;
                //Slog.i(TAG, "ADJ " + app + " high ram!");
                } else {
                    mNewNumAServiceProcs++;
                //Slog.i(TAG, "ADJ " + app + " not high ram!");
                }
            } else {
                app.serviceHighRam = false;
            }
        }
        if (app.serviceb) {
            adj = ProcessList.SERVICE_B_ADJ;
        }
    }
    app.curRawAdj = adj;
    //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
    if (adj > app.maxAdj) {
        adj = app.maxAdj;
        if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        }
    }
    // Do final modification to adj.  Everything we do between here and applying
    // the final setAdj must be done in this function, because we will also use
    // it when computing the final cached adj later.  Note that we don't need to
    // worry about this for max adj above, since max adj will always be used to
    // keep it out of the cached vaues.
    app.curAdj = app.modifyRawOomAdj(adj);
    app.curSchedGroup = schedGroup;
    app.curProcState = procState;
    app.foregroundActivities = foregroundActivities;
    return app.curRawAdj;
}
Also used : ArraySet(android.util.ArraySet) Point(android.graphics.Point)

Aggregations

Point (android.graphics.Point)1151 Display (android.view.Display)217 Rect (android.graphics.Rect)194 Paint (android.graphics.Paint)170 WindowManager (android.view.WindowManager)138 RemoteException (android.os.RemoteException)76 RectF (android.graphics.RectF)62 Bitmap (android.graphics.Bitmap)54 Resources (android.content.res.Resources)41 View (android.view.View)41 ArrayList (java.util.ArrayList)40 ImageView (android.widget.ImageView)37 Camera (android.hardware.Camera)36 Canvas (android.graphics.Canvas)31 Matrix (android.graphics.Matrix)29 Animator (android.animation.Animator)27 SuppressLint (android.annotation.SuppressLint)27 Configuration (android.content.res.Configuration)26 IOException (java.io.IOException)24 Message (android.os.Message)22