/* * 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 static android.os.Parcelable.Creator; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; import android.content.pm.PackageManager; import android.crashrecovery.flags.Flags; 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.Executor; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; /** * A service to provide packages supporting explicit health checks and route checks to these * packages on behalf of the package watchdog. * *
To extend this class, you must declare the service in your manifest file with the * {@link android.Manifest.permission#BIND_EXPLICIT_HEALTH_CHECK_SERVICE} permission, * and include an intent filter with the {@link #SERVICE_INTERFACE} action. In adddition, * your implementation must live in * {@link PackageManager#getServicesSystemSharedLibraryPackageName()}. * For example:
** <service android:name=".FooExplicitHealthCheckService" * android:exported="true" * android:priority="100" * android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"> * <intent-filter> * <action android:name="android.service.watchdog.ExplicitHealthCheckService" /> * </intent-filter> * </service> ** @hide */ @SystemApi public abstract class ExplicitHealthCheckService extends Service { private static final String TAG = "ExplicitHealthCheckService"; /** * {@link Bundle} key for a {@link List} of {@link PackageConfig} value. * * {@hide} */ public static final String EXTRA_SUPPORTED_PACKAGES = "android.service.watchdog.extra.supported_packages"; /** * {@link Bundle} key for a {@link List} of {@link String} value. * * {@hide} */ public static final String EXTRA_REQUESTED_PACKAGES = "android.service.watchdog.extra.requested_packages"; /** * {@link Bundle} key for a {@link String} value. */ @FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY) public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE = "android.service.watchdog.extra.HEALTH_CHECK_PASSED_PACKAGE"; /** * The Intent action that a service must respond to. Add it to the intent filter of the service * in its manifest. */ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService"; /** * The permission that a service must require to ensure that only Android system can bind to it. * If this permission is not enforced in the AndroidManifest of the service, the system will * skip that service. */ public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"; private final ExplicitHealthCheckServiceWrapper mWrapper = new ExplicitHealthCheckServiceWrapper(); /** * Called when the system requests an explicit health check for {@code packageName}. * *
When {@code packageName} passes the check, implementors should call * {@link #notifyHealthCheckPassed} to inform the system. * *
It could take many hours before a {@code packageName} passes a check and implementors * should never drop requests unless {@link onCancel} is called or the service dies. * *
Requests should not be queued and additional calls while expecting a result for
* {@code packageName} should have no effect.
*/
public abstract void onRequestHealthCheck(@NonNull String packageName);
/**
* Called when the system cancels the explicit health check request for {@code packageName}.
* Should do nothing if there are is no active request for {@code packageName}.
*/
public abstract void onCancelHealthCheck(@NonNull String packageName);
/**
* Called when the system requests for all the packages supporting explicit health checks. The
* system may request an explicit health check for any of these packages with
* {@link #onRequestHealthCheck}.
*
* @return all packages supporting explicit health checks
*/
@NonNull public abstract List
* The callback will receive a {@link Bundle} containing the package name that passed the
* health check, identified by the key {@link #EXTRA_HEALTH_CHECK_PASSED_PACKAGE}.
*
* Note: This API is primarily intended for testing purposes. Calling this outside of a
* test environment will override the default callback mechanism used to notify the system
* about health check results. Use with caution in production code.
*
* @param executor The executor on which the callback should be invoked. If {@code null}, the
* callback will be executed on the main thread.
* @param callback A callback that receives a {@link Bundle} containing the package name that
* passed the health check.
*/
@FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
public final void setHealthCheckPassedCallback(@CallbackExecutor @Nullable Executor executor,
@Nullable Consumer