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 
CarCameraService(Context context)38     public CarCameraService(Context context) {
39         mContext = context;
40         mDeviceMap = new HashMap<Integer, Long>();
41     }
42 
43     @Override
init()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
release()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
dump(PrintWriter writer)84     public void dump(PrintWriter writer) {
85         // TODO
86     }
87 
88     @Override
getCameraList()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
getCapabilities(int cameraType)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
getCameraCrop(int cameraType)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
setCameraCrop(int cameraType, Rect rect)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
getCameraPosition(int cameraType)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
setCameraPosition(int cameraType, Rect rect)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
getCameraState(int cameraType)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
setCameraState(int cameraType, CarCameraState state)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      */
getDeviceIdLocked(int cameraType)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      */
nativeOpen()213     private native long nativeOpen();
nativeClose(long module)214     private native void nativeClose(long module);
nativeGetSupportedCameras(long module)215     private native int[] nativeGetSupportedCameras(long module);
nativeGetDevice(long module, int cameraType)216     private native long nativeGetDevice(long module, int cameraType);
nativeGetCapabilities(long device)217     private native int nativeGetCapabilities(long device);
nativeGetCameraCrop(long device)218     private native Rect nativeGetCameraCrop(long device);
nativeSetCameraCrop(long device, Rect rect)219     private native void nativeSetCameraCrop(long device, Rect rect);
nativeGetCameraPosition(long device)220     private native Rect nativeGetCameraPosition(long device);
nativeSetCameraPosition(long device, Rect rect)221     private native void nativeSetCameraPosition(long device, Rect rect);
nativeGetCameraState(long device)222     private native CarCameraState nativeGetCameraState(long device);
nativeSetCameraState(long device, CarCameraState state)223     private native void nativeSetCameraState(long device, CarCameraState state);
224 }
225