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.hardware.location.ContextHubClient; 19 import android.hardware.location.ContextHubTransaction; 20 import android.hardware.location.NanoAppMessage; 21 22 import java.util.concurrent.atomic.AtomicBoolean; 23 24 import dev.pigweed.pw_rpc.Channel; 25 import dev.pigweed.pw_rpc.ChannelOutputException; 26 27 /** 28 * Implements the Channel.Output interface of Pigweed RPC and provides a layer of abstraction on top 29 * of Pigweed RPC to make it more friendly to use with CHRE APIs. 30 */ 31 public class ChreChannelOutput implements Channel.Output { 32 /** 33 * Message type to use for RPC messages. 34 */ 35 public static final int CHRE_MESSAGE_TYPE_RPC = 0x7FFFFFF5; 36 37 // 1 denotes that a host endpoint is the client that created the channel. 38 private static final int CHANNEL_ID_HOST_CLIENT = (1 << 16); 39 40 private final ContextHubClient mClient; 41 private final long mNanoappId; 42 43 // Whether this output channel is no longer able to communicate with the nanoapp. 44 private AtomicBoolean mAuthDenied = new AtomicBoolean(false); 45 ChreChannelOutput(ContextHubClient client, long nanoappId)46 public ChreChannelOutput(ContextHubClient client, long nanoappId) { 47 mClient = client; 48 mNanoappId = nanoappId; 49 } 50 51 /** 52 * This method MUST NOT be called directly from users of this class. 53 */ 54 @Override send(byte[] packet)55 public void send(byte[] packet) throws ChannelOutputException { 56 NanoAppMessage message = NanoAppMessage.createMessageToNanoApp(mNanoappId, 57 CHRE_MESSAGE_TYPE_RPC, packet); 58 if (mAuthDenied.get() 59 || ContextHubTransaction.RESULT_SUCCESS != mClient.sendMessageToNanoApp(message)) { 60 throw new ChannelOutputException(); 61 } 62 } 63 64 /** 65 * @return Channel ID to use for all Channels that use this output to send 66 * messages to a nanoapp. 67 */ getChannelId()68 public int getChannelId() { 69 return (CHANNEL_ID_HOST_CLIENT | mClient.getId()); 70 } 71 72 /** 73 * Used to indicate whether the particular nanoapp cannot be communicated 74 * with any more (e.g. due to permissions loss). 75 */ setAuthDenied(boolean denied)76 void setAuthDenied(boolean denied) { 77 mAuthDenied.set(denied); 78 } 79 } 80