diff options
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | api/system-current.txt | 8 | ||||
-rw-r--r-- | core/java/android/service/watchdog/ExplicitHealthCheckService.java | 119 | ||||
-rw-r--r-- | core/java/android/service/watchdog/PackageConfig.aidl (renamed from core/java/android/service/watchdog/PackageInfo.aidl) | 2 | ||||
-rw-r--r-- | core/java/android/service/watchdog/PackageInfo.java | 130 | ||||
-rw-r--r-- | packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java | 9 | ||||
-rw-r--r-- | services/core/java/com/android/server/ExplicitHealthCheckController.java | 18 | ||||
-rw-r--r-- | services/core/java/com/android/server/PackageWatchdog.java | 9 | ||||
-rw-r--r-- | tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java | 13 |
9 files changed, 148 insertions, 162 deletions
diff --git a/Android.bp b/Android.bp index b4110fa906cf..0fcc0d501a1d 100644 --- a/Android.bp +++ b/Android.bp @@ -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", diff --git a/api/system-current.txt b/api/system-current.txt index 3028ae86e38a..101ad23f2939 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -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; } } diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java index 682b872d676b..eeefb4ae10fa 100644 --- a/core/java/android/service/watchdog/ExplicitHealthCheckService.java +++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java @@ -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(); diff --git a/core/java/android/service/watchdog/PackageInfo.aidl b/core/java/android/service/watchdog/PackageConfig.aidl index 5605aec1c4fe..013158676f79 100644 --- a/core/java/android/service/watchdog/PackageInfo.aidl +++ b/core/java/android/service/watchdog/PackageConfig.aidl @@ -19,4 +19,4 @@ package android.service.watchdog; /** * @hide */ -parcelable PackageInfo; +parcelable PackageConfig; diff --git a/core/java/android/service/watchdog/PackageInfo.java b/core/java/android/service/watchdog/PackageInfo.java deleted file mode 100644 index cee9b6d0fbf9..000000000000 --- a/core/java/android/service/watchdog/PackageInfo.java +++ /dev/null @@ -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]; - } - }; -} diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java index 69e91d1b857e..765e9f95216d 100644 --- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java +++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java @@ -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); } diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java index 19ab33e85f5e..f7c4aac2e04f 100644 --- a/services/core/java/com/android/server/ExplicitHealthCheckController.java +++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java @@ -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); diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index 7d0d8344a566..b44009fd6880 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -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()); } diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index fa7bf61a07b2..13e737e9fed3 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -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()); } |