1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.targetprep; 17 18 import com.android.tradefed.config.Option; 19 import com.android.tradefed.config.OptionClass; 20 import com.android.tradefed.device.DeviceNotAvailableException; 21 import com.android.tradefed.device.ITestDevice; 22 import com.android.tradefed.invoker.TestInformation; 23 24 import java.util.ArrayList; 25 import java.util.Arrays; 26 import java.util.List; 27 import java.util.concurrent.TimeUnit; 28 29 /** 30 * Reads the list of packages on the phone and sets all packages to be 'last used' 24 hrs ago. 31 * Writes to /data/system/package-usage.list and deletes it at teardown. 32 */ 33 @OptionClass(alias = "set-packages-recently-used") 34 public class SetPackagesRecentlyUsed extends BaseTargetPreparer { 35 36 private static final String LINE_PREFIX = "package:"; 37 private static final String PACKAGE_USAGE_FILE = "/data/system/package-usage.list"; 38 39 @Option( 40 name = "package-recently-used-time", 41 description = "Time since package last used", 42 isTimeVal = true 43 ) 44 private long mRecentTimeMillis = TimeUnit.DAYS.toMillis(1); 45 46 @Option( 47 name = "package-recently-used-name", 48 description = "Package(s) to set. If none specified, then all are set." 49 ) 50 private List<String> mPackages = new ArrayList<>(); 51 52 @Override setUp(TestInformation testInfo)53 public void setUp(TestInformation testInfo) 54 throws TargetSetupError, BuildError, DeviceNotAvailableException { 55 // Need to set this prop to ensure that postinstall dex2opt scripts run 56 // successfully 57 testInfo.getDevice().executeShellCommand("setprop persist.pm.mock-upgrade true"); 58 long deviceTimeMillis = testInfo.getDevice().getDeviceDate(); 59 long deviceRecentMillis = deviceTimeMillis - mRecentTimeMillis; 60 StringBuilder builder = new StringBuilder(); 61 builder.append("PACKAGE_USAGE__VERSION_1\n"); 62 for (String p : getPackagesToSet(testInfo.getDevice())) { 63 if (p.startsWith(LINE_PREFIX)) { 64 builder.append(p.substring(LINE_PREFIX.length())); 65 builder.append(" "); 66 builder.append(Long.toString(deviceRecentMillis)); 67 builder.append(" 0 0 0 0 0 0 0\n"); 68 } 69 } 70 testInfo.getDevice().pushString(builder.toString(), PACKAGE_USAGE_FILE); 71 } 72 getPackagesToSet(ITestDevice device)73 private List<String> getPackagesToSet(ITestDevice device) throws DeviceNotAvailableException { 74 if (mPackages.isEmpty()) { 75 String packageString; 76 try { 77 String res = device.executeShellCommand("cmd package list package -a"); 78 if (res == null || res.contains("Error: Unknown option: -a")) { 79 throw new RuntimeException(); 80 } 81 packageString = res; 82 } catch (RuntimeException e) { 83 packageString = device.executeShellCommand("cmd package list package"); 84 } 85 String[] packages = packageString.split("\n"); 86 return Arrays.asList(packages); 87 } else { 88 return mPackages; 89 } 90 } 91 92 @Override tearDown(TestInformation testInfo, Throwable e)93 public void tearDown(TestInformation testInfo, Throwable e) throws DeviceNotAvailableException { 94 testInfo.getDevice().executeShellCommand("rm " + PACKAGE_USAGE_FILE); 95 } 96 } 97