From cd6b11575f316046e945c275f2068f4ec5e18988 Mon Sep 17 00:00:00 2001 From: Zimuzo Date: Fri, 29 Mar 2019 17:42:19 +0000 Subject: [PATCH] Add supported PackageInfo to ExplicitHealthCheckService API With the change in I4f13638598037acaeb30d61c8d5178f45882fcba to separate the PackageWatchdog package expiry deadline from the explicit health check deadline. It would be cleaner for ExtServices to supply this deadline per-package. We now do that as a field in PackageInfo. Bug: 120598832 Test: Builds Change-Id: I29e2d619a5296716c29893ab3aa2f35f69bfb4d7 --- Android.bp | 1 + api/system-current.txt | 11 +- .../watchdog/ExplicitHealthCheckService.java | 32 +++-- .../android/service/watchdog/PackageInfo.aidl | 22 +++ .../android/service/watchdog/PackageInfo.java | 130 ++++++++++++++++++ .../ExplicitHealthCheckServiceImpl.java | 11 +- .../watchdog/ExplicitHealthChecker.java | 6 +- .../ext/services/watchdog/NetworkChecker.java | 7 +- 8 files changed, 198 insertions(+), 22 deletions(-) create mode 100644 core/java/android/service/watchdog/PackageInfo.aidl create mode 100644 core/java/android/service/watchdog/PackageInfo.java diff --git a/Android.bp b/Android.bp index 7cc2f30cc227c..c35d8a9c22cd6 100644 --- a/Android.bp +++ b/Android.bp @@ -319,6 +319,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/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 3f74596999cbc..64589093654eb 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6895,12 +6895,21 @@ 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 onGetRequestedPackages(); - method @NonNull public abstract java.util.List onGetSupportedPackages(); + method @NonNull public abstract java.util.List 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); + 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 CREATOR; + } + } package android.telecom { diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java index 015fba19d7851..682b872d676b1 100644 --- a/core/java/android/service/watchdog/ExplicitHealthCheckService.java +++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java @@ -61,7 +61,7 @@ public abstract class ExplicitHealthCheckService extends Service { private static final String TAG = "ExplicitHealthCheckService"; /** - * {@link Bundle} key for a {@link List} of {@link String} value. + * {@link Bundle} key for a {@link List} of {@link PackageInfo} value. * * {@hide} */ @@ -130,7 +130,7 @@ public abstract class ExplicitHealthCheckService extends Service { * * @return all packages supporting explicit health checks */ - @NonNull public abstract List onGetSupportedPackages(); + @NonNull public abstract List onGetSupportedPackages(); /** * Called when the system requests for all the packages that it has currently requested @@ -187,22 +187,26 @@ public abstract class ExplicitHealthCheckService extends Service { @Override public void getSupportedPackages(RemoteCallback callback) throws RemoteException { - mHandler.post(() -> sendPackages(callback, EXTRA_SUPPORTED_PACKAGES, - ExplicitHealthCheckService.this.onGetSupportedPackages())); + mHandler.post(() -> { + List packages = + ExplicitHealthCheckService.this.onGetSupportedPackages(); + Objects.requireNonNull(packages, "Supported package list must be non-null"); + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList(EXTRA_SUPPORTED_PACKAGES, new ArrayList<>(packages)); + callback.sendResult(bundle); + }); } @Override public void getRequestedPackages(RemoteCallback callback) throws RemoteException { - mHandler.post(() -> sendPackages(callback, EXTRA_REQUESTED_PACKAGES, - ExplicitHealthCheckService.this.onGetRequestedPackages())); - } - - private void sendPackages(RemoteCallback callback, String key, List packages) { - Objects.requireNonNull(packages, - "Supported and requested package list must be non-null"); - Bundle bundle = new Bundle(); - bundle.putStringArrayList(key, new ArrayList<>(packages)); - callback.sendResult(bundle); + mHandler.post(() -> { + List packages = + ExplicitHealthCheckService.this.onGetRequestedPackages(); + Objects.requireNonNull(packages, "Requested package list must be non-null"); + Bundle bundle = new Bundle(); + bundle.putStringArrayList(EXTRA_REQUESTED_PACKAGES, new ArrayList<>(packages)); + callback.sendResult(bundle); + }); } } } diff --git a/core/java/android/service/watchdog/PackageInfo.aidl b/core/java/android/service/watchdog/PackageInfo.aidl new file mode 100644 index 0000000000000..5605aec1c4fe3 --- /dev/null +++ b/core/java/android/service/watchdog/PackageInfo.aidl @@ -0,0 +1,22 @@ +/* + * 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; + +/** + * @hide + */ +parcelable PackageInfo; diff --git a/core/java/android/service/watchdog/PackageInfo.java b/core/java/android/service/watchdog/PackageInfo.java new file mode 100644 index 0000000000000..cee9b6d0fbf9b --- /dev/null +++ b/core/java/android/service/watchdog/PackageInfo.java @@ -0,0 +1,130 @@ +/* + * 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 CREATOR = new Creator() { + @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 040e2ab26874a..52e54f965cc03 100644 --- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java +++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java @@ -19,6 +19,7 @@ package android.ext.services.watchdog; import android.content.ComponentName; import android.content.Intent; import android.service.watchdog.ExplicitHealthCheckService; +import android.service.watchdog.PackageInfo; import android.util.Log; import java.util.ArrayList; @@ -67,8 +68,12 @@ public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckSer } @Override - public List onGetSupportedPackages() { - return new ArrayList<>(mSupportedCheckers.keySet()); + public List onGetSupportedPackages() { + List packages = new ArrayList<>(); + for (ExplicitHealthChecker checker : mSupportedCheckers.values()) { + packages.add(checker.getSupportedPackage()); + } + return packages; } @Override @@ -82,7 +87,7 @@ public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckSer while (it.hasNext()) { ExplicitHealthChecker checker = it.next(); if (checker.isPending()) { - packages.add(checker.getPackageName()); + packages.add(checker.getSupportedPackage().getPackageName()); } } return packages; diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java index 650878e43d7c2..c51be8863d90a 100644 --- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java +++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java @@ -16,6 +16,8 @@ package android.ext.services.watchdog; +import android.service.watchdog.PackageInfo; + /** * A type of explicit health check that can be performed on a device, e.g network health check */ @@ -38,7 +40,7 @@ interface ExplicitHealthChecker { boolean isPending(); /** - * Returns the package name this checker can make requests for. + * Returns the {@link PackageInfo} object this checker can make requests for. */ - String getPackageName(); + PackageInfo getSupportedPackage(); } diff --git a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java index 32375e6a9bbcf..09b319e819330 100644 --- a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java +++ b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java @@ -21,6 +21,7 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.service.watchdog.ExplicitHealthCheckService; +import android.service.watchdog.PackageInfo; import com.android.internal.annotations.GuardedBy; @@ -34,6 +35,8 @@ final class NetworkChecker extends ConnectivityManager.NetworkCallback private final Object mLock = new Object(); private final ExplicitHealthCheckService mService; private final String mPackageName; + // TODO: Receive from DeviceConfig flag + private final long mRequestDurationMillis = 0; @GuardedBy("mLock") private boolean mIsPending; @@ -73,8 +76,8 @@ final class NetworkChecker extends ConnectivityManager.NetworkCallback } @Override - public String getPackageName() { - return mPackageName; + public PackageInfo getSupportedPackage() { + return new PackageInfo(mPackageName, mRequestDurationMillis); } // TODO(b/120598832): Also monitor NetworkCallback#onAvailable to see if we have any