Merge "Change watchdog PackageInfo to PackageConfig" into qt-dev

This commit is contained in:
Zimuzo Ezeozue
2019-04-25 09:58:52 +00:00
committed by Android (Google) Code Review
9 changed files with 148 additions and 162 deletions

View File

@@ -320,7 +320,7 @@ java_defaults {
"core/java/android/service/vr/IVrManager.aidl",
"core/java/android/service/vr/IVrStateCallbacks.aidl",
"core/java/android/service/watchdog/IExplicitHealthCheckService.aidl",
"core/java/android/service/watchdog/PackageInfo.aidl",
"core/java/android/service/watchdog/PackageConfig.aidl",
"core/java/android/print/ILayoutResultCallback.aidl",
"core/java/android/print/IPrinterDiscoveryObserver.aidl",
"core/java/android/print/IPrintDocumentAdapter.aidl",

View File

@@ -6839,19 +6839,19 @@ package android.service.watchdog {
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
method public abstract void onCancelHealthCheck(@NonNull String);
method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
method @NonNull public abstract java.util.List<android.service.watchdog.PackageInfo> onGetSupportedPackages();
method @NonNull public abstract java.util.List<android.service.watchdog.ExplicitHealthCheckService.PackageConfig> onGetSupportedPackages();
method public abstract void onRequestHealthCheck(@NonNull String);
field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
}
public final class PackageInfo implements android.os.Parcelable {
ctor public PackageInfo(@NonNull String, long);
public static final class ExplicitHealthCheckService.PackageConfig implements android.os.Parcelable {
ctor public ExplicitHealthCheckService.PackageConfig(@NonNull String, long);
method public int describeContents();
method public long getHealthCheckTimeoutMillis();
method @NonNull public String getPackageName();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.watchdog.PackageInfo> CREATOR;
field @NonNull public static final android.os.Parcelable.Creator<android.service.watchdog.ExplicitHealthCheckService.PackageConfig> CREATOR;
}
}

View File

@@ -16,6 +16,8 @@
package android.service.watchdog;
import static android.os.Parcelable.Creator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
@@ -26,13 +28,18 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* A service to provide packages supporting explicit health checks and route checks to these
@@ -61,7 +68,7 @@ public abstract class ExplicitHealthCheckService extends Service {
private static final String TAG = "ExplicitHealthCheckService";
/**
* {@link Bundle} key for a {@link List} of {@link PackageInfo} value.
* {@link Bundle} key for a {@link List} of {@link PackageConfig} value.
*
* {@hide}
*/
@@ -130,7 +137,7 @@ public abstract class ExplicitHealthCheckService extends Service {
*
* @return all packages supporting explicit health checks
*/
@NonNull public abstract List<PackageInfo> onGetSupportedPackages();
@NonNull public abstract List<PackageConfig> onGetSupportedPackages();
/**
* Called when the system requests for all the packages that it has currently requested
@@ -167,6 +174,112 @@ public abstract class ExplicitHealthCheckService extends Service {
});
}
/**
* A PackageConfig contains a package supporting explicit health checks and the
* timeout in {@link System#uptimeMillis} across reboots after which health
* check requests from clients are failed.
*
* @hide
*/
@SystemApi
public static final class PackageConfig implements Parcelable {
// TODO: Receive from DeviceConfig flag
private static final long DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(1);
private final String mPackageName;
private final long mHealthCheckTimeoutMillis;
/**
* Creates a new instance.
*
* @param packageName the package name
* @param durationMillis the duration in milliseconds, must be greater than or
* equal to 0. If it is 0, it will use a system default value.
*/
public PackageConfig(@NonNull String packageName, long healthCheckTimeoutMillis) {
mPackageName = Preconditions.checkNotNull(packageName);
if (healthCheckTimeoutMillis == 0) {
mHealthCheckTimeoutMillis = DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS;
} else {
mHealthCheckTimeoutMillis = Preconditions.checkArgumentNonnegative(
healthCheckTimeoutMillis);
}
}
private PackageConfig(Parcel parcel) {
mPackageName = parcel.readString();
mHealthCheckTimeoutMillis = parcel.readLong();
}
/**
* Gets the package name.
*
* @return the package name
*/
public @NonNull String getPackageName() {
return mPackageName;
}
/**
* Gets the timeout in milliseconds to evaluate an explicit health check result after a
* request.
*
* @return the duration in {@link System#uptimeMillis} across reboots
*/
public long getHealthCheckTimeoutMillis() {
return mHealthCheckTimeoutMillis;
}
@Override
public String toString() {
return "PackageConfig{" + mPackageName + ", " + mHealthCheckTimeoutMillis + "}";
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof PackageConfig)) {
return false;
}
PackageConfig otherInfo = (PackageConfig) other;
return Objects.equals(otherInfo.getHealthCheckTimeoutMillis(),
mHealthCheckTimeoutMillis)
&& Objects.equals(otherInfo.getPackageName(), mPackageName);
}
@Override
public int hashCode() {
return Objects.hash(mPackageName, mHealthCheckTimeoutMillis);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mPackageName);
parcel.writeLong(mHealthCheckTimeoutMillis);
}
public static final @NonNull Creator<PackageConfig> CREATOR = new Creator<PackageConfig>() {
@Override
public PackageConfig createFromParcel(Parcel source) {
return new PackageConfig(source);
}
@Override
public PackageConfig[] newArray(int size) {
return new PackageConfig[size];
}
};
}
private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub {
@Override
public void setCallback(RemoteCallback callback) throws RemoteException {
@@ -188,7 +301,7 @@ public abstract class ExplicitHealthCheckService extends Service {
@Override
public void getSupportedPackages(RemoteCallback callback) throws RemoteException {
mHandler.post(() -> {
List<PackageInfo> packages =
List<PackageConfig> packages =
ExplicitHealthCheckService.this.onGetSupportedPackages();
Objects.requireNonNull(packages, "Supported package list must be non-null");
Bundle bundle = new Bundle();

View File

@@ -19,4 +19,4 @@ package android.service.watchdog;
/**
* @hide
*/
parcelable PackageInfo;
parcelable PackageConfig;

View File

@@ -1,130 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.service.watchdog;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* A PackageInfo contains a package supporting explicit health checks and the
* timeout in {@link System#uptimeMillis} across reboots after which health
* check requests from clients are failed.
*
* @hide
*/
@SystemApi
public final class PackageInfo implements Parcelable {
// TODO: Receive from DeviceConfig flag
private static final long DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(1);
private final String mPackageName;
private final long mHealthCheckTimeoutMillis;
/**
* Creates a new instance.
*
* @param packageName the package name
* @param durationMillis the duration in milliseconds, must be greater than or
* equal to 0. If it is 0, it will use a system default value.
*/
public PackageInfo(@NonNull String packageName, long healthCheckTimeoutMillis) {
mPackageName = Preconditions.checkNotNull(packageName);
if (healthCheckTimeoutMillis == 0) {
mHealthCheckTimeoutMillis = DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS;
} else {
mHealthCheckTimeoutMillis = Preconditions.checkArgumentNonnegative(
healthCheckTimeoutMillis);
}
}
private PackageInfo(Parcel parcel) {
mPackageName = parcel.readString();
mHealthCheckTimeoutMillis = parcel.readLong();
}
/**
* Gets the package name.
*
* @return the package name
*/
public @NonNull String getPackageName() {
return mPackageName;
}
/**
* Gets the timeout in milliseconds to evaluate an explicit health check result after a request.
*
* @return the duration in {@link System#uptimeMillis} across reboots
*/
public long getHealthCheckTimeoutMillis() {
return mHealthCheckTimeoutMillis;
}
@Override
public String toString() {
return "PackageInfo{" + mPackageName + ", " + mHealthCheckTimeoutMillis + "}";
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof PackageInfo)) {
return false;
}
PackageInfo otherInfo = (PackageInfo) other;
return Objects.equals(otherInfo.getHealthCheckTimeoutMillis(), mHealthCheckTimeoutMillis)
&& Objects.equals(otherInfo.getPackageName(), mPackageName);
}
@Override
public int hashCode() {
return Objects.hash(mPackageName, mHealthCheckTimeoutMillis);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mPackageName);
parcel.writeLong(mHealthCheckTimeoutMillis);
}
public static final @NonNull Creator<PackageInfo> CREATOR = new Creator<PackageInfo>() {
@Override
public PackageInfo createFromParcel(Parcel source) {
return new PackageInfo(source);
}
@Override
public PackageInfo[] newArray(int size) {
return new PackageInfo[size];
}
};
}

View File

@@ -16,11 +16,12 @@
package android.ext.services.watchdog;
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
import android.content.ComponentName;
import android.content.Intent;
import android.provider.DeviceConfig;
import android.service.watchdog.ExplicitHealthCheckService;
import android.service.watchdog.PackageInfo;
import android.util.Log;
import java.util.ArrayList;
@@ -74,8 +75,8 @@ public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckSer
}
@Override
public List<PackageInfo> onGetSupportedPackages() {
List<PackageInfo> packages = new ArrayList<>();
public List<PackageConfig> onGetSupportedPackages() {
List<PackageConfig> packages = new ArrayList<>();
long requestTimeoutMillis = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ROLLBACK,
PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS,
@@ -84,7 +85,7 @@ public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckSer
requestTimeoutMillis = DEFAULT_REQUEST_TIMEOUT_MILLIS;
}
for (ExplicitHealthChecker checker : mSupportedCheckers.values()) {
PackageInfo pkg = new PackageInfo(checker.getSupportedPackageName(),
PackageConfig pkg = new PackageConfig(checker.getSupportedPackageName(),
requestTimeoutMillis);
packages.add(pkg);
}

View File

@@ -18,6 +18,7 @@ package com.android.server;
import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE;
import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
import android.Manifest;
import android.annotation.MainThread;
@@ -35,7 +36,6 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.service.watchdog.ExplicitHealthCheckService;
import android.service.watchdog.IExplicitHealthCheckService;
import android.service.watchdog.PackageInfo;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Slog;
@@ -71,7 +71,7 @@ class ExplicitHealthCheckController {
// To prevent deadlocks between the controller and watchdog threads, we have
// a lock invariant to ALWAYS acquire the PackageWatchdog#mLock before #mLock in this class.
// It's easier to just NOT hold #mLock when calling into watchdog code on this consumer.
@GuardedBy("mLock") @Nullable private Consumer<List<PackageInfo>> mSupportedConsumer;
@GuardedBy("mLock") @Nullable private Consumer<List<PackageConfig>> mSupportedConsumer;
// Called everytime we need to notify the watchdog to sync requests between itself and the
// health check service. In practice, should never be null after it has been #setEnabled.
// To prevent deadlocks between the controller and watchdog threads, we have
@@ -106,7 +106,7 @@ class ExplicitHealthCheckController {
* ensure a happens-before relationship of the set parameters and visibility on other threads.
*/
public void setCallbacks(Consumer<String> passedConsumer,
Consumer<List<PackageInfo>> supportedConsumer, Runnable notifySyncRunnable) {
Consumer<List<PackageConfig>> supportedConsumer, Runnable notifySyncRunnable) {
synchronized (mLock) {
if (mPassedConsumer != null || mSupportedConsumer != null
|| mNotifySyncRunnable != null) {
@@ -146,17 +146,17 @@ class ExplicitHealthCheckController {
return;
}
getSupportedPackages(supportedPackageInfos -> {
getSupportedPackages(supportedPackageConfigs -> {
// Notify the watchdog without lock held
mSupportedConsumer.accept(supportedPackageInfos);
mSupportedConsumer.accept(supportedPackageConfigs);
getRequestedPackages(previousRequestedPackages -> {
synchronized (mLock) {
// Hold lock so requests and cancellations are sent atomically.
// It is important we don't mix requests from multiple threads.
Set<String> supportedPackages = new ArraySet<>();
for (PackageInfo info : supportedPackageInfos) {
supportedPackages.add(info.getPackageName());
for (PackageConfig config : supportedPackageConfigs) {
supportedPackages.add(config.getPackageName());
}
// Note, this may modify newRequestedPackages
newRequestedPackages.retainAll(supportedPackages);
@@ -235,7 +235,7 @@ class ExplicitHealthCheckController {
* Returns the packages that we can request explicit health checks for.
* The packages will be returned to the {@code consumer}.
*/
private void getSupportedPackages(Consumer<List<PackageInfo>> consumer) {
private void getSupportedPackages(Consumer<List<PackageConfig>> consumer) {
synchronized (mLock) {
if (!prepareServiceLocked("get health check supported packages")) {
return;
@@ -244,7 +244,7 @@ class ExplicitHealthCheckController {
Slog.d(TAG, "Getting health check supported packages");
try {
mRemoteService.getSupportedPackages(new RemoteCallback(result -> {
List<PackageInfo> packages =
List<PackageConfig> packages =
result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES);
Slog.i(TAG, "Explicit health check supported packages " + packages);
consumer.accept(packages);

View File

@@ -16,6 +16,8 @@
package com.android.server;
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
@@ -27,7 +29,6 @@ import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.service.watchdog.PackageInfo;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -453,13 +454,13 @@ public class PackageWatchdog {
}
}
private void onSupportedPackages(List<PackageInfo> supportedPackages) {
private void onSupportedPackages(List<PackageConfig> supportedPackages) {
boolean isStateChanged = false;
Map<String, Long> supportedPackageTimeouts = new ArrayMap<>();
Iterator<PackageInfo> it = supportedPackages.iterator();
Iterator<PackageConfig> it = supportedPackages.iterator();
while (it.hasNext()) {
PackageInfo info = it.next();
PackageConfig info = it.next();
supportedPackageTimeouts.put(info.getPackageName(), info.getHealthCheckTimeoutMillis());
}

View File

@@ -16,6 +16,8 @@
package com.android.server;
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
import static com.android.server.PackageWatchdog.MonitoredPackage;
import static com.android.server.PackageWatchdog.TRIGGER_FAILURE_COUNT;
@@ -28,7 +30,6 @@ import android.content.Context;
import android.content.pm.VersionedPackage;
import android.os.Handler;
import android.os.test.TestLooper;
import android.service.watchdog.PackageInfo;
import android.util.AtomicFile;
import androidx.test.InstrumentationRegistry;
@@ -741,7 +742,7 @@ public class PackageWatchdogTest {
private List<String> mSupportedPackages = new ArrayList<>();
private List<String> mRequestedPackages = new ArrayList<>();
private Consumer<String> mPassedConsumer;
private Consumer<List<PackageInfo>> mSupportedConsumer;
private Consumer<List<PackageConfig>> mSupportedConsumer;
private Runnable mNotifySyncRunnable;
@Override
@@ -754,7 +755,7 @@ public class PackageWatchdogTest {
@Override
public void setCallbacks(Consumer<String> passedConsumer,
Consumer<List<PackageInfo>> supportedConsumer, Runnable notifySyncRunnable) {
Consumer<List<PackageConfig>> supportedConsumer, Runnable notifySyncRunnable) {
mPassedConsumer = passedConsumer;
mSupportedConsumer = supportedConsumer;
mNotifySyncRunnable = notifySyncRunnable;
@@ -766,11 +767,11 @@ public class PackageWatchdogTest {
if (mIsEnabled) {
packages.retainAll(mSupportedPackages);
mRequestedPackages.addAll(packages);
List<PackageInfo> packageInfos = new ArrayList<>();
List<PackageConfig> packageConfigs = new ArrayList<>();
for (String packageName: packages) {
packageInfos.add(new PackageInfo(packageName, SHORT_DURATION));
packageConfigs.add(new PackageConfig(packageName, SHORT_DURATION));
}
mSupportedConsumer.accept(packageInfos);
mSupportedConsumer.accept(packageConfigs);
} else {
mSupportedConsumer.accept(Collections.emptyList());
}