1 /* 2 * Copyright 2017 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 android.hardware.location; 17 18 import android.annotation.NonNull; 19 import android.annotation.RequiresPermission; 20 import android.annotation.SystemApi; 21 import android.os.RemoteException; 22 23 import com.android.internal.util.Preconditions; 24 25 import dalvik.system.CloseGuard; 26 27 import java.io.Closeable; 28 import java.util.concurrent.atomic.AtomicBoolean; 29 30 /** 31 * A class describing a client of the Context Hub Service. 32 * 33 * Clients can send messages to nanoapps at a Context Hub through this object. The APIs supported 34 * by this object are thread-safe and can be used without external synchronization. 35 * 36 * @hide 37 */ 38 @SystemApi 39 public class ContextHubClient implements Closeable { 40 /* 41 * The proxy to the client interface at the service. 42 */ 43 private IContextHubClient mClientProxy = null; 44 45 /* 46 * The Context Hub that this client is attached to. 47 */ 48 private final ContextHubInfo mAttachedHub; 49 50 private final CloseGuard mCloseGuard = CloseGuard.get(); 51 52 private final AtomicBoolean mIsClosed = new AtomicBoolean(false); 53 ContextHubClient(ContextHubInfo hubInfo)54 /* package */ ContextHubClient(ContextHubInfo hubInfo) { 55 mAttachedHub = hubInfo; 56 mCloseGuard.open("close"); 57 } 58 59 /** 60 * Sets the proxy interface of the client at the service. This method should always be called 61 * by the ContextHubManager after the client is registered at the service, and should only be 62 * called once. 63 * 64 * @param clientProxy the proxy of the client at the service 65 */ setClientProxy(IContextHubClient clientProxy)66 /* package */ void setClientProxy(IContextHubClient clientProxy) { 67 Preconditions.checkNotNull(clientProxy, "IContextHubClient cannot be null"); 68 if (mClientProxy != null) { 69 throw new IllegalStateException("Cannot change client proxy multiple times"); 70 } 71 72 mClientProxy = clientProxy; 73 } 74 75 /** 76 * Returns the hub that this client is attached to. 77 * 78 * @return the ContextHubInfo of the attached hub 79 */ 80 @NonNull getAttachedHub()81 public ContextHubInfo getAttachedHub() { 82 return mAttachedHub; 83 } 84 85 /** 86 * Closes the connection for this client and the Context Hub Service. 87 * 88 * When this function is invoked, the messaging associated with this client is invalidated. 89 * All futures messages targeted for this client are dropped at the service. 90 */ close()91 public void close() { 92 if (!mIsClosed.getAndSet(true)) { 93 mCloseGuard.close(); 94 try { 95 mClientProxy.close(); 96 } catch (RemoteException e) { 97 throw e.rethrowFromSystemServer(); 98 } 99 } 100 } 101 102 /** 103 * Sends a message to a nanoapp through the Context Hub Service. 104 * 105 * This function returns TRANSACTION_SUCCESS if the message has reached the HAL, but 106 * does not guarantee delivery of the message to the target nanoapp. 107 * 108 * @param message the message object to send 109 * 110 * @return the result of sending the message defined as in ContextHubTransaction.Result 111 * 112 * @throws NullPointerException if NanoAppMessage is null 113 * 114 * @see NanoAppMessage 115 * @see ContextHubTransaction.Result 116 */ 117 @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) 118 @ContextHubTransaction.Result sendMessageToNanoApp(@onNull NanoAppMessage message)119 public int sendMessageToNanoApp(@NonNull NanoAppMessage message) { 120 Preconditions.checkNotNull(message, "NanoAppMessage cannot be null"); 121 122 try { 123 return mClientProxy.sendMessageToNanoApp(message); 124 } catch (RemoteException e) { 125 throw e.rethrowFromSystemServer(); 126 } 127 } 128 129 @Override finalize()130 protected void finalize() throws Throwable { 131 try { 132 if (mCloseGuard != null) { 133 mCloseGuard.warnIfOpen(); 134 } 135 close(); 136 } finally { 137 super.finalize(); 138 } 139 } 140 } 141