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

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

Merge "Implements ContextHubService.registerEndpoint" into main

parents 37091a81 ee697651
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -1267,6 +1267,9 @@ public final class ContextHubManager {
     * registration succeeds, the endpoint can receive notifications through the provided callback.
     * registration succeeds, the endpoint can receive notifications through the provided callback.
     *
     *
     * @param hubEndpoint {@link HubEndpoint} object created by {@link HubEndpoint.Builder}
     * @param hubEndpoint {@link HubEndpoint} object created by {@link HubEndpoint.Builder}
     * @throws IllegalStateException if the registration failed, for example if too many endpoints
     *     are registered at the service
     * @throws UnsupportedOperationException if endpoint registration is not supported
     */
     */
    @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
    @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+108 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2024 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.location.contexthub;

import android.content.Context;
import android.hardware.contexthub.EndpointInfo;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubMessage;
import android.hardware.contexthub.HubServiceInfo;
import android.hardware.contexthub.IContextHubEndpoint;
import android.hardware.contexthub.IContextHubEndpointCallback;
import android.hardware.location.IContextHubTransactionCallback;

/**
 * A class that represents a broker for the endpoint registered by the client app. This class
 * manages direct IContextHubEndpoint/IContextHubEndpointCallback API/callback calls.
 *
 * @hide
 */
public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub {
    private static final String TAG = "ContextHubEndpointBroker";

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

    /** The proxy to talk to the Context Hub HAL. */
    private final IContextHubWrapper mContextHubProxy;

    /** The manager that registered this endpoint. */
    private final ContextHubEndpointManager mEndpointManager;

    /** Metadata about this endpoint (app-facing container). */
    private final HubEndpointInfo mEndpointInfo;

    /** Metadata about this endpoint (HAL-facing container). */
    private final EndpointInfo mHalEndpointInfo;

    /** The remote callback interface for this endpoint. */
    private final IContextHubEndpointCallback mContextHubEndpointCallback;

    /* package */ ContextHubEndpointBroker(
            Context context,
            IContextHubWrapper contextHubProxy,
            ContextHubEndpointManager endpointManager,
            EndpointInfo halEndpointInfo,
            IContextHubEndpointCallback callback) {
        mContext = context;
        mContextHubProxy = contextHubProxy;
        mEndpointManager = endpointManager;
        mEndpointInfo = new HubEndpointInfo(halEndpointInfo);
        mHalEndpointInfo = halEndpointInfo;
        mContextHubEndpointCallback = callback;
    }

    @Override
    public HubEndpointInfo getAssignedHubEndpointInfo() {
        return mEndpointInfo;
    }

    @Override
    public int openSession(HubEndpointInfo destination, HubServiceInfo serviceInfo) {
        // TODO(b/378487799): Implement this
        return 0;
    }

    @Override
    public void closeSession(int sessionId, int reason) {
        // TODO(b/378487799): Implement this

    }

    @Override
    public void openSessionRequestComplete(int sessionId) {
        // TODO(b/378487799): Implement this

    }

    @Override
    public void unregister() {
        // TODO(b/378487799): Implement this

    }

    @Override
    public void sendMessage(
            int sessionId, HubMessage message, IContextHubTransactionCallback callback) {
        // TODO(b/381102453): Implement this
    }

    @Override
    public void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode) {
        // TODO(b/381102453): Implement this
    }
}
+111 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2024 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.location.contexthub;

import android.content.Context;
import android.hardware.contexthub.EndpointInfo;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.IContextHubEndpoint;
import android.hardware.contexthub.IContextHubEndpointCallback;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A class that manages registration/unregistration of clients and manages messages to/from clients.
 *
 * @hide
 */
/* package */ class ContextHubEndpointManager {
    private static final String TAG = "ContextHubEndpointManager";

    /** The hub ID of the Context Hub Service. */
    private static final long SERVICE_HUB_ID = 0x416e64726f696400L;

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

    /** The proxy to talk to the Context Hub. */
    private final IContextHubWrapper mContextHubProxy;

    /** A map of endpoint IDs to brokers currently registered. */
    private final Map<Long, ContextHubEndpointBroker> mEndpointMap = new ConcurrentHashMap<>();

    /** Variables for managing endpoint ID creation */
    private final Object mEndpointLock = new Object();

    @GuardedBy("mEndpointLock")
    private long mNextEndpointId = 0;

    /* package */ ContextHubEndpointManager(Context context, IContextHubWrapper contextHubProxy) {
        mContext = context;
        mContextHubProxy = contextHubProxy;
    }

    /**
     * Registers a new endpoint with the service.
     *
     * @param pendingEndpointInfo the object describing the endpoint being registered
     * @param callback the callback interface of the endpoint to register
     * @return the endpoint interface
     * @throws IllegalStateException if max number of endpoints have already registered
     */
    /* package */ IContextHubEndpoint registerEndpoint(
            HubEndpointInfo pendingEndpointInfo, IContextHubEndpointCallback callback)
            throws RemoteException {
        ContextHubEndpointBroker broker;
        long endpointId = getNewEndpointId();
        EndpointInfo halEndpointInfo =
                ContextHubServiceUtil.createHalEndpointInfo(
                        pendingEndpointInfo, endpointId, SERVICE_HUB_ID);
        try {
            mContextHubProxy.registerEndpoint(halEndpointInfo);
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException while calling HAL registerEndpoint", e);
            throw e;
        }
        broker =
                new ContextHubEndpointBroker(
                        mContext,
                        mContextHubProxy,
                        this /* endpointManager */,
                        halEndpointInfo,
                        callback);
        mEndpointMap.put(endpointId, broker);

        // TODO(b/378487799): Add death recipient

        Log.d(TAG, "Registered endpoint with ID = " + endpointId);
        return IContextHubEndpoint.Stub.asInterface(broker);
    }

    /**
     * @return an available endpoint ID
     */
    private long getNewEndpointId() {
        synchronized (mEndpointLock) {
            if (mNextEndpointId == Long.MAX_VALUE) {
                throw new IllegalStateException("Too many endpoints connected");
            }
            return mNextEndpointId++;
        }
    }
}
+11 −2
Original line number Original line Diff line number Diff line
@@ -155,6 +155,9 @@ public class ContextHubService extends IContextHubService.Stub {
    // The manager for sending messages to/from clients
    // The manager for sending messages to/from clients
    private ContextHubClientManager mClientManager;
    private ContextHubClientManager mClientManager;


    // Manages endpoint and its sessions between apps and HAL
    private ContextHubEndpointManager mEndpointManager;

    // The default client for old API clients
    // The default client for old API clients
    private Map<Integer, IContextHubClient> mDefaultClientMap;
    private Map<Integer, IContextHubClient> mDefaultClientMap;


@@ -330,14 +333,17 @@ public class ContextHubService extends IContextHubService.Stub {
            HubInfoRegistry registry;
            HubInfoRegistry registry;
            try {
            try {
                registry = new HubInfoRegistry(mContextHubWrapper);
                registry = new HubInfoRegistry(mContextHubWrapper);
                mEndpointManager = new ContextHubEndpointManager(mContext, mContextHubWrapper);
                Log.i(TAG, "Enabling generic offload API");
                Log.i(TAG, "Enabling generic offload API");
            } catch (UnsupportedOperationException e) {
            } catch (UnsupportedOperationException e) {
                mEndpointManager = null;
                registry = null;
                registry = null;
                Log.w(TAG, "Generic offload API not supported, disabling");
                Log.w(TAG, "Generic offload API not supported, disabling");
            }
            }
            mHubInfoRegistry = registry;
            mHubInfoRegistry = registry;
        } else {
        } else {
            mHubInfoRegistry = null;
            mHubInfoRegistry = null;
            mEndpointManager = null;
            Log.i(TAG, "Disabling generic offload API");
            Log.i(TAG, "Disabling generic offload API");
        }
        }


@@ -790,8 +796,11 @@ public class ContextHubService extends IContextHubService.Stub {
            HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback)
            HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback)
            throws RemoteException {
            throws RemoteException {
        super.registerEndpoint_enforcePermission();
        super.registerEndpoint_enforcePermission();
        // TODO(b/375487784): Implement this
        if (mEndpointManager == null) {
        return null;
            Log.e(TAG, "ContextHubService.registerEndpoint: endpoint manager failed to initialize");
            throw new UnsupportedOperationException("Endpoint registration is not supported");
        }
        return mEndpointManager.registerEndpoint(pendingHubEndpointInfo, callback);
    }
    }


    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+50 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.server.location.contexthub;


import android.Manifest;
import android.Manifest;
import android.content.Context;
import android.content.Context;
import android.hardware.contexthub.EndpointInfo;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubServiceInfo;
import android.hardware.contexthub.V1_0.AsyncEventType;
import android.hardware.contexthub.V1_0.AsyncEventType;
import android.hardware.contexthub.V1_0.ContextHubMsg;
import android.hardware.contexthub.V1_0.ContextHubMsg;
import android.hardware.contexthub.V1_0.HostEndPoint;
import android.hardware.contexthub.V1_0.HostEndPoint;
@@ -415,4 +418,51 @@ import java.util.List;
    static String formatDateFromTimestamp(long timeStampInMs) {
    static String formatDateFromTimestamp(long timeStampInMs) {
        return DATE_FORMATTER.format(Instant.ofEpochMilli(timeStampInMs));
        return DATE_FORMATTER.format(Instant.ofEpochMilli(timeStampInMs));
    }
    }

    /**
     * Converts a context hub HAL EndpointInfo object based on the provided HubEndpointInfo.
     *
     * @param info the HubEndpointInfo object
     * @return the equivalent EndpointInfo object
     */
    /* package */
    static EndpointInfo convertHalEndpointInfo(HubEndpointInfo info) {
        return createHalEndpointInfo(
                info, info.getIdentifier().getEndpoint(), info.getIdentifier().getHub());
    }

    /**
     * Creates a context hub HAL EndpointInfo object based on the provided HubEndpointInfo. As
     * opposed to convertHalEndpointInfo, this method can be used to overwrite/specify the endpoint
     * and hub ID.
     *
     * @param info the HubEndpointInfo object
     * @param endpointId the endpoint ID of this object
     * @param hubId the hub ID of this object
     * @return the equivalent EndpointInfo object
     */
    /* package */
    static EndpointInfo createHalEndpointInfo(HubEndpointInfo info, long endpointId, long hubId) {
        EndpointInfo outputInfo = new EndpointInfo();
        outputInfo.id = new android.hardware.contexthub.EndpointId();
        outputInfo.id.id = endpointId;
        outputInfo.id.hubId = hubId;
        outputInfo.name = info.getName();
        outputInfo.version = info.getVersion();
        outputInfo.tag = info.getTag();
        Collection<String> permissions = info.getRequiredPermissions();
        outputInfo.requiredPermissions = permissions.toArray(new String[permissions.size()]);
        Collection<HubServiceInfo> services = info.getServiceInfoCollection();
        outputInfo.services = new android.hardware.contexthub.Service[services.size()];
        int i = 0;
        for (HubServiceInfo service : services) {
            outputInfo.services[i] = new android.hardware.contexthub.Service();
            outputInfo.services[i].format = service.getFormat();
            outputInfo.services[i].serviceDescriptor = service.getServiceDescriptor();
            outputInfo.services[i].majorVersion = service.getMajorVersion();
            outputInfo.services[i].minorVersion = service.getMinorVersion();
            i++;
        }
        return outputInfo;
    }
}
}
Loading