The CameraManager class is an entry class open to the App to use the camera. It includes operations such as getting a list of camera ids, opening and closing the camera, for detecting, representing, and connecting to the CameraDevice.

Below is the code for the APP to get the CameraManager class. CAMERA_SERVICE is defined in the Context, CAMERA_SERVICE = “camera”.

val manager = activity.getSystemService(Context.CAMERA_SERVICE) as CameraManager
Copy the code

Since the name passed in is not equal to either WINDOW_SERVICE or SEARCH_SERVICE, the getSystemService lookup is called with its parent ContextThemeWrapper.

frameworks/base/core/java/android/app/Activity.java

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2.Window.Callback.KeyEvent.Callback.OnCreateContextMenuListener.ComponentCallbacks2.Window.OnWindowDismissedCallback {...@Override
    public Object getSystemService(@ServiceName @NonNull String name) {
        if (getBaseContext() == null) {
            throw new IllegalStateException(
                    "System services not available to Activities before onCreate()");
        }

        if (WINDOW_SERVICE.equals(name)) {
            return mWindowManager;
        } else if (SEARCH_SERVICE.equals(name)) {
            ensureSearchManager();
            return mSearchManager;
        }
        return super.getSystemService(name); }... }Copy the code

ContextImpl method getSystemService(…) .

frameworks/base/core/java/android/app/ContextImpl.java

class ContextImpl extends Context {...@Override
    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name); }... }Copy the code

The SystemServiceRegistry class manages all system services that can be returned by Context#getSystemService. SYSTEM_SERVICE_FETCHERS is a HashMap whose key is String and value is ServiceFetcher<? >. So where does this HashMap populate?

frameworks/base/core/java/android/app/SystemServiceRegistry.java

final class SystemServiceRegistry {...private static finalHashMap<String, ServiceFetcher<? >> SYSTEM_SERVICE_FETCHERS =newHashMap<String, ServiceFetcher<? > > (); .public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<? > fetcher = SYSTEM_SERVICE_FETCHERS.get(name);returnfetcher ! =null ? fetcher.getService(ctx) : null; }... }Copy the code

It was added in the static block of the SystemServiceRegistry class. This includes CAMERA_SERVICE. CachedServiceFetcher inherits from ServiceFetcher. CachedServiceFetcher is an abstract class whose createService(…) Method to be implemented. The getService (…). The ContextImpl member mServiceCache method retrieves the cache array from the ContextImpl member variable mServiceCache, and then gets the Object from the corresponding mCacheIndex. Since this “pit” was just added to the CachedServiceFetcher constructor (mCacheIndex = sServiceCacheSize++), the service must be null. CreateService (…) is called. Create the corresponding object and assign a value to the corresponding cache pit.

frameworks/base/core/java/android/app/SystemServiceRegistry.java

final class SystemServiceRegistry {...private static intsServiceCacheSize; .static{... registerService(Context.CAMERA_SERVICE, CameraManager.class,new CachedServiceFetcher<CameraManager>() {
            @Override
            public CameraManager createService(ContextImpl ctx) {
                return newCameraManager(ctx); }}); . }...private static <T> void registerService(String serviceName, Class
       
         serviceClass, ServiceFetcher
        
          serviceFetcher)
        
        { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); }...static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
        private final int mCacheIndex;

        public CachedServiceFetcher(a) {
            mCacheIndex = sServiceCacheSize++;
        }

        @Override
        @SuppressWarnings("unchecked")
        public final T getService(ContextImpl ctx) {
            finalObject[] cache = ctx.mservicecache;synchronized (cache) {
                // Fetch or create the service.
                Object service = cache[mCacheIndex];
                if (service == null) {
                    service = createService(ctx);
                    cache[mCacheIndex] = service;
                }
                return(T)service; }}public abstract T createService(ContextImpl ctx); }... }Copy the code

The cache array points to mServiceCache, a member of the ContextImpl class. The mServiceCache assignment actually calls the createServiceCache() method of the SystemServiceRegistry class again.

frameworks/base/core/java/android/app/ContextImpl.java

class ContextImpl extends Context {...// The system service cache for the system services that are cached per-ContextImpl.
    finalObject[] mServiceCache = SystemServiceRegistry.createServiceCache(); . }Copy the code

Create an array to cache each context service instance.

frameworks/base/core/java/android/app/SystemServiceRegistry.java

final class SystemServiceRegistry {...public static Object[] createServiceCache() {
        return newObject[sServiceCacheSize]; }... }Copy the code

You now have a CameraManager object.

frameworks/base/core/java/android/hardware/camera2/CameraManager.java

public final class CameraManager {...private final Context mContext;
    private final Object mLock = new Object();

    / * * *@hide* /
    public CameraManager(Context context) {
        synchronized(mLock) { mContext = context; }}... }Copy the code