Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a230f09 authored by Arthur Ishiguro's avatar Arthur Ishiguro
Browse files

Add wakelocks for endpoint discovery callbacks

Bug: 383556228
Flag: android.chre.flags.offload_implementation
Test: Confirm desired wakelock behavior through dumpsys power

Change-Id: I87dc63bfac07080fb47350cc482d1b23909706af
parent c1f77cb8
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -771,6 +771,7 @@ public final class ContextHubManager {
     */
    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
    private IContextHubEndpointDiscoveryCallback createDiscoveryCallback(
            IContextHubService service,
            Executor executor,
            HubEndpointDiscoveryCallback callback,
            @Nullable String serviceDescriptor) {
@@ -779,6 +780,7 @@ public final class ContextHubManager {
            public void onEndpointsStarted(HubEndpointInfo[] hubEndpointInfoList) {
                if (hubEndpointInfoList.length == 0) {
                    Log.w(TAG, "onEndpointsStarted: received empty discovery list");
                    invokeCallbackFinished(service);
                    return;
                }
                executor.execute(
@@ -791,6 +793,7 @@ public final class ContextHubManager {
                            } else {
                                callback.onEndpointsStarted(discoveryList);
                            }
                            invokeCallbackFinished(service);
                        });
            }

@@ -798,6 +801,7 @@ public final class ContextHubManager {
            public void onEndpointsStopped(HubEndpointInfo[] hubEndpointInfoList, int reason) {
                if (hubEndpointInfoList.length == 0) {
                    Log.w(TAG, "onEndpointsStopped: received empty discovery list");
                    invokeCallbackFinished(service);
                    return;
                }
                executor.execute(
@@ -810,8 +814,17 @@ public final class ContextHubManager {
                            } else {
                                callback.onEndpointsStopped(discoveryList, reason);
                            }
                            invokeCallbackFinished(service);
                        });
            }

            private void invokeCallbackFinished(IContextHubService service) {
                try {
                    service.onDiscoveryCallbackFinished();
                } catch (RemoteException e) {
                    e.rethrowFromSystemServer();
                }
            }
        };
    }

@@ -873,7 +886,7 @@ public final class ContextHubManager {
        Objects.requireNonNull(executor, "executor cannot be null");
        Objects.requireNonNull(callback, "callback cannot be null");
        IContextHubEndpointDiscoveryCallback iCallback =
                createDiscoveryCallback(executor, callback, null);
                createDiscoveryCallback(mService, executor, callback, null);
        try {
            mService.registerEndpointDiscoveryCallbackId(endpointId, iCallback);
        } catch (RemoteException e) {
@@ -919,7 +932,7 @@ public final class ContextHubManager {
        }

        IContextHubEndpointDiscoveryCallback iCallback =
                createDiscoveryCallback(executor, callback, serviceDescriptor);
                createDiscoveryCallback(mService, executor, callback, serviceDescriptor);
        try {
            mService.registerEndpointDiscoveryCallbackDescriptor(serviceDescriptor, iCallback);
        } catch (RemoteException e) {
+4 −0
Original line number Diff line number Diff line
@@ -150,4 +150,8 @@ interface IContextHubService {
    // Unregister an endpoint with the context hub
    @EnforcePermission("ACCESS_CONTEXT_HUB")
    void unregisterEndpointDiscoveryCallback(in IContextHubEndpointDiscoveryCallback callback);

    // Called when a discovery callback is finished executing
    @EnforcePermission("ACCESS_CONTEXT_HUB")
    void onDiscoveryCallbackFinished();
}
+8 −1
Original line number Diff line number Diff line
@@ -334,7 +334,7 @@ public class ContextHubService extends IContextHubService.Stub {
        if (Flags.offloadApi() && Flags.offloadImplementation()) {
            HubInfoRegistry registry;
            try {
                registry = new HubInfoRegistry(mContextHubWrapper);
                registry = new HubInfoRegistry(mContext, mContextHubWrapper);
                mEndpointManager =
                        new ContextHubEndpointManager(
                                mContext, mContextHubWrapper, registry, mTransactionManager);
@@ -821,6 +821,13 @@ public class ContextHubService extends IContextHubService.Stub {
        mHubInfoRegistry.unregisterEndpointDiscoveryCallback(callback);
    }

    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
    @Override
    public void onDiscoveryCallbackFinished() throws RemoteException {
        super.onDiscoveryCallbackFinished_enforcePermission();
        mHubInfoRegistry.onDiscoveryCallbackFinished();
    }

    private void checkEndpointDiscoveryPreconditions() {
        if (mHubInfoRegistry == null) {
            Log.e(TAG, "Hub endpoint registry failed to initialize");
+51 −1
Original line number Diff line number Diff line
@@ -16,12 +16,18 @@

package com.android.server.location.contexthub;

import android.content.Context;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubServiceInfo;
import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
import android.hardware.location.HubInfo;
import android.os.Binder;
import android.os.DeadObjectException;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Process;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.Log;
@@ -38,6 +44,10 @@ import java.util.function.BiConsumer;

class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycleCallback {
    private static final String TAG = "HubInfoRegistry";

    /** The duration of wakelocks acquired during discovery callbacks */
    private static final long WAKELOCK_TIMEOUT_MILLIS = 5 * 1000;

    private final Object mLock = new Object();

    private final IContextHubWrapper mContextHubWrapper;
@@ -99,7 +109,11 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl

    private final Object mCallbackLock = new Object();

    HubInfoRegistry(IContextHubWrapper contextHubWrapper) throws InstantiationException {
    /** Wakelock held while endpoint callbacks are being invoked */
    private final WakeLock mWakeLock;

    HubInfoRegistry(Context context, IContextHubWrapper contextHubWrapper)
            throws InstantiationException {
        mContextHubWrapper = contextHubWrapper;
        try {
            refreshCachedHubs();
@@ -109,6 +123,16 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl
            Log.e(TAG, error, e);
            throw new InstantiationException(error);
        }

        PowerManager powerManager = context.getSystemService(PowerManager.class);
        if (powerManager == null) {
            String error = "PowerManager was null";
            Log.e(TAG, error);
            throw new InstantiationError(error);
        }
        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        mWakeLock.setWorkSource(new WorkSource(Process.myUid(), context.getPackageName()));
        mWakeLock.setReferenceCounted(true);
    }

    /** Retrieve the list of hubs available. */
@@ -282,6 +306,11 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl
        }
    }

    /* package */
    void onDiscoveryCallbackFinished() {
        releaseWakeLock();
    }

    private void checkCallbackAlreadyRegistered(
            IContextHubEndpointDiscoveryCallback callback) {
        synchronized (mCallbackLock) {
@@ -315,6 +344,7 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl
                    }
                }

                acquireWakeLock();
                consumer.accept(
                        discoveryCallback.getCallback(),
                        infoList.toArray(new HubEndpointInfo[infoList.size()]));
@@ -322,6 +352,26 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl
        }
    }

    private void acquireWakeLock() {
        Binder.withCleanCallingIdentity(
                () -> {
                    mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
                });
    }

    private void releaseWakeLock() {
        Binder.withCleanCallingIdentity(
                () -> {
                    if (mWakeLock.isHeld()) {
                        try {
                            mWakeLock.release();
                        } catch (RuntimeException e) {
                            Log.e(TAG, "Releasing the wakelock fails - ", e);
                        }
                    }
                });
    }

    void dump(IndentingPrintWriter ipw) {
        synchronized (mLock) {
            dumpLocked(ipw);