BackgroundDexOptService.java revision cf1a2f73fc102be2ac7060ac97d4682bb2565ca5
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
19cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobInfo;
20cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobParameters;
21cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobScheduler;
22cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.app.job.JobService;
23cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tateimport android.content.ComponentName;
247395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport android.content.Context;
257395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport android.os.ServiceManager;
267395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport android.util.Log;
277395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
287395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport java.util.HashSet;
297395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstromimport java.util.concurrent.atomic.AtomicBoolean;
307395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
317395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom/**
327395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom * {@hide}
337395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom */
34cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tatepublic class BackgroundDexOptService extends JobService {
357395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    static final String TAG = "BackgroundDexOptService";
367395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
37cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    static final int BACKGROUND_DEXOPT_JOB = 808;
38cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    private static ComponentName sDexoptServiceName = new ComponentName(
39cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate            BackgroundDexOptService.class.getPackage().getName(),
40cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate            BackgroundDexOptService.class.getName());
417395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
427395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    final AtomicBoolean mIdleTime = new AtomicBoolean(false);
437395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
44cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    public static void schedule(Context context) {
45cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
46cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        JobInfo job = new JobInfo.Builder(BACKGROUND_DEXOPT_JOB, sDexoptServiceName)
47cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                .setRequiresDeviceIdle(true)
48cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                .setRequiresCharging(true)
49cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                .build();
50cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        js.schedule(job);
517395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    }
527395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
53cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    @Override
54cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    public boolean onStartJob(JobParameters params) {
557395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        Log.i(TAG, "onIdleStart");
56cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        final PackageManagerService pm =
57cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                (PackageManagerService)ServiceManager.getService("package");
58cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate
59cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        if (pm.isStorageLow()) {
607395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            return false;
617395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        }
62cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        final HashSet<String> pkgs = pm.getPackagesThatNeedDexOpt();
637395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        if (pkgs == null) {
647395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            return false;
657395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        }
66cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate
67cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        final JobParameters jobParams = params;
687395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        mIdleTime.set(true);
697395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        new Thread("BackgroundDexOptService_DexOpter") {
707395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            @Override
717395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            public void run() {
727395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                for (String pkg : pkgs) {
737395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                    if (!mIdleTime.get()) {
74cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                        // stopped while still working, so we need to reschedule
75cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                        schedule(BackgroundDexOptService.this);
76cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                        return;
777395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                    }
78cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                    pm.performDexOpt(pkg, false);
797395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom                }
80cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                // ran to completion, so we abandon our timeslice and do not reschedule
81cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate                jobFinished(jobParams, false);
827395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            }
837395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        }.start();
847395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        return true;
857395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    }
867395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom
87cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    @Override
88cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate    public boolean onStopJob(JobParameters params) {
897395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        Log.i(TAG, "onIdleStop");
907395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom        mIdleTime.set(false);
91cf1a2f73fc102be2ac7060ac97d4682bb2565ca5Christopher Tate        return false;
927395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom    }
937395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom}
94