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

Commit 9602bec9 authored by Kweku Adams's avatar Kweku Adams
Browse files

Cache frequently used LocalServices.

Any LocalServices object that is reused in a class should be cached locally
so that we avoid repeated lookups within the LocalServices map,
especially during tight loops.

Bug: 295877092
Test: atest CtsJobSchedulerTestCases
Test: atest FrameworksMockingServicesTests:JobStatusTest
Test: atest FrameworksMockingServicesTests:QuotaControllerTest
Change-Id: Ie8d90a0f8aebbb23138613095859e1f9ce1b207f
parent 0372edf8
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ public final class GrantedUriPermissions {
    private final int mSourceUserId;
    private final String mTag;
    private final IBinder mPermissionOwner;
    private final UriGrantsManagerInternal mUriGrantsManagerInternal;
    private final ArrayList<Uri> mUris = new ArrayList<>();

    private GrantedUriPermissions(int grantFlags, int uid, String tag)
@@ -45,13 +46,13 @@ public final class GrantedUriPermissions {
        mGrantFlags = grantFlags;
        mSourceUserId = UserHandle.getUserId(uid);
        mTag = tag;
        mPermissionOwner = LocalServices
                .getService(UriGrantsManagerInternal.class).newUriPermissionOwner("job: " + tag);
        mUriGrantsManagerInternal = LocalServices.getService(UriGrantsManagerInternal.class);
        mPermissionOwner = mUriGrantsManagerInternal.newUriPermissionOwner("job: " + tag);
    }

    public void revoke() {
        for (int i = mUris.size()-1; i >= 0; i--) {
            LocalServices.getService(UriGrantsManagerInternal.class).revokeUriPermissionFromOwner(
            mUriGrantsManagerInternal.revokeUriPermissionFromOwner(
                    mPermissionOwner, mUris.get(i), mGrantFlags, mSourceUserId);
        }
        mUris.clear();
+10 −9
Original line number Diff line number Diff line
@@ -235,7 +235,9 @@ class JobConcurrencyManager {
    private final Handler mHandler;
    private final Injector mInjector;

    private final ActivityManagerInternal mActivityManagerInternal;
    private PowerManager mPowerManager;
    private final UserManagerInternal mUserManagerInternal;

    private boolean mCurrentInteractiveState;
    private boolean mEffectiveInteractiveState;
@@ -507,6 +509,9 @@ class JobConcurrencyManager {
        mInjector = injector;
        mNotificationCoordinator = new JobNotificationCoordinator();

        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);

        mHandler = AppSchedulingModuleThread.getHandler();

        mGracePeriodObserver = new GracePeriodObserver(mContext);
@@ -1253,9 +1258,7 @@ class JobConcurrencyManager {
                return false;
            case PRIVILEGED_STATE_UNDEFINED:
            default:
                final ActivityManagerInternal activityManagerInternal =
                        LocalServices.getService(ActivityManagerInternal.class);
                final int procState = activityManagerInternal.getUidProcessState(uid);
                final int procState = mActivityManagerInternal.getUidProcessState(uid);
                if (procState == ActivityManager.PROCESS_STATE_TOP) {
                    cachedPrivilegedState.put(uid, PRIVILEGED_STATE_TOP);
                    return true;
@@ -1266,7 +1269,7 @@ class JobConcurrencyManager {
                }

                final BackgroundStartPrivileges bsp =
                        activityManagerInternal.getBackgroundStartPrivileges(uid);
                        mActivityManagerInternal.getBackgroundStartPrivileges(uid);
                if (DEBUG) {
                    Slog.d(TAG, "Job " + job.toShortString() + " bsp state: " + bsp);
                }
@@ -2213,19 +2216,17 @@ class JobConcurrencyManager {
    boolean shouldRunAsFgUserJob(JobStatus job) {
        if (!mShouldRestrictBgUser) return true;
        int userId = job.getSourceUserId();
        UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
        UserInfo userInfo = um.getUserInfo(userId);
        UserInfo userInfo = mUserManagerInternal.getUserInfo(userId);

        // If the user has a parent user (e.g. a work profile of another user), the user should be
        // treated equivalent as its parent user.
        if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
                && userInfo.profileGroupId != userId) {
            userId = userInfo.profileGroupId;
            userInfo = um.getUserInfo(userId);
            userInfo = mUserManagerInternal.getUserInfo(userId);
        }

        int currentUser = LocalServices.getService(ActivityManagerInternal.class)
                .getCurrentUserId();
        int currentUser = mActivityManagerInternal.getCurrentUserId();
        // A user is treated as foreground user if any of the followings is true:
        // 1. The user is current user
        // 2. The user is primary user
+10 −9
Original line number Diff line number Diff line
@@ -251,6 +251,9 @@ public class JobSchedulerService extends com.android.server.SystemService
        }
    };

    @VisibleForTesting
    public static UsageStatsManagerInternal sUsageStatsManagerInternal;

    /** Global local for all job scheduler state. */
    final Object mLock = new Object();
    /** Master list of jobs. */
@@ -358,8 +361,8 @@ public class JobSchedulerService extends com.android.server.SystemService
    DeviceIdleInternal mLocalDeviceIdleController;
    @VisibleForTesting
    AppStateTrackerImpl mAppStateTracker;
    final UsageStatsManagerInternal mUsageStats;
    private final AppStandbyInternal mAppStandbyInternal;
    private final BatteryStatsInternal mBatteryStatsInternal;

    /**
     * Set to true once we are allowed to run third party apps.
@@ -2416,7 +2419,7 @@ public class JobSchedulerService extends com.android.server.SystemService

        // Set up the app standby bucketing tracker
        mStandbyTracker = new StandbyTracker();
        mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
        sUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);

        final Categorizer quotaCategorizer = (userId, packageName, tag) -> {
            if (QUOTA_TRACKER_TIMEOUT_UIJ_TAG.equals(tag)) {
@@ -2467,6 +2470,8 @@ public class JobSchedulerService extends com.android.server.SystemService
        mAppStandbyInternal = LocalServices.getService(AppStandbyInternal.class);
        mAppStandbyInternal.addListener(mStandbyTracker);

        mBatteryStatsInternal = LocalServices.getService(BatteryStatsInternal.class);

        // The job store needs to call back
        publishLocalService(JobSchedulerInternal.class, new LocalService());

@@ -4127,7 +4132,7 @@ public class JobSchedulerService extends com.android.server.SystemService
                return;
            }

            long sinceLast = mUsageStats.getTimeSinceLastJobRun(packageName, userId);
            long sinceLast = sUsageStatsManagerInternal.getTimeSinceLastJobRun(packageName, userId);
            if (sinceLast > 2 * DateUtils.DAY_IN_MILLIS) {
                // Too long ago, not worth logging
                sinceLast = 0L;
@@ -4137,8 +4142,6 @@ public class JobSchedulerService extends com.android.server.SystemService
                mJobs.forEachJobForSourceUid(uid, counter);
            }
            if (counter.numDeferred() > 0 || sinceLast > 0) {
                BatteryStatsInternal mBatteryStatsInternal = LocalServices.getService
                        (BatteryStatsInternal.class);
                mBatteryStatsInternal.noteJobsDeferred(uid, counter.numDeferred(), sinceLast);
                FrameworkStatsLog.write_non_chained(
                        FrameworkStatsLog.DEFERRED_JOB_STATS_REPORTED, uid, null,
@@ -4183,10 +4186,8 @@ public class JobSchedulerService extends com.android.server.SystemService

    // Static to support external callers
    public static int standbyBucketForPackage(String packageName, int userId, long elapsedNow) {
        UsageStatsManagerInternal usageStats = LocalServices.getService(
                UsageStatsManagerInternal.class);
        int bucket = usageStats != null
                ? usageStats.getAppStandbyBucket(packageName, userId, elapsedNow)
        int bucket = sUsageStatsManagerInternal != null
                ? sUsageStatsManagerInternal.getAppStandbyBucket(packageName, userId, elapsedNow)
                : 0;

        bucket = standbyBucketToBucketIndex(bucket);
+4 −3
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ public final class JobServiceContext implements ServiceConnection {
    private final EconomyManagerInternal mEconomyManagerInternal;
    private final JobPackageTracker mJobPackageTracker;
    private final PowerManager mPowerManager;
    private final UsageStatsManagerInternal mUsageStatsManagerInternal;
    private PowerManager.WakeLock mWakeLock;

    // Execution state.
@@ -321,6 +322,7 @@ public final class JobServiceContext implements ServiceConnection {
        mNotificationCoordinator = notificationCoordinator;
        mCompletedListener = service;
        mPowerManager = mContext.getSystemService(PowerManager.class);
        mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);
        mAvailable = true;
        mVerb = VERB_FINISHED;
        mPreferredUid = NO_PREFERRED_UID;
@@ -535,9 +537,8 @@ public final class JobServiceContext implements ServiceConnection {
                // Whatever.
            }
            final int jobUserId = job.getSourceUserId();
            UsageStatsManagerInternal usageStats =
                    LocalServices.getService(UsageStatsManagerInternal.class);
            usageStats.setLastJobRunTime(sourcePackage, jobUserId, mExecutionStartTimeElapsed);
            mUsageStatsManagerInternal
                    .setLastJobRunTime(sourcePackage, jobUserId, mExecutionStartTimeElapsed);
            mAvailable = false;
            mStoppedReason = null;
            mStoppedTime = 0;
+11 −4
Original line number Diff line number Diff line
@@ -228,6 +228,8 @@ public final class JobStatus {
    /** The minimum possible update delay is 1 second. */
    public static final long MIN_TRIGGER_MAX_DELAY = 1000;

    private JobSchedulerInternal mJobSchedulerInternal;

    final JobInfo job;
    /**
     * Uid of the package requesting this job.  This can differ from the "source"
@@ -1152,8 +1154,10 @@ public final class JobStatus {
     * exemptions.
     */
    public int getEffectiveStandbyBucket() {
        final JobSchedulerInternal jsi = LocalServices.getService(JobSchedulerInternal.class);
        final boolean isBuggy = jsi.isAppConsideredBuggy(
        if (mJobSchedulerInternal == null) {
            mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
        }
        final boolean isBuggy = mJobSchedulerInternal.isAppConsideredBuggy(
                getUserId(), getServiceComponent().getPackageName(),
                getTimeoutBlameUserId(), getTimeoutBlamePackageName());

@@ -1262,12 +1266,15 @@ public final class JobStatus {
     * @return true if the exemption status changed
     */
    public boolean updateMediaBackupExemptionStatus() {
        final JobSchedulerInternal jsi = LocalServices.getService(JobSchedulerInternal.class);
        if (mJobSchedulerInternal == null) {
            mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
        }
        boolean hasMediaExemption = mHasExemptedMediaUrisOnly
                && !job.hasLateConstraint()
                && job.getRequiredNetwork() != null
                && getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT
                && sourcePackageName.equals(jsi.getCloudMediaProviderPackage(sourceUserId));
                && sourcePackageName.equals(
                        mJobSchedulerInternal.getCloudMediaProviderPackage(sourceUserId));
        if (mHasMediaBackupExemption == hasMediaExemption) {
            return false;
        }
Loading