blob: 90a2f480643de986b49b505dfc88c181c1b83193 [file] [log] [blame]
/*
* Copyright (C) 2021 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 com.android.server.health;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.health.HealthInfo;
import android.hardware.health.IHealth;
import android.hardware.health.IHealthInfoCallback;
import android.os.RemoteException;
import android.os.Trace;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
/**
* On service registration, {@link #onRegistration} is called, which registers {@code this}, an
* {@link IHealthInfoCallback}, to the health service.
*
* <p>When the health service has updates to health info via {@link IHealthInfoCallback}, {@link
* HealthInfoCallback#update} is called.
*
* <p>AIDL variant of {@link HealthHalCallbackHidl}.
*
* @hide
*/
// It is made public so Mockito can access this class. It should have been package private if not
// for testing.
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class HealthRegCallbackAidl {
private static final String TAG = "HealthRegCallbackAidl";
private final HealthInfoCallback mServiceInfoCallback;
private final IHealthInfoCallback mHalInfoCallback = new HalInfoCallback();
HealthRegCallbackAidl(@Nullable HealthInfoCallback healthInfoCallback) {
mServiceInfoCallback = healthInfoCallback;
}
/**
* Called when the service manager sees {@code newService} replacing {@code oldService}.
* This unregisters the health info callback from the old service (ignoring errors), then
* registers the health info callback to the new service.
*
* @param oldService the old IHealth service
* @param newService the new IHealth service
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void onRegistration(@Nullable IHealth oldService, @NonNull IHealth newService) {
if (mServiceInfoCallback == null) return;
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "HealthUnregisterCallbackAidl");
try {
unregisterCallback(oldService, mHalInfoCallback);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "HealthRegisterCallbackAidl");
try {
registerCallback(newService, mHalInfoCallback);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
private static void unregisterCallback(@Nullable IHealth oldService, IHealthInfoCallback cb) {
if (oldService == null) return;
try {
oldService.unregisterCallback(cb);
} catch (RemoteException e) {
// Ignore errors. The service might have died.
Slog.w(
TAG,
"health: cannot unregister previous callback (transaction error): "
+ e.getMessage());
}
}
private static void registerCallback(@NonNull IHealth newService, IHealthInfoCallback cb) {
try {
newService.registerCallback(cb);
} catch (RemoteException e) {
Slog.e(
TAG,
"health: cannot register callback, framework may cease to"
+ " receive updates on health / battery info!",
e);
return;
}
// registerCallback does NOT guarantee that update is called immediately, so request a
// manual update here.
try {
newService.update();
} catch (RemoteException e) {
Slog.e(TAG, "health: cannot update after registering health info callback", e);
}
}
private class HalInfoCallback extends IHealthInfoCallback.Stub {
@Override
public void healthInfoChanged(HealthInfo healthInfo) throws RemoteException {
mServiceInfoCallback.update(healthInfo);
}
@Override
public String getInterfaceHash() {
return IHealthInfoCallback.HASH;
}
@Override
public int getInterfaceVersion() {
return IHealthInfoCallback.VERSION;
}
}
}