Merge "use 'cmd' command for install-multiple"
diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h
index 2d3e82a..85bd263 100644
--- a/include/utils/SortedVector.h
+++ b/include/utils/SortedVector.h
@@ -38,18 +38,18 @@
 
 public:
             typedef TYPE    value_type;
-    
-    /*! 
+
+    /*!
      * Constructors and destructors
      */
-    
+
                             SortedVector();
                             SortedVector(const SortedVector<TYPE>& rhs);
     virtual                 ~SortedVector();
 
     /*! copy operator */
-    const SortedVector<TYPE>&   operator = (const SortedVector<TYPE>& rhs) const;    
-    SortedVector<TYPE>&         operator = (const SortedVector<TYPE>& rhs);    
+    const SortedVector<TYPE>&   operator = (const SortedVector<TYPE>& rhs) const;
+    SortedVector<TYPE>&         operator = (const SortedVector<TYPE>& rhs);
 
     /*
      * empty the vector
@@ -57,7 +57,7 @@
 
     inline  void            clear()             { VectorImpl::clear(); }
 
-    /*! 
+    /*!
      * vector stats
      */
 
@@ -70,11 +70,11 @@
     //! sets the capacity. capacity can never be reduced less than size()
     inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }
 
-    /*! 
+    /*!
      * C-style array access
      */
-     
-    //! read-only C-style access 
+
+    //! read-only C-style access
     inline  const TYPE*     array() const;
 
     //! read-write C-style access. BE VERY CAREFUL when modifying the array
@@ -83,12 +83,12 @@
 
             //! finds the index of an item
             ssize_t         indexOf(const TYPE& item) const;
-            
+
             //! finds where this item should be inserted
             size_t          orderOf(const TYPE& item) const;
-            
-    
-    /*! 
+
+
+    /*!
      * accessors
      */
 
@@ -105,7 +105,7 @@
 
             //! add an item in the right place (and replace the one that is there)
             ssize_t         add(const TYPE& item);
-            
+
             //! editItemAt() MUST NOT change the order of this item
             TYPE&           editItemAt(size_t index) {
                 return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) );
@@ -114,7 +114,7 @@
             //! merges a vector into this one
             ssize_t         merge(const Vector<TYPE>& vector);
             ssize_t         merge(const SortedVector<TYPE>& vector);
-            
+
             //! removes an item
             ssize_t         remove(const TYPE&);
 
@@ -122,7 +122,24 @@
     inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);
     //! remove one item
     inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }
-            
+
+    /*
+     * these inlines add some level of compatibility with STL.
+     */
+    typedef TYPE* iterator;
+    typedef TYPE const* const_iterator;
+
+    inline iterator begin() { return editArray(); }
+    inline iterator end()   { return editArray() + size(); }
+    inline const_iterator begin() const { return array(); }
+    inline const_iterator end() const   { return array() + size(); }
+    inline void reserve(size_t n) { setCapacity(n); }
+    inline bool empty() const{ return isEmpty(); }
+    inline iterator erase(iterator pos) {
+        ssize_t index = removeItemsAt(pos-array());
+        return begin() + index;
+    }
+
 protected:
     virtual void    do_construct(void* storage, size_t num) const;
     virtual void    do_destroy(void* storage, size_t num) const;
@@ -164,13 +181,13 @@
 template<class TYPE> inline
 SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
     SortedVectorImpl::operator = (rhs);
-    return *this; 
+    return *this;
 }
 
 template<class TYPE> inline
 const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
     SortedVectorImpl::operator = (rhs);
-    return *this; 
+    return *this;
 }
 
 template<class TYPE> inline
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index e681718..a6eaf11 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -91,6 +91,7 @@
     { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" },
     { 00750, AID_ROOT,   AID_SHELL,  0, "data/nativetest" },
     { 00750, AID_ROOT,   AID_SHELL,  0, "data/nativetest64" },
+    { 00775, AID_ROOT,   AID_ROOT,   0, "data/preloads" },
     { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },
     { 00755, AID_ROOT,   AID_SYSTEM, 0, "mnt" },
     { 00755, AID_ROOT,   AID_ROOT,   0, "root" },
diff --git a/logcat/logpersist b/logcat/logpersist
index e9982e2..f0e7d42 100755
--- a/logcat/logpersist
+++ b/logcat/logpersist
@@ -17,6 +17,7 @@
    ;;
 esac
 
+log_tag_property=persist.log.tag
 data=/data/misc/logd
 service=logcatd
 size_default=256
@@ -65,6 +66,9 @@
   exit 1
 fi
 
+log_tag="`getprop ${log_tag_property}`"
+logd_logpersistd="`getprop ${property}`"
+
 case ${progname} in
 *.cat)
   if [ -n "${size}${buffer}" -o "true" = "${clear}" ]; then
@@ -123,6 +127,12 @@
   while [ "clear" = "`getprop ${property#persist.}`" ]; do
     continue
   done
+  # Tell Settings that we are back on again if we turned logging off
+  tag="${log_tag#Settings}"
+  if [ X"${log_tag}" != X"${tag}" ]; then
+    echo "WARNING: enabling logd service" >&2
+    setprop ${log_tag_property} "${tag#,}"
+  fi
   # ${service}.rc does the heavy lifting with the following trigger
   setprop ${property} ${service}
   # 20ms done, to permit process feedback check
@@ -158,3 +168,9 @@
   echo "ERROR: Unexpected command ${0##*/} ${args}" >&2
   exit 1
 esac
+
+if [ X"${log_tag}" != X"`getprop ${log_tag_property}`" ] ||
+   [ X"${logd_logpersistd}" != X"`getprop ${property}`" ]; then
+  echo "WARNING: killing Settings" >&2
+  am force-stop com.android.settings
+fi
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index ac2b128..a0b7499 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -401,7 +401,32 @@
     }
 }
 
-pid_t LogKlog::sniffPid(const char *cp, size_t len) {
+pid_t LogKlog::sniffPid(const char **buf, size_t len) {
+    const char *cp = *buf;
+    // HTC kernels with modified printk "c0   1648 "
+    if ((len > 9) &&
+            (cp[0] == 'c') &&
+            isdigit(cp[1]) &&
+            (isdigit(cp[2]) || (cp[2] == ' ')) &&
+            (cp[3] == ' ')) {
+        bool gotDigit = false;
+        int i;
+        for (i = 4; i < 9; ++i) {
+            if (isdigit(cp[i])) {
+                gotDigit = true;
+            } else if (gotDigit || (cp[i] != ' ')) {
+                break;
+            }
+        }
+        if ((i == 9) && (cp[i] == ' ')) {
+            int pid = 0;
+            char dummy;
+            if (sscanf(cp + 4, "%d%c", &pid, &dummy) == 2) {
+                *buf = cp + 10; // skip-it-all
+                return pid;
+            }
+        }
+    }
     while (len) {
         // Mediatek kernels with modified printk
         if (*cp == '[') {
@@ -587,7 +612,7 @@
     }
 
     // Parse pid, tid and uid
-    const pid_t pid = sniffPid(p, len - (p - buf));
+    const pid_t pid = sniffPid(&p, len - (p - buf));
     const pid_t tid = pid;
     const uid_t uid = pid ? logbuf->pidToUid(pid) : 0;
 
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index ee73b71..a4f871e 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -51,7 +51,7 @@
 
 protected:
     void sniffTime(log_time &now, const char **buf, size_t len, bool reverse);
-    pid_t sniffPid(const char *buf, size_t len);
+    pid_t sniffPid(const char **buf, size_t len);
     void calculateCorrection(const log_time &monotonic,
                              const char *real_string, size_t len);
     virtual bool onDataAvailable(SocketClient *cli);
diff --git a/sdcard/fuse.cpp b/sdcard/fuse.cpp
index f371901..54ac919 100644
--- a/sdcard/fuse.cpp
+++ b/sdcard/fuse.cpp
@@ -18,6 +18,8 @@
 
 #include "fuse.h"
 
+#include <android-base/logging.h>
+
 /* FUSE_CANONICAL_PATH is not currently upstreamed */
 #define FUSE_CANONICAL_PATH 2016
 
@@ -579,8 +581,8 @@
     pthread_mutex_lock(&fuse->global->lock);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] LOOKUP %s @ %" PRIx64 " (%s)\n", handler->token, name, hdr->nodeid,
-        parent_node ? parent_node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] LOOKUP " << name << " @ " << hdr->nodeid
+               << " (" << (parent_node ? parent_node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!parent_node || !(actual_name = find_file_within(parent_path, name,
@@ -601,8 +603,9 @@
 
     pthread_mutex_lock(&fuse->global->lock);
     node = lookup_node_by_id_locked(fuse, hdr->nodeid);
-    TRACE("[%d] FORGET #%" PRIu64 " @ %" PRIx64 " (%s)\n", handler->token, req->nlookup,
-            hdr->nodeid, node ? node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] FORGET #" << req->nlookup
+               << " @ " << std::hex << hdr->nodeid
+               << " (" << (node ? node->name : "?") << ")";
     if (node) {
         __u64 n = req->nlookup;
         while (n) {
@@ -622,8 +625,9 @@
 
     pthread_mutex_lock(&fuse->global->lock);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] GETATTR flags=%x fh=%" PRIx64 " @ %" PRIx64 " (%s)\n", handler->token,
-            req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] GETATTR flags=" << req->getattr_flags
+               << " fh=" << std::hex << req->fh << " @ " << std::hex << hdr->nodeid
+               << " (" << (node ? node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!node) {
@@ -645,8 +649,9 @@
 
     pthread_mutex_lock(&fuse->global->lock);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] SETATTR fh=%" PRIx64 " valid=%x @ %" PRIx64 " (%s)\n", handler->token,
-            req->fh, req->valid, hdr->nodeid, node ? node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] SETATTR fh=" << std::hex << req->fh
+               << " valid=" << std::hex << req->valid << " @ " << std::hex << hdr->nodeid
+               << " (" << (node ? node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!node) {
@@ -710,8 +715,9 @@
     pthread_mutex_lock(&fuse->global->lock);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] MKNOD %s 0%o @ %" PRIx64 " (%s)\n", handler->token,
-            name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] MKNOD " << name << " 0" << std::oct << req->mode
+               << " @ " << std::hex << hdr->nodeid
+               << " (" << (parent_node ? parent_node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!parent_node || !(actual_name = find_file_within(parent_path, name,
@@ -739,8 +745,9 @@
     pthread_mutex_lock(&fuse->global->lock);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] MKDIR %s 0%o @ %" PRIx64 " (%s)\n", handler->token,
-            name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] MKDIR " << name << " 0" << std::oct << req->mode
+               << " @ " << std::hex << hdr->nodeid
+               << " (" << (parent_node ? parent_node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!parent_node || !(actual_name = find_file_within(parent_path, name,
@@ -787,8 +794,8 @@
     pthread_mutex_lock(&fuse->global->lock);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] UNLINK %s @ %" PRIx64 " (%s)\n", handler->token,
-            name, hdr->nodeid, parent_node ? parent_node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] UNLINK " << name << " @ " << std::hex << hdr->nodeid
+               << " (" << (parent_node ? parent_node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!parent_node || !find_file_within(parent_path, name,
@@ -809,8 +816,9 @@
     pthread_mutex_unlock(&fuse->global->lock);
     if (parent_node && child_node) {
         /* Tell all other views that node is gone */
-        TRACE("[%d] fuse_notify_delete parent=%" PRIx64 ", child=%" PRIx64 ", name=%s\n",
-                handler->token, (uint64_t) parent_node->nid, (uint64_t) child_node->nid, name);
+        DLOG(INFO) << "[" << handler->token << "] fuse_notify_delete"
+                   << " parent=" << std::hex << parent_node->nid
+                   << ", child=" << std::hex << child_node->nid << ", name=" << name;
         if (fuse != fuse->global->fuse_default) {
             fuse_notify_delete(fuse->global->fuse_default, parent_node->nid, child_node->nid, name);
         }
@@ -835,8 +843,8 @@
     pthread_mutex_lock(&fuse->global->lock);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] RMDIR %s @ %" PRIx64 " (%s)\n", handler->token,
-            name, hdr->nodeid, parent_node ? parent_node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] UNLINK " << name << " @ " << std::hex << hdr->nodeid
+               << " (" << (parent_node ? parent_node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!parent_node || !find_file_within(parent_path, name,
@@ -857,8 +865,9 @@
     pthread_mutex_unlock(&fuse->global->lock);
     if (parent_node && child_node) {
         /* Tell all other views that node is gone */
-        TRACE("[%d] fuse_notify_delete parent=%" PRIx64 ", child=%" PRIx64 ", name=%s\n",
-                handler->token, (uint64_t) parent_node->nid, (uint64_t) child_node->nid, name);
+        DLOG(INFO) << "[" << handler->token << "] fuse_notify_delete"
+                   << " parent=" << std::hex << parent_node->nid
+                   << ", child=" << std::hex << child_node->nid << ", name=" << name;
         if (fuse != fuse->global->fuse_default) {
             fuse_notify_delete(fuse->global->fuse_default, parent_node->nid, child_node->nid, name);
         }
@@ -892,10 +901,11 @@
             old_parent_path, sizeof(old_parent_path));
     new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
             new_parent_path, sizeof(new_parent_path));
-    TRACE("[%d] RENAME %s->%s @ %" PRIx64 " (%s) -> %" PRIx64 " (%s)\n", handler->token,
-            old_name, new_name,
-            hdr->nodeid, old_parent_node ? old_parent_node->name : "?",
-            req->newdir, new_parent_node ? new_parent_node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] RENAME " << old_name << "->" << new_name
+               << " @ " << std::hex << hdr->nodeid
+               << " (" << (old_parent_node ? old_parent_node->name : "?") << ") -> "
+               << std::hex << req->newdir
+               << " (" << (new_parent_node ? new_parent_node->name : "?") << ")";
     if (!old_parent_node || !new_parent_node) {
         res = -ENOENT;
         goto lookup_error;
@@ -976,8 +986,8 @@
 
     pthread_mutex_lock(&fuse->global->lock);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] OPEN 0%o @ %" PRIx64 " (%s)\n", handler->token,
-            req->flags, hdr->nodeid, node ? node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] OPEN 0" << std::oct << req->flags
+               << " @ " << std::hex << hdr->nodeid << " (" << (node ? node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!node) {
@@ -1018,8 +1028,8 @@
      * overlaps the request buffer and will clobber data in the request.  This
      * saves us 128KB per request handler thread at the cost of this scary comment. */
 
-    TRACE("[%d] READ %p(%d) %u@%" PRIu64 "\n", handler->token,
-            h, h->fd, size, (uint64_t) offset);
+    DLOG(INFO) << "[" << handler->token << "] READ " << std::hex << h << "(" << h->fd << ") "
+               << size << "@" << offset;
     if (size > MAX_READ) {
         return -EINVAL;
     }
@@ -1045,8 +1055,8 @@
         buffer = (const __u8*) aligned_buffer;
     }
 
-    TRACE("[%d] WRITE %p(%d) %u@%" PRIu64 "\n", handler->token,
-            h, h->fd, req->size, req->offset);
+    DLOG(INFO) << "[" << handler->token << "] WRITE " << std::hex << h << "(" << h->fd << ") "
+               << req->size << "@" << req->offset;
     res = pwrite64(h->fd, buffer, req->size, req->offset);
     if (res < 0) {
         return -errno;
@@ -1141,8 +1151,8 @@
 
     pthread_mutex_lock(&fuse->global->lock);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] OPENDIR @ %" PRIx64 " (%s)\n", handler->token,
-            hdr->nodeid, node ? node->name : "?");
+    DLOG(INFO) << "[" << handler->token << "] OPENDIR @ " << std::hex << hdr->nodeid
+               << " (" << (node ? node->name : "?") << ")";
     pthread_mutex_unlock(&fuse->global->lock);
 
     if (!node) {
@@ -1401,8 +1411,8 @@
     }
 
     default: {
-        TRACE("[%d] NOTIMPL op=%d uniq=%" PRIx64 " nid=%" PRIx64 "\n",
-                handler->token, hdr->opcode, hdr->unique, hdr->nodeid);
+        DLOG(INFO) << "[" << handler->token << "] NOTIMPL op=" << hdr->opcode
+                   << "uniq=" << std::hex << hdr->unique << "nid=" << std::hex << hdr->nodeid;
         return -ENOSYS;
     }
     }
diff --git a/sdcard/fuse.h b/sdcard/fuse.h
index 634fbf1..9dafa79 100644
--- a/sdcard/fuse.h
+++ b/sdcard/fuse.h
@@ -33,6 +33,7 @@
 #include <map>
 #include <string>
 
+#include <android-base/logging.h>
 #include <cutils/fs.h>
 #include <cutils/log.h>
 #include <cutils/multiuser.h>
@@ -40,15 +41,20 @@
 
 #include <private/android_filesystem_config.h>
 
-// TODO(b/30222003): Fix compilation with FUSE_TRACE == 1.
 #define FUSE_TRACE 0
 
 #if FUSE_TRACE
 #define TRACE(x...) ALOGD(x)
-#else
+static constexpr bool kEnableDLog = true;
+#else  // FUSE_TRACE == 0
 #define TRACE(x...) do {} while (0)
+static constexpr bool kEnableDLog = false;
 #endif
 
+// Use same strategy as DCHECK().
+#define DLOG(x) \
+    if (kEnableDLog) LOG(x)
+
 #define ERROR(x...) ALOGE(x)
 
 /* Maximum number of bytes to write in one request. */