camera2: Enforce client eviction on user switch.

Bug: 19186859
Change-Id: I172a2ce46c8e8a131ae7e8dd99d60c5f4f0d6668
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 53f1c72..ca1c504 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 
+#include <cutils/multiuser.h>
 #include <utils/Vector.h>
 #include <utils/KeyedVector.h>
 #include <binder/AppOpsManager.h>
@@ -92,6 +93,11 @@
     // Default number of messages to store in eviction log
     static const size_t DEFAULT_EVICTION_LOG_LENGTH = 50;
 
+    enum {
+        // Default last user id
+        DEFAULT_LAST_USER_ID = 0,
+    };
+
     // Implementation of BinderService<T>
     static char const* getServiceName() { return "media.camera"; }
 
@@ -145,6 +151,8 @@
     virtual status_t    setTorchMode(const String16& cameraId, bool enabled,
             const sp<IBinder>& clientBinder);
 
+    virtual void notifySystemEvent(int eventId, int arg0);
+
     // OK = supports api of that version, -EOPNOTSUPP = does not support
     virtual status_t    supportsCameraApi(
             int cameraId, int apiVersion);
@@ -447,7 +455,7 @@
     virtual void onFirstRef();
 
     // Check if we can connect, before we acquire the service lock.
-    status_t validateConnect(const String8& cameraId, /*inout*/int& clientUid) const;
+    status_t validateConnectLocked(const String8& cameraId, /*inout*/int& clientUid) const;
 
     // Handle active client evictions, and update service state.
     // Only call with with mServiceLock held.
@@ -485,6 +493,9 @@
     // Circular buffer for storing event logging for dumps
     RingBuffer<String8> mEventLog;
 
+    // UID of last user.
+    int mLastUserId;
+
     /**
      * Get the camera state for a given camera id.
      *
@@ -530,6 +541,11 @@
     sp<CameraService::BasicClient> removeClientLocked(const String8& cameraId);
 
     /**
+     * Handle a notification that the current device user has changed.
+     */
+    void doUserSwitch(int newUserId);
+
+    /**
      * Add a event log message that a client has been disconnected.
      */
     void logDisconnected(const String8& cameraId, int clientPid, const String8& clientPackage);
@@ -702,22 +718,24 @@
             "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
             halVersion, static_cast<int>(effectiveApiLevel));
 
-    // Enforce client permissions and do basic sanity checks
-    if((ret = validateConnect(cameraId, /*inout*/clientUid)) != NO_ERROR) {
-        return ret;
-    }
-
     sp<CLIENT> client = nullptr;
     {
         // Acquire mServiceLock and prevent other clients from connecting
         std::unique_ptr<AutoConditionLock> lock =
                 AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
+
         if (lock == nullptr) {
             ALOGE("CameraService::connect X (PID %d) rejected (too many other clients connecting)."
                     , clientPid);
             return -EBUSY;
         }
 
+        // Enforce client permissions and do basic sanity checks
+        if((ret = validateConnectLocked(cameraId, /*inout*/clientUid)) != NO_ERROR) {
+            return ret;
+        }
+        mLastUserId = multiuser_get_user_id(clientUid);
+
         // Check the shim parameters after acquiring lock, if they have already been updated and
         // we were doing a shim update, return immediately
         if (shimUpdateOnly) {