• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.android.chre.utils.pigweed;
17 
18 import android.content.Intent;
19 import android.hardware.location.ContextHubClient;
20 import android.hardware.location.ContextHubClientCallback;
21 import android.hardware.location.ContextHubInfo;
22 import android.hardware.location.ContextHubManager;
23 import android.hardware.location.NanoAppRpcService;
24 import android.hardware.location.NanoAppState;
25 
26 import java.util.List;
27 import java.util.Objects;
28 
29 import dev.pigweed.pw_rpc.Channel;
30 import dev.pigweed.pw_rpc.Client;
31 import dev.pigweed.pw_rpc.MethodClient;
32 import dev.pigweed.pw_rpc.Service;
33 
34 /**
35  * Pigweed RPC Client Helper.
36  *
37  * See https://g3doc.corp.google.com/location/lbs/contexthub/g3doc/nanoapps/pw_rpc_host.md
38  */
39 public class ChreRpcClient {
40 
41     // Non null.
42     private final Client mRpcClient;
43     // Non null.
44     private final Channel mChannel;
45     // Non null.
46     private final ChreChannelOutput mChannelOutput;
47     private final long mServerNanoappId;
48     // Non null.
49     private final ContextHubClient mContextHubClient;
50     private ChreIntentHandler mIntentHandler;
51 
52     /**
53      * Creates a ContextHubClient and initializes the helper.
54      *
55      * Use this constructor for persistent clients using callbacks.
56      *
57      * @param manager         The context manager used to create a client, non null
58      * @param info            Context hub info, non null
59      * @param serverNanoappId The ID of the RPC server nanoapp
60      * @param services        The list of services provided by the server, non null
61      * @param callback        The callbacks receiving messages and life-cycle events from nanoapps,
62      *                        nullable
63      */
ChreRpcClient(ContextHubManager manager, ContextHubInfo info, long serverNanoappId, List<Service> services, ContextHubClientCallback callback)64     public ChreRpcClient(ContextHubManager manager, ContextHubInfo info,
65             long serverNanoappId, List<Service> services,
66             ContextHubClientCallback callback) {
67         Objects.requireNonNull(manager);
68         Objects.requireNonNull(info);
69         Objects.requireNonNull(services);
70         ChreCallbackHandler callbackHandler = new ChreCallbackHandler(serverNanoappId, callback);
71         mContextHubClient = manager.createClient(info, callbackHandler);
72         mServerNanoappId = serverNanoappId;
73         mChannelOutput = new ChreChannelOutput(mContextHubClient, serverNanoappId);
74         mChannel = new Channel(mChannelOutput.getChannelId(), mChannelOutput);
75         mRpcClient = Client.create(List.of(mChannel), services);
76         callbackHandler.lateInit(mRpcClient, mChannelOutput);
77     }
78 
79     /**
80      * Initializes the helper
81      *
82      * Use this constructor for non-persistent clients using intents.
83      *
84      * handleIntent() must be called with any CHRE intent received by the BroadcastReceiver.
85      *
86      * @param contextHubClient The context hub client providing the RPC server nanoapp, non null
87      * @param serverNanoappId  The ID of the RPC server nanoapp
88      * @param services         The list of services provided by the server, non null
89      */
ChreRpcClient(ContextHubClient contextHubClient, long serverNanoappId, List<Service> services)90     public ChreRpcClient(ContextHubClient contextHubClient, long serverNanoappId,
91             List<Service> services) {
92         mContextHubClient = Objects.requireNonNull(contextHubClient);
93         Objects.requireNonNull(services);
94         mServerNanoappId = serverNanoappId;
95         mChannelOutput = new ChreChannelOutput(contextHubClient, serverNanoappId);
96         mChannel = new Channel(mChannelOutput.getChannelId(), mChannelOutput);
97         mRpcClient = Client.create(List.of(mChannel), services);
98     }
99 
100     /**
101      * Returns whether the state matches the server nanoapp and the service is provided.
102      *
103      * @param state           A nanoapp state
104      * @param serverNanoappId The ID of the RPC server nanoapp
105      * @param serviceId       ID of the service
106      * @param serviceVersion  Version of the service
107      * @return the state matches the server nanoapp and the service is provided
108      */
hasService(NanoAppState state, long serverNanoappId, long serviceId, int serviceVersion)109     public static boolean hasService(NanoAppState state, long serverNanoappId, long serviceId,
110             int serviceVersion) {
111         if (state.getNanoAppId() != serverNanoappId) {
112             return false;
113         }
114 
115         for (NanoAppRpcService service : state.getRpcServices()) {
116             if (service.getId() == serviceId) {
117                 return service.getVersion() == serviceVersion;
118             }
119         }
120 
121         return false;
122     }
123 
124     /**
125      * Handles CHRE intents.
126      *
127      * @param intent The CHRE intent, non null
128      */
handleIntent(Intent intent)129     public void handleIntent(Intent intent) {
130         ChreIntentHandler.handle(intent, mServerNanoappId, mRpcClient, mChannelOutput);
131     }
132 
133     /**
134      * Returns the context hub client.
135      */
getContextHubClient()136     public ContextHubClient getContextHubClient() {
137         return mContextHubClient;
138     }
139 
140     /**
141      * Shorthand for closing the underlying ContextHubClient.
142      */
close()143     public void close() {
144         mContextHubClient.close();
145     }
146 
147     /**
148      * Returns a MethodClient.
149      *
150      * Use the client to invoke the service.
151      *
152      * @param methodName the method name as "package.Service.Method" or "package.Service/Method"
153      * @return The MethodClient instance
154      */
getMethodClient(String methodName)155     public MethodClient getMethodClient(String methodName) {
156         return mRpcClient.method(mChannel.id(), methodName);
157     }
158 }
159