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

Commit 2b55a755 authored by Willie Koomson's avatar Willie Koomson
Browse files

Move widget events job scheduling to background thread

The call to JobScheduler.schedule may block for several milliseconds due
to lock contention. Move this call to a background thread so that it
does not block system server start / cause a perf regression.

Bug: 431264524
Test: Boot device with added tracepoints
Test: CtsAppWidgetTestCases:WidgetEventsTest
Flag: EXEMPT bugfix

Change-Id: Id1ff87293a2408f33e2a1479c7c4ea16a0b0d2f7
parent 3d57c36d
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.app.PendingIntent;
import android.app.StatsManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
import android.app.job.JobScheduler;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
@@ -330,6 +331,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    private UserManager mUserManager;
    private AppOpsManager mAppOpsManager;
    private KeyguardManager mKeyguardManager;
    private JobScheduler mJobScheduler;
    private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
    private PackageManagerInternal mPackageManagerInternal;
    private ActivityManagerInternal mActivityManagerInternal;
@@ -384,6 +386,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        mKeyguardManager = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
        mJobScheduler = (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        if (removeAppWidgetServiceIoFromCriticalPath()) {
@@ -419,7 +422,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        mWidgetEventsReportIntervalMs = DeviceConfig.getLong(NAMESPACE_SYSTEMUI,
                SystemUiDeviceConfigFlags.WIDGET_EVENTS_REPORT_INTERVAL_MS,
                DEFAULT_WIDGET_EVENTS_REPORT_INTERVAL_MS);
        ReportWidgetEventsJob.schedule(mContext, mWidgetEventsReportIntervalMs);
        DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_SYSTEMUI,
                new HandlerExecutor(mCallbackHandler), this::handleSystemUiDeviceConfigChange);

@@ -458,6 +460,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        mAppOpsManagerInternal = LocalServices.getService(AppOpsManagerInternal.class);
        mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);
        registerPullCallbacks();
        // Schedule may take several milliseconds due to lock contention
        BackgroundThread.getExecutor().execute(
                () -> ReportWidgetEventsJob.schedule(mJobScheduler, mWidgetEventsReportIntervalMs));
    }

    /**
@@ -5638,7 +5643,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
                mWidgetEventsReportIntervalMs = properties.getLong(
                        SystemUiDeviceConfigFlags.WIDGET_EVENTS_REPORT_INTERVAL_MS,
                        /* defaultValue = */ mWidgetEventsReportIntervalMs);
                ReportWidgetEventsJob.schedule(mContext, mWidgetEventsReportIntervalMs);
                ReportWidgetEventsJob.schedule(mJobScheduler, mWidgetEventsReportIntervalMs);
            }
        }
    }
+4 −5
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.appwidget.AppWidgetManagerInternal;
import android.content.ComponentName;
import android.content.Context;
import android.util.Slog;

import com.android.internal.os.BackgroundThread;
@@ -40,10 +39,9 @@ public class ReportWidgetEventsJob extends JobService {
    private static final String NAMESPACE =
            "com.android.server.appwidget.AppWidgetServiceImpl.ReportWidgetEventsJob";

    static void schedule(Context context, long periodMillis) {
    static void schedule(JobScheduler jobScheduler, long periodMillis) {
        try {
            JobScheduler jobScheduler = context.getSystemService(JobScheduler.class)
                    .forNamespace(NAMESPACE);
            jobScheduler = jobScheduler.forNamespace(NAMESPACE);

            // If periodMillis is 0 or less, do not schedule a job. The event will be reported to
            // UsageStatsManager as soon as it is received from the widget view.
@@ -52,7 +50,8 @@ public class ReportWidgetEventsJob extends JobService {
                return;
            }

            ComponentName component = new ComponentName(context, ReportWidgetEventsJob.class);
            ComponentName component = new ComponentName("android",
                    ReportWidgetEventsJob.class.getName());
            JobInfo newJob = new JobInfo.Builder(JOB_ID, component)
                    .setRequiresDeviceIdle(false)
                    .setPeriodic(periodMillis)