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