Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51a14f20 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Track process with visible activities"

parents 7ef0432b fb3c0995
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -1252,7 +1252,6 @@ class ProcessRecord implements WindowProcessListener {

    void setHasForegroundActivities(boolean hasForegroundActivities) {
        mHasForegroundActivities = hasForegroundActivities;
        mWindowProcessController.setHasForegroundActivities(hasForegroundActivities);
    }

    boolean hasForegroundActivities() {
+0 −11
Original line number Diff line number Diff line
@@ -445,7 +445,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    private Task task;              // the task this is in.
    private long createTime = System.currentTimeMillis();
    long lastVisibleTime;         // last time this activity became visible
    long cpuTimeAtResume;         // the cpu time of host process at the time of resuming activity
    long pauseTime;               // last time we started pausing the activity
    long launchTickTime;          // base time for launch tick messages
    long topResumedStateLossTime; // last time we reported top resumed state loss to an activity
@@ -5010,16 +5009,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        resumeKeyDispatchingLocked();
        final Task stack = getRootTask();
        mStackSupervisor.mNoAnimActivities.clear();

        // Mark the point when the activity is resuming
        // TODO: To be more accurate, the mark should be before the onCreate,
        //       not after the onResume. But for subsequent starts, onResume is fine.
        if (hasProcess()) {
            cpuTimeAtResume = app.getCpuTime();
        } else {
            cpuTimeAtResume = 0; // Couldn't get the cpu time of process
        }

        returningOptions = null;

        if (canTurnScreenOn()) {
+4 −10
Original line number Diff line number Diff line
@@ -366,6 +366,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    PendingIntentController mPendingIntentController;
    IntentFirewall mIntentFirewall;

    final VisibleActivityProcessTracker mVisibleActivityProcessTracker;

    /* Global service lock used by the package the owns this service. */
    final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
    /**
@@ -741,6 +743,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        mSystemThread = ActivityThread.currentActivityThread();
        mUiContext = mSystemThread.getSystemUiContext();
        mLifecycleManager = new ClientLifecycleManager();
        mVisibleActivityProcessTracker = new VisibleActivityProcessTracker(this);
        mInternal = new LocalService();
        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
        mWindowOrganizerController = new WindowOrganizerController(this);
@@ -6103,16 +6106,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

        @Override
        public boolean hasResumedActivity(int uid) {
            synchronized (mGlobalLock) {
                final ArraySet<WindowProcessController> processes = mProcessMap.getProcesses(uid);
                for (int i = 0, n = processes.size(); i < n; i++) {
                    final WindowProcessController process = processes.valueAt(i);
                    if (process.hasResumedActivity()) {
                        return true;
                    }
                }
            }
            return false;
            return mVisibleActivityProcessTracker.hasResumedActivity(uid);
        }

        public void setBackgroundActivityStartCallback(
+0 −14
Original line number Diff line number Diff line
@@ -162,7 +162,6 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.AppGlobals;
@@ -5689,19 +5688,6 @@ class Task extends WindowContainer<WindowContainer> {

        if (prev != null) {
            prev.resumeKeyDispatchingLocked();

            if (prev.hasProcess() && prev.cpuTimeAtResume > 0) {
                final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
                if (diff > 0) {
                    final Runnable r = PooledLambda.obtainRunnable(
                            ActivityManagerInternal::updateForegroundTimeIfOnBattery,
                            mAtmService.mAmInternal, prev.info.packageName,
                            prev.info.applicationInfo.uid,
                            diff);
                    mAtmService.mH.post(r);
                }
            }
            prev.cpuTimeAtResume = 0; // reset it
        }

        mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm;

import android.util.ArrayMap;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;

import java.util.concurrent.Executor;

/**
 * A quick lookup for all processes with visible activities. It also tracks the CPU usage of
 * host process with foreground (resumed) activity.
 */
class VisibleActivityProcessTracker {
    @GuardedBy("mProcMap")
    private final ArrayMap<WindowProcessController, CpuTimeRecord> mProcMap = new ArrayMap<>();
    final Executor mBgExecutor = BackgroundThread.getExecutor();
    final ActivityTaskManagerService mAtms;

    VisibleActivityProcessTracker(ActivityTaskManagerService atms) {
        mAtms = atms;
    }

    /** Called when any activity is visible in the process that didn't have one. */
    void onAnyActivityVisible(WindowProcessController wpc) {
        final CpuTimeRecord r = new CpuTimeRecord(wpc);
        synchronized (mProcMap) {
            mProcMap.put(wpc, r);
        }
        if (wpc.hasResumedActivity()) {
            r.mShouldGetCpuTime = true;
            mBgExecutor.execute(r);
        }
    }

    /** Called when all visible activities of the process are no longer visible. */
    void onAllActivitiesInvisible(WindowProcessController wpc) {
        final CpuTimeRecord r = removeProcess(wpc);
        if (r != null && r.mShouldGetCpuTime) {
            mBgExecutor.execute(r);
        }
    }

    /** Called when an activity is resumed on a process which is known to have visible activity. */
    void onActivityResumedWhileVisible(WindowProcessController wpc) {
        final CpuTimeRecord r;
        synchronized (mProcMap) {
            r = mProcMap.get(wpc);
        }
        if (r != null && !r.mShouldGetCpuTime) {
            r.mShouldGetCpuTime = true;
            mBgExecutor.execute(r);
        }
    }

    boolean hasResumedActivity(int uid) {
        synchronized (mProcMap) {
            for (int i = mProcMap.size() - 1; i >= 0; i--) {
                final WindowProcessController wpc = mProcMap.keyAt(i);
                if (wpc.mUid == uid && wpc.hasResumedActivity()) {
                    return true;
                }
            }
        }
        return false;
    }

    CpuTimeRecord removeProcess(WindowProcessController wpc) {
        synchronized (mProcMap) {
            return mProcMap.remove(wpc);
        }
    }

    /**
     * Get CPU time in background thread because it will access proc files or the lock of cpu
     * tracker is held by a background thread.
     */
    private class CpuTimeRecord implements Runnable {
        private final WindowProcessController mProc;
        private long mCpuTime;
        private boolean mHasStartCpuTime;
        boolean mShouldGetCpuTime;

        CpuTimeRecord(WindowProcessController wpc) {
            mProc = wpc;
        }

        @Override
        public void run() {
            if (mProc.getPid() == 0) {
                // The process is dead.
                return;
            }
            if (!mHasStartCpuTime) {
                mHasStartCpuTime = true;
                mCpuTime = mProc.getCpuTime();
            } else {
                final long diff = mProc.getCpuTime() - mCpuTime;
                if (diff > 0) {
                    mAtms.mAmInternal.updateForegroundTimeIfOnBattery(
                            mProc.mInfo.packageName, mProc.mInfo.uid, diff);
                }
            }
        }
    }
}
Loading