merge in mnc-release history after reset to mnc-dev
diff --git a/fingerprintd/FingerprintDaemonProxy.cpp b/fingerprintd/FingerprintDaemonProxy.cpp
index a8a4024..a55f30a 100644
--- a/fingerprintd/FingerprintDaemonProxy.cpp
+++ b/fingerprintd/FingerprintDaemonProxy.cpp
@@ -41,7 +41,7 @@
     closeHal();
 }
 
-void FingerprintDaemonProxy::hal_notify_callback(fingerprint_msg_t msg) {
+void FingerprintDaemonProxy::hal_notify_callback(const fingerprint_msg_t *msg) {
     FingerprintDaemonProxy* instance = FingerprintDaemonProxy::getInstance();
     const sp<IFingerprintDaemonCallback> callback = instance->mCallback;
     if (callback == NULL) {
@@ -49,52 +49,52 @@
         return;
     }
     const int64_t device = (int64_t) instance->mDevice;
-    switch (msg.type) {
+    switch (msg->type) {
         case FINGERPRINT_ERROR:
-            ALOGD("onError(%d)", msg.data.error);
-            callback->onError(device, msg.data.error);
+            ALOGD("onError(%d)", msg->data.error);
+            callback->onError(device, msg->data.error);
             break;
         case FINGERPRINT_ACQUIRED:
-            ALOGD("onAcquired(%d)", msg.data.acquired.acquired_info);
-            callback->onAcquired(device, msg.data.acquired.acquired_info);
+            ALOGD("onAcquired(%d)", msg->data.acquired.acquired_info);
+            callback->onAcquired(device, msg->data.acquired.acquired_info);
             break;
         case FINGERPRINT_AUTHENTICATED:
             ALOGD("onAuthenticated(fid=%d, gid=%d)",
-                    msg.data.authenticated.finger.fid,
-                    msg.data.authenticated.finger.gid);
-            if (msg.data.authenticated.finger.fid != 0) {
-                uint8_t* hat = reinterpret_cast<uint8_t *>(&msg.data.authenticated.hat);
-                instance->notifyKeystore(hat, sizeof(msg.data.authenticated.hat));
+                    msg->data.authenticated.finger.fid,
+                    msg->data.authenticated.finger.gid);
+            if (msg->data.authenticated.finger.fid != 0) {
+                const uint8_t* hat = reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
+                instance->notifyKeystore(hat, sizeof(msg->data.authenticated.hat));
             }
             callback->onAuthenticated(device,
-                    msg.data.authenticated.finger.fid,
-                    msg.data.authenticated.finger.gid);
+                    msg->data.authenticated.finger.fid,
+                    msg->data.authenticated.finger.gid);
             break;
         case FINGERPRINT_TEMPLATE_ENROLLING:
             ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)",
-                    msg.data.enroll.finger.fid,
-                    msg.data.enroll.finger.gid,
-                    msg.data.enroll.samples_remaining);
+                    msg->data.enroll.finger.fid,
+                    msg->data.enroll.finger.gid,
+                    msg->data.enroll.samples_remaining);
             callback->onEnrollResult(device,
-                    msg.data.enroll.finger.fid,
-                    msg.data.enroll.finger.gid,
-                    msg.data.enroll.samples_remaining);
+                    msg->data.enroll.finger.fid,
+                    msg->data.enroll.finger.gid,
+                    msg->data.enroll.samples_remaining);
             break;
         case FINGERPRINT_TEMPLATE_REMOVED:
             ALOGD("onRemove(fid=%d, gid=%d)",
-                    msg.data.removed.finger.fid,
-                    msg.data.removed.finger.gid);
+                    msg->data.removed.finger.fid,
+                    msg->data.removed.finger.gid);
             callback->onRemoved(device,
-                    msg.data.removed.finger.fid,
-                    msg.data.removed.finger.gid);
+                    msg->data.removed.finger.fid,
+                    msg->data.removed.finger.gid);
             break;
         default:
-            ALOGE("invalid msg: %d", msg.type);
+            ALOGE("invalid msg type: %d", msg->type);
             return;
     }
 }
 
-void FingerprintDaemonProxy::notifyKeystore(uint8_t *auth_token, size_t auth_token_length) {
+void FingerprintDaemonProxy::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) {
     if (auth_token != NULL && auth_token_length > 0) {
         // TODO: cache service?
         sp < IServiceManager > sm = defaultServiceManager();
@@ -151,10 +151,7 @@
 
 int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) {
     ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId);
-    fingerprint_finger_id_t finger;
-    finger.fid = fingerId;
-    finger.gid = groupId;
-    return mDevice->remove(mDevice, finger);
+    return mDevice->remove(mDevice, groupId, fingerId);
 }
 
 uint64_t FingerprintDaemonProxy::getAuthenticatorId() {
diff --git a/fingerprintd/FingerprintDaemonProxy.h b/fingerprintd/FingerprintDaemonProxy.h
index 95c926b..50d30ef 100644
--- a/fingerprintd/FingerprintDaemonProxy.h
+++ b/fingerprintd/FingerprintDaemonProxy.h
@@ -48,8 +48,8 @@
         FingerprintDaemonProxy();
         virtual ~FingerprintDaemonProxy();
         void binderDied(const wp<IBinder>& who);
-        void notifyKeystore(uint8_t *auth_token, size_t auth_token_length);
-        static void hal_notify_callback(fingerprint_msg_t msg);
+        void notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length);
+        static void hal_notify_callback(const fingerprint_msg_t *msg);
 
         static FingerprintDaemonProxy* sInstance;
         fingerprint_module_t const* mModule;
diff --git a/fingerprintd/IFingerprintDaemon.h b/fingerprintd/IFingerprintDaemon.h
index fe3f64b..08cb008 100644
--- a/fingerprintd/IFingerprintDaemon.h
+++ b/fingerprintd/IFingerprintDaemon.h
@@ -65,7 +65,7 @@
 
         // DECLARE_META_INTERFACE - C++ client interface not needed
         static const android::String16 descriptor;
-        static void hal_notify_callback(fingerprint_msg_t msg);
+        static void hal_notify_callback(const fingerprint_msg_t *msg);
 };
 
 // ----------------------------------------------------------------------------
diff --git a/run-as/package.c b/run-as/package.c
index 9e1f5bb..aea89e5 100644
--- a/run-as/package.c
+++ b/run-as/package.c
@@ -16,6 +16,7 @@
 */
 #include <errno.h>
 #include <fcntl.h>
+#include <stdio.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -421,7 +422,7 @@
  * If the package database is corrupted, return -1 and set errno to EINVAL
  */
 int
-get_package_info(const char* pkgName, PackageInfo *info)
+get_package_info(const char* pkgName, uid_t userId, PackageInfo *info)
 {
     char*        buffer;
     size_t       buffer_len;
@@ -506,7 +507,20 @@
         if (q == p)
             goto BAD_FORMAT;
 
-        p = string_copy(info->dataDir, sizeof info->dataDir, p, q - p);
+        /* If userId == 0 (i.e. user is device owner) we can use dataDir value
+         * from packages.list, otherwise compose data directory as
+         * /data/user/$uid/$packageId
+         */
+        if (userId == 0) {
+            p = string_copy(info->dataDir, sizeof info->dataDir, p, q - p);
+        } else {
+            snprintf(info->dataDir,
+                     sizeof info->dataDir,
+                     "/data/user/%d/%s",
+                     userId,
+                     pkgName);
+            p = q;
+        }
 
         /* skip spaces */
         if (parse_spaces(&p, end) < 0)
diff --git a/run-as/package.h b/run-as/package.h
index 34603c0..eeb5913 100644
--- a/run-as/package.h
+++ b/run-as/package.h
@@ -33,9 +33,11 @@
     char   seinfo[PATH_MAX];
 } PackageInfo;
 
-/* see documentation in package.c for these functiosn */
+/* see documentation in package.c for these functions */
 
-extern int  get_package_info(const char* packageName, PackageInfo*  info);
+extern int  get_package_info(const char* packageName,
+                             uid_t userId,
+                             PackageInfo*  info);
 
 extern int  check_data_path(const char* dataDir, uid_t uid);
 
diff --git a/run-as/run-as.c b/run-as/run-as.c
index 368b8f1..3f32e7d 100644
--- a/run-as/run-as.c
+++ b/run-as/run-as.c
@@ -102,13 +102,14 @@
 static void
 usage(void)
 {
-    panic("Usage:\n    " PROGNAME " <package-name> <command> [<args>]\n");
+    panic("Usage:\n    " PROGNAME " <package-name> [--user <uid>] <command> [<args>]\n");
 }
 
 int main(int argc, char **argv)
 {
     const char* pkgname;
-    int myuid, uid, gid;
+    uid_t myuid, uid, gid, userAppId = 0;
+    int commandArgvOfs = 2, userId = 0;
     PackageInfo info;
     struct __user_cap_header_struct capheader;
     struct __user_cap_data_struct capdata[2];
@@ -136,14 +137,31 @@
         panic("Could not set capabilities: %s\n", strerror(errno));
     }
 
-    /* retrieve package information from system (does setegid) */
     pkgname = argv[1];
-    if (get_package_info(pkgname, &info) < 0) {
+
+    /* get user_id from command line if provided */
+    if ((argc >= 4) && !strcmp(argv[2], "--user")) {
+        userId = atoi(argv[3]);
+        if (userId < 0)
+            panic("Negative user id %d is provided\n", userId);
+        commandArgvOfs += 2;
+    }
+
+    /* retrieve package information from system (does setegid) */
+    if (get_package_info(pkgname, userId, &info) < 0) {
         panic("Package '%s' is unknown\n", pkgname);
     }
 
+    /* verify that user id is not too big. */
+    if ((UID_MAX - info.uid) / AID_USER < (uid_t)userId) {
+        panic("User id %d is too big\n", userId);
+    }
+
+    /* calculate user app ID. */
+    userAppId = (AID_USER * userId) + info.uid;
+
     /* reject system packages */
-    if (info.uid < AID_APP) {
+    if (userAppId < AID_APP) {
         panic("Package '%s' is not an application\n", pkgname);
     }
 
@@ -153,14 +171,14 @@
     }
 
     /* check that the data directory path is valid */
-    if (check_data_path(info.dataDir, info.uid) < 0) {
+    if (check_data_path(info.dataDir, userAppId) < 0) {
         panic("Package '%s' has corrupt installation\n", pkgname);
     }
 
     /* Ensure that we change all real/effective/saved IDs at the
      * same time to avoid nasty surprises.
      */
-    uid = gid = info.uid;
+    uid = gid = userAppId;
     if(setresgid(gid,gid,gid) || setresuid(uid,uid,uid)) {
         panic("Permission denied\n");
     }
@@ -181,8 +199,9 @@
     }
 
     /* User specified command for exec. */
-    if ((argc >= 3) && (execvp(argv[2], argv+2) < 0)) {
-        panic("exec failed for %s: %s\n", argv[2], strerror(errno));
+    if ((argc >= commandArgvOfs + 1) &&
+        (execvp(argv[commandArgvOfs], argv+commandArgvOfs) < 0)) {
+        panic("exec failed for %s: %s\n", argv[commandArgvOfs], strerror(errno));
     }
 
     /* Default exec shell. */