Merge changes I52110b84,I15d10a19,I5f52b832,Ifbaceb47

* changes:
  Remove spurious error logging from BackgroundDexOptService
  Migrate BackgroundDexOptServiceIntegrationTests to androidx.test
  Framework: Allow root to send bg-dexopt
  Fix BackgroundDexOptServiceIntegrationTests
This commit is contained in:
Andreas Gampe
2019-07-08 16:22:25 +00:00
committed by Gerrit Code Review
7 changed files with 56 additions and 29 deletions

View File

@@ -254,9 +254,16 @@ public class BackgroundDexOptService extends JobService {
@Override
public void run() {
int result = idleOptimization(pm, pkgs, BackgroundDexOptService.this);
if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
if (result == OPTIMIZE_PROCESSED) {
Log.i(TAG, "Idle optimizations completed.");
} else if (result == OPTIMIZE_ABORT_NO_SPACE_LEFT) {
Log.w(TAG, "Idle optimizations aborted because of space constraints.");
// If we didn't abort we ran to completion (or stopped because of space).
} else if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
Log.w(TAG, "Idle optimizations aborted by job scheduler.");
} else {
Log.w(TAG, "Idle optimizations ended with unexpected code: " + result);
}
if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
// Abandon our timeslice and do not reschedule.
jobFinished(jobParams, /* reschedule */ false);
}
@@ -339,6 +346,7 @@ public class BackgroundDexOptService extends JobService {
long lowStorageThreshold, boolean isForPrimaryDex) {
ArraySet<String> updatedPackages = new ArraySet<>();
Set<String> unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
boolean hadSomeLowSpaceFailure = false;
Log.d(TAG, "Unsused Packages " + String.join(",", unusedPackages));
// Only downgrade apps when space is low on device.
// Threshold is selected above the lowStorageThreshold so that we can pro-actively clean
@@ -359,6 +367,7 @@ public class BackgroundDexOptService extends JobService {
} else {
if (abort_code == OPTIMIZE_ABORT_NO_SPACE_LEFT) {
// can't dexopt because of low space.
hadSomeLowSpaceFailure = true;
continue;
}
dex_opt_performed = optimizePackage(pm, pkg, isForPrimaryDex);
@@ -369,7 +378,7 @@ public class BackgroundDexOptService extends JobService {
}
notifyPinService(updatedPackages);
return OPTIMIZE_PROCESSED;
return hadSomeLowSpaceFailure ? OPTIMIZE_ABORT_NO_SPACE_LEFT : OPTIMIZE_PROCESSED;
}

View File

@@ -9004,6 +9004,20 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
/**
* Enforces that only the system UID or root's UID or shell's UID can call
* a method exposed via Binder.
*
* @param message used as message if SecurityException is thrown
* @throws SecurityException if the caller is not system or shell
*/
private static void enforceSystemOrRootOrShell(String message) {
final int uid = Binder.getCallingUid();
if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
throw new SecurityException(message);
}
}
@Override
public void performFstrimIfNeeded() {
enforceSystemOrRoot("Only the system can request fstrim");
@@ -9498,7 +9512,13 @@ public class PackageManagerService extends IPackageManager.Stub
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return false;
}
return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
enforceSystemOrRootOrShell("runBackgroundDexoptJob");
final long identity = Binder.clearCallingIdentity();
try {
return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
private static List<SharedLibraryInfo> findSharedLibraries(PackageParser.Package p) {

View File

@@ -1334,6 +1334,7 @@ class PackageManagerShellCommand extends ShellCommand {
}
boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
packageNames);
getOutPrintWriter().println(result ? "Success" : "Failure");
return result ? 0 : -1;
}

View File

@@ -17,7 +17,7 @@
android_test {
name: "BackgroundDexOptServiceIntegrationTests",
srcs: ["src/**/*.java"],
static_libs: ["android-support-test"],
static_libs: ["androidx.test.rules"],
platform_apis: true,
test_suites: ["device-tests"],
certificate: "platform",

View File

@@ -34,7 +34,7 @@
</application>
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.frameworks.bgdexopttest"
android:label="Integration test for BackgroundDexOptService" />
</manifest>

View File

@@ -50,6 +50,6 @@
<option name="test-tag" value="BackgroundDexOptServiceIntegrationTests"/>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.frameworks.bgdexopttest"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
</test>
</configuration>

View File

@@ -19,13 +19,14 @@ package com.android.server.pm;
import android.app.AlarmManager;
import android.content.Context;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.os.storage.StorageManager;
import android.support.test.InstrumentationRegistry;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -34,6 +35,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -141,27 +143,19 @@ public final class BackgroundDexOptServiceIntegrationTests {
// Run the command and return the stdout.
private static String runShellCommand(String cmd) throws IOException {
Log.i(TAG, String.format("running command: '%s'", cmd));
long startTime = System.nanoTime();
Process p = Runtime.getRuntime().exec(cmd);
int res;
try {
res = p.waitFor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation()
.executeShellCommand(cmd);
byte[] buf = new byte[512];
int bytesRead;
FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
StringBuilder stdout = new StringBuilder();
while ((bytesRead = fis.read(buf)) != -1) {
stdout.append(new String(buf, 0, bytesRead));
}
String stdout = inputStreamToString(p.getInputStream());
String stderr = inputStreamToString(p.getErrorStream());
long elapsedTime = System.nanoTime() - startTime;
Log.i(TAG, String.format("ran command: '%s' in %d ms with return code %d", cmd,
TimeUnit.NANOSECONDS.toMillis(elapsedTime), res));
fis.close();
Log.i(TAG, "stdout");
Log.i(TAG, stdout);
Log.i(TAG, "stderr");
Log.i(TAG, stderr);
if (res != 0) {
throw new RuntimeException(String.format("failed command: '%s'", cmd));
}
return stdout;
Log.i(TAG, stdout.toString());
return stdout.toString();
}
// Run the command and return the stdout split by lines.
@@ -209,7 +203,10 @@ public final class BackgroundDexOptServiceIntegrationTests {
// TODO(aeubanks): figure out how to get scheduled bg-dexopt to run
private static void runBackgroundDexOpt() throws IOException {
runShellCommand("cmd package bg-dexopt-job " + PACKAGE_NAME);
String result = runShellCommand("cmd package bg-dexopt-job " + PACKAGE_NAME);
if (!result.trim().equals("Success")) {
throw new IllegalStateException("Expected command success, received >" + result + "<");
}
}
// Set the time ahead of the last use time of the test app in days.