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 17 package com.android.car.evs; 18 19 import android.hardware.HardwareBuffer; 20 21 import com.android.car.internal.evs.EvsHalWrapper; 22 import com.android.internal.annotations.GuardedBy; 23 import com.android.internal.annotations.VisibleForTesting; 24 25 /** 26 * EvaHalWrapper impl used by updatable car service. 27 */ 28 public final class EvsHalWrapperImpl extends EvsHalWrapper { 29 30 31 /** 32 * Because of its dependency on FMQ type, android.hardware.automotive.evs@1.1 interface does 33 * not support Java backend. Therefore, all hwbinder transactions happen in native methods 34 * declared below. 35 */ 36 37 static { 38 System.loadLibrary("carservicejni"); 39 } 40 41 private final EvsHalWrapper.HalEventCallback mCallback; 42 43 private final Object mLock = new Object(); 44 45 /** Stores a service handle initialized in native methods */ 46 @GuardedBy("mLock") 47 private long mNativeEvsServiceObj; 48 49 /** Constructor */ EvsHalWrapperImpl(EvsHalWrapper.HalEventCallback callback)50 public EvsHalWrapperImpl(EvsHalWrapper.HalEventCallback callback) { 51 super(); 52 mCallback = callback; 53 } 54 55 /** 56 * Create a {@code EvsHalWrapperImpl} object with a given JNI library that implements native 57 * methods. 58 */ 59 @VisibleForTesting create(EvsHalWrapper.HalEventCallback callback, String jniLibraryName)60 static EvsHalWrapperImpl create(EvsHalWrapper.HalEventCallback callback, 61 String jniLibraryName) { 62 System.loadLibrary(jniLibraryName); 63 return new EvsHalWrapperImpl(callback); 64 } 65 66 @Override init()67 public boolean init() { 68 long handle = nativeCreateServiceHandle(); 69 if (handle == 0) { 70 return false; 71 } 72 synchronized (mLock) { 73 mNativeEvsServiceObj = handle; 74 } 75 return true; 76 } 77 78 @Override release()79 public void release() { 80 long handle; 81 synchronized (mLock) { 82 handle = mNativeEvsServiceObj; 83 mNativeEvsServiceObj = 0; 84 } 85 if (handle == 0) { 86 return; 87 } 88 nativeDestroyServiceHandle(handle); 89 } 90 91 @Override isConnected()92 public boolean isConnected() { 93 return getNativeHandle() != 0; 94 } 95 96 @Override connectToHalServiceIfNecessary()97 public boolean connectToHalServiceIfNecessary() { 98 if (!isConnected() && !init()) { 99 return false; 100 } 101 102 return nativeConnectToHalServiceIfNecessary(getNativeHandle()); 103 } 104 105 @Override disconnectFromHalService()106 public void disconnectFromHalService() { 107 nativeDisconnectFromHalService(getNativeHandle()); 108 } 109 110 @Override openCamera(String cameraId)111 public boolean openCamera(String cameraId) { 112 return nativeOpenCamera(getNativeHandle(), cameraId); 113 } 114 115 @Override closeCamera()116 public void closeCamera() { 117 nativeCloseCamera(getNativeHandle()); 118 } 119 120 @Override requestToStartVideoStream()121 public boolean requestToStartVideoStream() { 122 return nativeRequestToStartVideoStream(getNativeHandle()); 123 } 124 125 @Override requestToStopVideoStream()126 public void requestToStopVideoStream() { 127 nativeRequestToStopVideoStream(getNativeHandle()); 128 } 129 130 @Override doneWithFrame(int bufferId)131 public void doneWithFrame(int bufferId) { 132 nativeDoneWithFrame(getNativeHandle(), bufferId); 133 } 134 135 @VisibleForTesting setServiceHandle(long handleToUse)136 boolean setServiceHandle(long handleToUse) { 137 if (handleToUse == 0) { 138 return false; 139 } 140 141 long handleToDestroy; 142 synchronized (mLock) { 143 handleToDestroy = mNativeEvsServiceObj; 144 mNativeEvsServiceObj = handleToUse; 145 } 146 147 nativeDestroyServiceHandle(handleToDestroy); 148 return true; 149 } 150 151 @VisibleForTesting createServiceHandleForTest()152 long createServiceHandleForTest() { 153 return nativeCreateServiceHandleForTest(); 154 } 155 156 157 @VisibleForTesting triggerBinderDied()158 void triggerBinderDied() { 159 nativeTriggerBinderDied(getNativeHandle()); 160 } 161 getNativeHandle()162 private long getNativeHandle() { 163 synchronized (mLock) { 164 return mNativeEvsServiceObj; 165 } 166 } 167 168 /** EVS stream event handler called after a native handler */ postNativeEventHandler(int eventType)169 private void postNativeEventHandler(int eventType) { 170 mCallback.onHalEvent(eventType); 171 } 172 173 /** EVS frame handler called after a native handler */ postNativeFrameHandler(int id, HardwareBuffer buffer)174 private void postNativeFrameHandler(int id, HardwareBuffer buffer) { 175 mCallback.onFrameEvent(id, buffer); 176 } 177 178 /** EVS service death handler called after a native handler */ postNativeDeathHandler()179 private void postNativeDeathHandler() { 180 mCallback.onHalDeath(); 181 } 182 183 /** Attempts to connect to the HAL service if it has not done yet */ nativeConnectToHalServiceIfNecessary(long handle)184 private native boolean nativeConnectToHalServiceIfNecessary(long handle); 185 186 /** Attempts to disconnect from the HAL service */ nativeDisconnectFromHalService(long handle)187 private native void nativeDisconnectFromHalService(long handle); 188 189 /** Attempts to open a target camera device */ nativeOpenCamera(long handle, String cameraId)190 private native boolean nativeOpenCamera(long handle, String cameraId); 191 192 /** Requests to close a target camera device */ nativeCloseCamera(long handle)193 private native void nativeCloseCamera(long handle); 194 195 /** Requests to start a video stream */ nativeRequestToStartVideoStream(long handle)196 private native boolean nativeRequestToStartVideoStream(long handle); 197 198 /** Requests to stop a video stream */ nativeRequestToStopVideoStream(long handle)199 private native void nativeRequestToStopVideoStream(long handle); 200 201 /** Request to return an used buffer */ nativeDoneWithFrame(long handle, int bufferId)202 private native void nativeDoneWithFrame(long handle, int bufferId); 203 204 /** Trigger a onBinderDied callback for tests */ nativeTriggerBinderDied(long handle)205 private native void nativeTriggerBinderDied(long handle); 206 207 /** Creates a EVS service handle */ nativeCreateServiceHandle()208 private static native long nativeCreateServiceHandle(); 209 210 /** Creates a EVS service handle for tests */ nativeCreateServiceHandleForTest()211 private static native long nativeCreateServiceHandleForTest(); 212 213 /** Destroys a EVS service handle */ nativeDestroyServiceHandle(long handle)214 private static native void nativeDestroyServiceHandle(long handle); 215 } 216