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