Merge changes from topic "fallback_permission" into main

* changes:
  Camera: Avoid permission check if fallback impl is not enabled
  Camera: Check if fallback impl is granted camera permissions
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index dfbf06b..7665fe8 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -24,6 +24,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.ServiceConnection;
 import android.graphics.ImageFormat;
 import android.hardware.camera2.CameraCharacteristics.Key;
@@ -278,6 +279,8 @@
         private final Object mLock = new Object();
         private final int PROXY_SERVICE_DELAY_MS = 2000;
         private ExtensionConnectionManager mConnectionManager = new ExtensionConnectionManager();
+        private boolean mPermissionForFallbackEnabled = false;
+        private boolean mIsFallbackEnabled = false;
 
         // Singleton, don't allow construction
         private CameraExtensionManagerGlobal() {}
@@ -325,6 +328,7 @@
                                 "Choosing the fallback software implementation service: "
                                 + serviceName);
                         intent.setClassName(packageName, serviceName);
+                        mIsFallbackEnabled = true;
                     }
                 }
 
@@ -436,6 +440,20 @@
                     releaseProxyConnectionLocked(ctx, extension);
                 }
 
+                if (Flags.concertMode() && ret && useFallback && mIsFallbackEnabled) {
+                    try {
+                        InitializeSessionHandler cb = new InitializeSessionHandler(ctx);
+                        initializeSession(cb, extension);
+                        ret = mPermissionForFallbackEnabled;
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Failed to initialize extension. Extension service does not"
+                                + " respond!");
+                        ret = false;
+                    } finally {
+                        releaseSession(extension);
+                    }
+                }
+
                 return ret;
             }
         }
@@ -464,7 +482,6 @@
                 if (!vendorImpl) {
                     unregisterClient(ctx, token, extension);
                     ret = registerClientHelper(ctx, token, extension, true /*useFallback*/);
-
                 }
             }
 
@@ -508,6 +525,7 @@
                     try {
                         mConnectionManager.getProxy(extension).releaseSession();
                         mConnectionManager.setSessionInitialized(false);
+                        mPermissionForFallbackEnabled = false; // Reset permission status
                     } catch (RemoteException e) {
                         Log.e(TAG, "Failed to release session! Extension service does"
                                 + " not respond!");
@@ -556,6 +574,52 @@
             }
         }
 
+        private class InitializeSessionHandler extends IInitializeSessionCallback.Stub {
+            private Context mContext;
+
+            public InitializeSessionHandler(Context context) {
+                mContext = context;
+            }
+
+            @Override
+            public void onSuccess() {
+                // Verify that the camera permission is granted if using
+                // the fallback implementation for an extension
+                String[] callingUidPackages = mContext.getPackageManager()
+                        .getPackagesForUid(Binder.getCallingUid());
+                String fallbackPackageName = mContext.getResources()
+                        .getString(FALLBACK_PACKAGE_NAME);
+
+                if (!fallbackPackageName.isEmpty()
+                        && Arrays.stream(callingUidPackages)
+                        .anyMatch(fallbackPackageName::equals)) {
+                    String[] cameraPermissions = {
+                        android.Manifest.permission.SYSTEM_CAMERA,
+                        android.Manifest.permission.CAMERA
+                    };
+
+                    boolean allPermissionsGranted = true;
+                    for (String permission : cameraPermissions) {
+                        int permissionResult = mContext.checkPermission(permission,
+                                Binder.getCallingPid(), Binder.getCallingUid());
+                        if (permissionResult != PackageManager.PERMISSION_GRANTED) {
+                            Log.w(TAG, permission + " permission not granted for "
+                                    + fallbackPackageName + ", permission check result: "
+                                    + permissionResult);
+                            allPermissionsGranted = false;
+                        }
+                    }
+
+                    mPermissionForFallbackEnabled = allPermissionsGranted;
+                }
+            }
+
+            @Override
+            public void onFailure() {
+                Log.e(TAG, "Failed to initialize proxy service session!");
+            }
+        }
+
         private class ExtensionConnectionManager {
             // Maps extension to ExtensionConnection
             private Map<Integer, ExtensionConnection> mConnections = new HashMap<>();