BackgroundDexOptService.java revision db4a79a5d7d348e9d2286d95d4e5a59dd484456f
17395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom/*
27395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * Copyright (C) 2014 The Android Open Source Project
37395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom *
47395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
57395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * you may not use this file except in compliance with the License.
67395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * You may obtain a copy of the License at
77395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom *
87395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
97395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom *
107395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
117395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
127395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * See the License for the specific language governing permissions and
147395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * limitations under the License.
157395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom */
167395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
177395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrompackage com.android.server.pm;
187395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
192c9655b3d4c1fb0687baa14730c6d97ab5a56789Christopher Tateimport android.app.AlarmManager;
20cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobInfo;
21cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobParameters;
22cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobScheduler;
23cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobService;
24cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.content.ComponentName;
257395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport android.content.Context;
267395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport android.os.ServiceManager;
27db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravleimport android.os.SystemProperties;
289f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkeyimport android.util.ArraySet;
297395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport android.util.Log;
307395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
317395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport java.util.concurrent.atomic.AtomicBoolean;
3227c073796978106746e4a51f2100b29068ab37f6Nicolas Geoffrayimport java.util.concurrent.TimeUnit;
337395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
347395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom/**
357395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * {@hide}
367395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom */
37cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tatepublic class BackgroundDexOptService extends JobService {
387395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    static final String TAG = "BackgroundDexOptService";
397395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
402c9655b3d4c1fb0687baa14730c6d97ab5a56789Christopher Tate    static final long RETRY_LATENCY = 4 * AlarmManager.INTERVAL_HOUR;
412c9655b3d4c1fb0687baa14730c6d97ab5a56789Christopher Tate
421b8b3aa265190e84467f740e99a0ade3a0e3cd67Christopher Tate    static final int BACKGROUND_DEXOPT_JOB = 800;
43cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    private static ComponentName sDexoptServiceName = new ComponentName(
441b8b3aa265190e84467f740e99a0ade3a0e3cd67Christopher Tate            "android",
45cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate            BackgroundDexOptService.class.getName());
467395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
47a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom    /**
48a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom     * Set of failed packages remembered across job runs.
49a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom     */
50a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom    static final ArraySet<String> sFailedPackageNames = new ArraySet<String>();
51a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom
527395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    final AtomicBoolean mIdleTime = new AtomicBoolean(false);
537395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
54db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle    private boolean useJitProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
55db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle
56db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle    public static void schedule(Context context) {
57cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
58cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        JobInfo job = new JobInfo.Builder(BACKGROUND_DEXOPT_JOB, sDexoptServiceName)
59cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                .setRequiresDeviceIdle(true)
60cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                .setRequiresCharging(true)
6127c073796978106746e4a51f2100b29068ab37f6Nicolas Geoffray                .setPeriodic(TimeUnit.DAYS.toMillis(1))
62cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                .build();
63cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        js.schedule(job);
647395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    }
657395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
66cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    @Override
67cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    public boolean onStartJob(JobParameters params) {
68db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle        Log.i(TAG, "onStartJob");
69cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        final PackageManagerService pm =
70cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                (PackageManagerService)ServiceManager.getService("package");
71cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate
72cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        if (pm.isStorageLow()) {
73db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle            Log.i(TAG, "Low storage, skipping this run");
747395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            return false;
757395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        }
76db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle        final ArraySet<String> pkgs = pm.getOptimizablePackages();
77db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle        if (pkgs == null || pkgs.isEmpty()) {
78db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle            Log.i(TAG, "No packages to optimize");
797395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            return false;
807395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        }
81cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate
82cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        final JobParameters jobParams = params;
837395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        mIdleTime.set(true);
847395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        new Thread("BackgroundDexOptService_DexOpter") {
857395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            @Override
867395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            public void run() {
877395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                for (String pkg : pkgs) {
887395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                    if (!mIdleTime.get()) {
89db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle                        // Out of the idle state. Stop the compilation.
90cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                        return;
917395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                    }
92a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                    if (sFailedPackageNames.contains(pkg)) {
93a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                        // skip previously failing package
94a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                        continue;
95a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                    }
96db4a79a5d7d348e9d2286d95d4e5a59dd484456fCalin Juravle                    if (!pm.performDexOpt(pkg, /* instruction set */ null, useJitProfiles)) {
97a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                        // there was a problem running dexopt,
98a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                        // remember this so we do not keep retrying.
99a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                        sFailedPackageNames.add(pkg);
100a00be9b4d521287fdf4678fb196c3e3a0053c3e4Brian Carlstrom                    }
1017395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                }
102cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                // ran to completion, so we abandon our timeslice and do not reschedule
103cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                jobFinished(jobParams, false);
1047395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            }
1057395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        }.start();
1067395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        return true;
1077395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    }
1087395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
109cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    @Override
110cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    public boolean onStopJob(JobParameters params) {
1117395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        Log.i(TAG, "onIdleStop");
1127395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        mIdleTime.set(false);
113cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        return false;
1147395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    }
1157395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom}
116