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