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

Commit 4ed613a8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Acquire wakelock on endpoint callbacks" into main

parents 86e7a10e d91289bd
Loading
Loading
Loading
Loading
+22 −1
Original line number Original line Diff line number Diff line
@@ -137,6 +137,8 @@ public class HubEndpoint {
                                                serviceDescriptor,
                                                serviceDescriptor,
                                                mLifecycleCallback.onSessionOpenRequest(
                                                mLifecycleCallback.onSessionOpenRequest(
                                                        initiator, serviceDescriptor)));
                                                        initiator, serviceDescriptor)));
                    } else {
                        invokeCallbackFinished();
                    }
                    }
                }
                }


@@ -163,6 +165,8 @@ public class HubEndpoint {
                                        + result.getReason());
                                        + result.getReason());
                        rejectSession(sessionId);
                        rejectSession(sessionId);
                    }
                    }

                    invokeCallbackFinished();
                }
                }


                private void acceptSession(
                private void acceptSession(
@@ -249,7 +253,12 @@ public class HubEndpoint {
                    activeSession.setOpened();
                    activeSession.setOpened();
                    if (mLifecycleCallback != null) {
                    if (mLifecycleCallback != null) {
                        mLifecycleCallbackExecutor.execute(
                        mLifecycleCallbackExecutor.execute(
                                () -> mLifecycleCallback.onSessionOpened(activeSession));
                                () -> {
                                    mLifecycleCallback.onSessionOpened(activeSession);
                                    invokeCallbackFinished();
                                });
                    } else {
                        invokeCallbackFinished();
                    }
                    }
                }
                }


@@ -278,7 +287,10 @@ public class HubEndpoint {
                                    synchronized (mLock) {
                                    synchronized (mLock) {
                                        mActiveSessions.remove(sessionId);
                                        mActiveSessions.remove(sessionId);
                                    }
                                    }
                                    invokeCallbackFinished();
                                });
                                });
                    } else {
                        invokeCallbackFinished();
                    }
                    }
                }
                }


@@ -323,8 +335,17 @@ public class HubEndpoint {
                                        e.rethrowFromSystemServer();
                                        e.rethrowFromSystemServer();
                                    }
                                    }
                                }
                                }
                                invokeCallbackFinished();
                            });
                            });
                }
                }

                private void invokeCallbackFinished() {
                    try {
                        mServiceToken.onCallbackFinished();
                    } catch (RemoteException e) {
                        e.rethrowFromSystemServer();
                    }
                }
            };
            };


    /** Binder returned from system service, non-null while registered. */
    /** Binder returned from system service, non-null while registered. */
+6 −0
Original line number Original line Diff line number Diff line
@@ -94,4 +94,10 @@ interface IContextHubEndpoint {
     */
     */
    @EnforcePermission("ACCESS_CONTEXT_HUB")
    @EnforcePermission("ACCESS_CONTEXT_HUB")
    void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode);
    void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode);

    /**
     * Invoked when a callback from IContextHubEndpointCallback finishes.
     */
    @EnforcePermission("ACCESS_CONTEXT_HUB")
    void onCallbackFinished();
}
}
+89 −32
Original line number Original line Diff line number Diff line
@@ -32,7 +32,10 @@ import android.hardware.location.ContextHubTransaction;
import android.hardware.location.IContextHubTransactionCallback;
import android.hardware.location.IContextHubTransactionCallback;
import android.os.Binder;
import android.os.Binder;
import android.os.IBinder;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.Log;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseArray;


@@ -54,6 +57,16 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
    /** Message used by noteOp when this client receives a message from an endpoint. */
    /** Message used by noteOp when this client receives a message from an endpoint. */
    private static final String RECEIVE_MSG_NOTE = "ContextHubEndpointMessageDelivery";
    private static final String RECEIVE_MSG_NOTE = "ContextHubEndpointMessageDelivery";


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

    /*
     * Internal interface used to invoke client callbacks.
     */
    interface CallbackConsumer {
        void accept(IContextHubEndpointCallback callback) throws RemoteException;
    }

    /** The context of the service. */
    /** The context of the service. */
    private final Context mContext;
    private final Context mContext;


@@ -134,6 +147,9 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub


    private final int mUid;
    private final int mUid;


    /** Wakelock held while nanoapp message are in flight to the client */
    private final WakeLock mWakeLock;

    /* package */ ContextHubEndpointBroker(
    /* package */ ContextHubEndpointBroker(
            Context context,
            Context context,
            IEndpointCommunication hubInterface,
            IEndpointCommunication hubInterface,
@@ -158,6 +174,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub


        mAppOpsManager = context.getSystemService(AppOpsManager.class);
        mAppOpsManager = context.getSystemService(AppOpsManager.class);
        mAppOpsManager.startWatchingMode(AppOpsManager.OP_NONE, mPackageName, this);
        mAppOpsManager.startWatchingMode(AppOpsManager.OP_NONE, mPackageName, this);

        PowerManager powerManager = context.getSystemService(PowerManager.class);
        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        mWakeLock.setWorkSource(new WorkSource(mUid, mPackageName));
        mWakeLock.setReferenceCounted(true);
    }
    }


    @Override
    @Override
@@ -302,6 +323,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        }
        }
    }
    }


    @Override
    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
    public void onCallbackFinished() {
        super.onCallbackFinished_enforcePermission();
        releaseWakeLock();
    }

    /** Invoked when the underlying binder of this broker has died at the client process. */
    /** Invoked when the underlying binder of this broker has died at the client process. */
    @Override
    @Override
    public void binderDied() {
    public void binderDied() {
@@ -357,15 +385,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
            mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true));
            mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true));
        }
        }


        if (mContextHubEndpointCallback != null) {
        boolean success =
            try {
                invokeCallback(
                mContextHubEndpointCallback.onSessionOpenRequest(
                        (consumer) ->
                        sessionId, initiator, serviceDescriptor);
                                consumer.onSessionOpenRequest(
            } catch (RemoteException e) {
                                        sessionId, initiator, serviceDescriptor));
                Log.e(TAG, "RemoteException while calling onSessionOpenRequest", e);
        if (!success) {
            cleanupSessionResources(sessionId);
            cleanupSessionResources(sessionId);
                return;
            }
        }
        }
    }
    }


@@ -374,14 +400,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
            Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId);
            Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId);
            return;
            return;
        }
        }
        if (mContextHubEndpointCallback != null) {

            try {
        invokeCallback(
                mContextHubEndpointCallback.onSessionClosed(
                (consumer) ->
                        sessionId, ContextHubServiceUtil.toAppHubEndpointReason(reason));
                        consumer.onSessionClosed(
            } catch (RemoteException e) {
                                sessionId, ContextHubServiceUtil.toAppHubEndpointReason(reason)));
                Log.e(TAG, "RemoteException while calling onSessionClosed", e);
            }
        }
    }
    }


    /* package */ void onEndpointSessionOpenComplete(int sessionId) {
    /* package */ void onEndpointSessionOpenComplete(int sessionId) {
@@ -392,13 +415,8 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
            }
            }
            mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE);
            mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE);
        }
        }
        if (mContextHubEndpointCallback != null) {

            try {
        invokeCallback((consumer) -> consumer.onSessionOpenComplete(sessionId));
                mContextHubEndpointCallback.onSessionOpenComplete(sessionId);
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while calling onSessionClosed", e);
            }
        }
    }
    }


    /* package */ void onMessageReceived(int sessionId, HubMessage message) {
    /* package */ void onMessageReceived(int sessionId, HubMessage message) {
@@ -440,16 +458,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
            return;
            return;
        }
        }


        if (mContextHubEndpointCallback != null) {
        boolean success =
            try {
                invokeCallback((consumer) -> consumer.onMessageReceived(sessionId, message));
                mContextHubEndpointCallback.onMessageReceived(sessionId, message);
        if (!success) {
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while calling onMessageReceived", e);
            sendMessageDeliveryStatus(
            sendMessageDeliveryStatus(
                    sessionId, message.getMessageSequenceNumber(), ErrorCode.TRANSIENT_ERROR);
                    sessionId, message.getMessageSequenceNumber(), ErrorCode.TRANSIENT_ERROR);
        }
        }
    }
    }
    }


    /* package */ void onMessageDeliveryStatusReceived(
    /* package */ void onMessageDeliveryStatusReceived(
            int sessionId, int sequenceNumber, byte errorCode) {
            int sessionId, int sequenceNumber, byte errorCode) {
@@ -520,4 +535,46 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        Collection<String> requiredPermissions = targetEndpointInfo.getRequiredPermissions();
        Collection<String> requiredPermissions = targetEndpointInfo.getRequiredPermissions();
        return ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, requiredPermissions);
        return ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, requiredPermissions);
    }
    }

    private void acquireWakeLock() {
        Binder.withCleanCallingIdentity(
                () -> {
                    if (mIsRegistered.get()) {
                        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);
                        }
                    }
                });
    }

    /**
     * Invokes a callback and acquires a wakelock.
     *
     * @param consumer The callback invoke
     * @return false if the callback threw a RemoteException
     */
    private boolean invokeCallback(CallbackConsumer consumer) {
        if (mContextHubEndpointCallback != null) {
            acquireWakeLock();
            try {
                consumer.accept(mContextHubEndpointCallback);
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while calling endpoint callback", e);
                releaseWakeLock();
                return false;
            }
        }
        return true;
    }
}
}