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

Commit 8bad754b authored by Xin Guan's avatar Xin Guan Committed by Android (Google) Code Review
Browse files

Merge "Offload some processing to IoThread" into main

parents d94aa06d 67b54235
Loading
Loading
Loading
Loading
+156 −137
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
@@ -201,7 +202,8 @@ public class UsageStatsService extends SystemService implements
    static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9;

    private final Object mLock = new Object();
    Handler mHandler;
    private Handler mHandler;
    private Handler mIoHandler;
    AppOpsManager mAppOps;
    UserManager mUserManager;
    PackageManager mPackageManager;
@@ -233,7 +235,7 @@ public class UsageStatsService extends SystemService implements
    private final SparseArray<LinkedList<Event>> mReportedEvents = new SparseArray<>();
    final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray();
    final SparseArray<ActivityData> mVisibleActivities = new SparseArray();
    @GuardedBy("mLock")
    @GuardedBy("mLaunchTimeAlarmQueues") // Don't hold the main lock
    private final SparseArray<LaunchTimeAlarmQueue> mLaunchTimeAlarmQueues = new SparseArray<>();
    @GuardedBy("mUsageEventListeners") // Don't hold the main lock when calling out
    private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners =
@@ -279,6 +281,38 @@ public class UsageStatsService extends SystemService implements
        }
    }

    private final Handler.Callback mIoHandlerCallback = (msg) -> {
        switch (msg.what) {
            case MSG_UID_STATE_CHANGED: {
                final int uid = msg.arg1;
                final int procState = msg.arg2;

                final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
                synchronized (mUidToKernelCounter) {
                    final int oldCounter = mUidToKernelCounter.get(uid, 0);
                    if (newCounter != oldCounter) {
                        mUidToKernelCounter.put(uid, newCounter);
                        try {
                            FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter);
                        } catch (IOException e) {
                            Slog.w(TAG, "Failed to update counter set: " + e);
                        }
                    }
                }
                return true;
            }
            case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: {
                final int userId = msg.arg1;
                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
                        "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")");
                handleEstimatedLaunchTimesOnUserUnlock(userId);
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                return true;
            }
        }
        return false;
    };

    private final Injector mInjector;

    public UsageStatsService(Context context) {
@@ -299,6 +333,7 @@ public class UsageStatsService extends SystemService implements
        mPackageManager = getContext().getPackageManager();
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mHandler = new H(BackgroundThread.get().getLooper());
        mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback);

        mAppStandby = mInjector.getAppStandbyController(getContext());
        mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext());
@@ -424,6 +459,9 @@ public class UsageStatsService extends SystemService implements
            }
            mUserUnlockedStates.remove(userId);
            mUserState.put(userId, null); // release the service (mainly for GC)
        }

        synchronized (mLaunchTimeAlarmQueues) {
            LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
            if (alarmQueue != null) {
                alarmQueue.removeAllAlarms();
@@ -479,10 +517,12 @@ public class UsageStatsService extends SystemService implements
            }
            reportEvent(unlockEvent, userId);

            mHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget();
            mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK,
                    userId, 0).sendToTarget();

            // Remove all the stats stored in system DE.
            deleteRecursively(new File(Environment.getDataSystemDeDirectory(userId), "usagestats"));

            // Force a flush to disk for the current user to ensure important events are persisted.
            // Note: there is a very very small chance that the system crashes between deleting
            // the stats above from DE and persisting them to CE here in which case we will lose
@@ -601,7 +641,7 @@ public class UsageStatsService extends SystemService implements
    private final IUidObserver mUidObserver = new UidObserver() {
        @Override
        public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
            mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
            mIoHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
        }

        @Override
@@ -673,16 +713,18 @@ public class UsageStatsService extends SystemService implements
                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED);
    }

    private static void deleteRecursively(File f) {
        File[] files = f.listFiles();
    private static void deleteRecursively(final File path) {
        if (path.isDirectory()) {
            final File[] files = path.listFiles();
            if (files != null) {
                for (File subFile : files) {
                    deleteRecursively(subFile);
                }
            }
        }

        if (f.exists() && !f.delete()) {
            Slog.e(TAG, "Failed to delete " + f);
        if (path.exists() && !path.delete()) {
            Slog.e(TAG, "Failed to delete " + path);
        }
    }

@@ -1244,6 +1286,9 @@ public class UsageStatsService extends SystemService implements
            Slog.i(TAG, "Removing user " + userId + " and all data.");
            mUserState.remove(userId);
            mAppTimeLimit.onUserRemoved(userId);
        }

        synchronized (mLaunchTimeAlarmQueues) {
            final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
            if (alarmQueue != null) {
                alarmQueue.removeAllAlarms();
@@ -1274,6 +1319,13 @@ public class UsageStatsService extends SystemService implements
            }
        }

        synchronized (mLaunchTimeAlarmQueues) {
            final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
            if (alarmQueue != null) {
                alarmQueue.removeAlarmForKey(packageName);
            }
        }

        final int tokenRemoved;
        synchronized (mLock) {
            final long timeRemoved = System.currentTimeMillis();
@@ -1282,10 +1334,7 @@ public class UsageStatsService extends SystemService implements
                // when the user service is initialized and package manager is queried.
                return;
            }
            final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
            if (alarmQueue != null) {
                alarmQueue.removeAlarmForKey(packageName);
            }

            final UserUsageStatsService userService = mUserState.get(userId);
            if (userService == null) {
                return;
@@ -1495,23 +1544,27 @@ public class UsageStatsService extends SystemService implements
            estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName);
            mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime);

            synchronized (mLock) {
            getOrCreateLaunchTimeAlarmQueue(userId).addAlarm(packageName,
                    SystemClock.elapsedRealtime() + (estimatedLaunchTime - now));
        }
        return estimatedLaunchTime;
    }

    private LaunchTimeAlarmQueue getOrCreateLaunchTimeAlarmQueue(int userId) {
        synchronized (mLaunchTimeAlarmQueues) {
            LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
            if (alarmQueue == null) {
                alarmQueue = new LaunchTimeAlarmQueue(
                    userId, getContext(), BackgroundThread.get().getLooper());
                mLaunchTimeAlarmQueues.put(userId, alarmQueue);
            }
                alarmQueue.addAlarm(packageName,
                        SystemClock.elapsedRealtime() + (estimatedLaunchTime - now));
            }

            return alarmQueue;
        }
        return estimatedLaunchTime;
    }

    @CurrentTimeMillisLong
    private long calculateEstimatedPackageLaunchTime(int userId, String packageName) {
        synchronized (mLock) {
        final long endTime = System.currentTimeMillis();
        final long beginTime = endTime - ONE_WEEK;
        final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS;
@@ -1549,7 +1602,6 @@ public class UsageStatsService extends SystemService implements
        } while (events.getNextEvent(event));
        return unknownTime;
    }
    }

    @CurrentTimeMillisLong
    private static long calculateNextLaunchTime(
@@ -1569,7 +1621,6 @@ public class UsageStatsService extends SystemService implements
    }

    private void handleEstimatedLaunchTimesOnUserUnlock(int userId) {
        synchronized (mLock) {
        final long nowElapsed = SystemClock.elapsedRealtime();
        final long now = System.currentTimeMillis();
        final long beginTime = now - ONE_WEEK;
@@ -1580,13 +1631,8 @@ public class UsageStatsService extends SystemService implements
        }
        final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>();
        final UsageEvents.Event event = new UsageEvents.Event();
            LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
            if (alarmQueue == null) {
                alarmQueue = new LaunchTimeAlarmQueue(
                        userId, getContext(), BackgroundThread.get().getLooper());
                mLaunchTimeAlarmQueues.put(userId, alarmQueue);
            }
        boolean changedTimes = false;
        final LaunchTimeAlarmQueue alarmQueue = getOrCreateLaunchTimeAlarmQueue(userId);
        for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent;
                unprocessedEvent = events.getNextEvent(event)) {
            final String packageName = event.getPackageName();
@@ -1625,7 +1671,6 @@ public class UsageStatsService extends SystemService implements
            mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
        }
    }
    }

    private void setEstimatedLaunchTime(int userId, String packageName,
            @CurrentTimeMillisLong long estimatedLaunchTime) {
@@ -1995,37 +2040,11 @@ public class UsageStatsService extends SystemService implements
                case MSG_PACKAGE_REMOVED:
                    onPackageRemoved(msg.arg1, (String) msg.obj);
                    break;
                case MSG_UID_STATE_CHANGED: {
                    final int uid = msg.arg1;
                    final int procState = msg.arg2;

                    final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
                    synchronized (mUidToKernelCounter) {
                        final int oldCounter = mUidToKernelCounter.get(uid, 0);
                        if (newCounter != oldCounter) {
                            mUidToKernelCounter.put(uid, newCounter);
                            try {
                                FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter);
                            } catch (IOException e) {
                                Slog.w(TAG, "Failed to update counter set: " + e);
                            }
                        }
                    }
                    break;
                }
                case MSG_ON_START:
                    synchronized (mLock) {
                        loadGlobalComponentUsageLocked();
                    }
                    break;
                case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: {
                    final int userId = msg.arg1;
                    Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
                            "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")");
                    handleEstimatedLaunchTimesOnUserUnlock(userId);
                    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                }
                break;
                case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: {
                    removeMessages(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);