1 /* 2 * Copyright (C) 2015 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; 18 19 import android.content.Context; 20 import android.car.hardware.camera.CarCameraState; 21 import android.car.hardware.camera.ICarCamera; 22 import android.graphics.Rect; 23 import android.util.Log; 24 25 import java.io.PrintWriter; 26 import java.util.Collection; 27 import java.util.HashMap; 28 import java.util.Set; 29 30 public class CarCameraService extends ICarCamera.Stub implements CarServiceBase { 31 public static final boolean DBG = false; 32 public static final String TAG = CarLog.TAG_CAMERA + ".CarCameraService"; 33 34 private final Context mContext; 35 private long mModule; 36 private final HashMap<Integer, Long> mDeviceMap; 37 38 public CarCameraService(Context context) { 39 mContext = context; 40 mDeviceMap = new HashMap<Integer, Long>(); 41 } 42 43 @Override 44 public synchronized void init() { 45 if (DBG) { 46 Log.d(TAG, "init called"); 47 } 48 mModule = nativeOpen(); 49 50 if (mModule != 0) { 51 int[] cameraType = nativeGetSupportedCameras(mModule); 52 53 if (cameraType != null) { 54 for (int i : cameraType) { 55 long devicePtr = nativeGetDevice(mModule, i); 56 if (devicePtr == 0) { 57 Log.e(TAG, "Null device pointer returned for cameraType = " + i); 58 } else { 59 mDeviceMap.put(i, devicePtr); 60 } 61 } 62 } else { 63 Log.e(TAG, "No car cameras are supported"); 64 } 65 } else { 66 Log.w(TAG, "Cannot load camera module"); 67 } 68 } 69 70 @Override 71 public synchronized void release() { 72 if (DBG) { 73 Log.d(TAG, "release called"); 74 } 75 Collection<Long> devices = mDeviceMap.values(); 76 for (Long device : devices) { 77 nativeClose(device); 78 } 79 mDeviceMap.clear(); 80 mModule = 0; 81 } 82 83 @Override 84 public void dump(PrintWriter writer) { 85 // TODO 86 } 87 88 @Override 89 public int[] getCameraList() { 90 if (DBG) { 91 Log.d(TAG, "getCameraList called"); 92 } 93 Set<Integer> keySet; 94 synchronized (this) { 95 keySet = mDeviceMap.keySet(); 96 } 97 98 int keySetSize = keySet.size(); 99 100 if (keySetSize > 0) { 101 int[] keyArray = new int[keySet.size()]; 102 int i = 0; 103 for (Integer key : keySet) { 104 keyArray[i++] = key.intValue(); 105 } 106 return keyArray; 107 } else { 108 return null; 109 } 110 } 111 112 @Override 113 public int getCapabilities(int cameraType) { 114 if (DBG) { 115 Log.d(TAG, "getCapabilities called, type = " + String.valueOf(cameraType)); 116 } 117 synchronized (this) { 118 long device = getDeviceIdLocked(cameraType); 119 return nativeGetCapabilities(device); 120 } 121 } 122 123 @Override 124 public Rect getCameraCrop(int cameraType) { 125 Rect rect; 126 synchronized (this) { 127 long device = getDeviceIdLocked(cameraType); 128 rect = nativeGetCameraCrop(device); 129 } 130 if(DBG && (rect != null)) { 131 Log.d(TAG, "getCameraCrop called: " + rect.toString()); 132 } 133 return rect; 134 } 135 136 @Override 137 public void setCameraCrop(int cameraType, Rect rect) { 138 if (DBG) { 139 Log.d(TAG, "setCameraCrop called." + rect.toString()); 140 } 141 synchronized (this) { 142 long device = getDeviceIdLocked(cameraType); 143 nativeSetCameraCrop(device, rect); 144 } 145 } 146 147 @Override 148 public Rect getCameraPosition(int cameraType) { 149 Rect rect; 150 synchronized (this) { 151 long device = getDeviceIdLocked(cameraType); 152 rect = nativeGetCameraPosition(device); 153 } 154 if(DBG && (rect != null)) { 155 Log.d(TAG, "getCameraPosition called: " + rect.toString()); 156 } 157 return rect; 158 } 159 160 @Override 161 public void setCameraPosition(int cameraType, Rect rect) { 162 if (DBG) { 163 Log.d(TAG, "setCameraPosition called." + rect.toString()); 164 } 165 synchronized (this) { 166 long device = getDeviceIdLocked(cameraType); 167 nativeSetCameraPosition(device, rect); 168 } 169 } 170 171 @Override 172 public CarCameraState getCameraState(int cameraType) { 173 CarCameraState state; 174 synchronized (this) { 175 long device = getDeviceIdLocked(cameraType); 176 state = nativeGetCameraState(device); 177 } 178 if(DBG && (state != null)) { 179 Log.d(TAG, "getCameraState called: " + state.toString()); 180 } 181 return state; 182 } 183 184 @Override 185 public void setCameraState(int cameraType, CarCameraState state) { 186 if (DBG) { 187 Log.d(TAG, "setCameraState called. state: " + state.toString()); 188 } 189 synchronized (this) { 190 long device = getDeviceIdLocked(cameraType); 191 nativeSetCameraState(device, state); 192 } 193 } 194 195 /** 196 * Validates that the cameraType is available and ready to be used. 197 * @param cameraType 198 * @return 199 */ 200 private long getDeviceIdLocked(int cameraType) { 201 Long deviceId = mDeviceMap.get(cameraType); 202 203 if (deviceId == null) { 204 throw new IllegalArgumentException("cameraType " + cameraType + " doesn't exist in" 205 + "device map"); 206 } 207 return deviceId; 208 } 209 210 /* 211 * Native function definitions 212 */ 213 private native long nativeOpen(); 214 private native void nativeClose(long module); 215 private native int[] nativeGetSupportedCameras(long module); 216 private native long nativeGetDevice(long module, int cameraType); 217 private native int nativeGetCapabilities(long device); 218 private native Rect nativeGetCameraCrop(long device); 219 private native void nativeSetCameraCrop(long device, Rect rect); 220 private native Rect nativeGetCameraPosition(long device); 221 private native void nativeSetCameraPosition(long device, Rect rect); 222 private native CarCameraState nativeGetCameraState(long device); 223 private native void nativeSetCameraState(long device, CarCameraState state); 224 } 225