Merge "adb: relax serial matching rules."
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index 26e376c..3333fc6 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -153,7 +153,9 @@
   // - Recursive, so it uses stack space relative to number of directory
   //   components.
 
-  if (directory_exists(path)) {
+  // If path points to a symlink to a directory, that's fine.
+  struct stat sb;
+  if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) {
     return true;
   }
 
diff --git a/adb/test_device.py b/adb/test_device.py
index 18174a2..2acc444 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -845,6 +845,72 @@
             if host_dir is not None:
                 shutil.rmtree(host_dir)
 
+    def test_pull_dir_symlink(self):
+        """Pull a directory into a symlink to a directory.
+
+        Bug: http://b/27362811
+        """
+        if os.name != "posix":
+            raise unittest.SkipTest('requires POSIX')
+
+        try:
+            host_dir = tempfile.mkdtemp()
+            real_dir = os.path.join(host_dir, "dir")
+            symlink = os.path.join(host_dir, "symlink")
+            os.mkdir(real_dir)
+            os.symlink(real_dir, symlink)
+
+            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
+            self.device.shell(['mkdir', '-p', self.DEVICE_TEMP_DIR])
+
+            # Populate device directory with random files.
+            temp_files = make_random_device_files(
+                self.device, in_dir=self.DEVICE_TEMP_DIR, num_files=32)
+
+            self.device.pull(remote=self.DEVICE_TEMP_DIR, local=symlink)
+
+            for temp_file in temp_files:
+                host_path = os.path.join(
+                    real_dir, posixpath.basename(self.DEVICE_TEMP_DIR),
+                    temp_file.base_name)
+                self._verify_local(temp_file.checksum, host_path)
+
+            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
+        finally:
+            if host_dir is not None:
+                shutil.rmtree(host_dir)
+
+    def test_pull_dir_symlink_collision(self):
+        """Pull a directory into a colliding symlink to directory."""
+        if os.name != "posix":
+            raise unittest.SkipTest('requires POSIX')
+
+        try:
+            host_dir = tempfile.mkdtemp()
+            real_dir = os.path.join(host_dir, "real")
+            tmp_dirname = os.path.basename(self.DEVICE_TEMP_DIR)
+            symlink = os.path.join(host_dir, tmp_dirname)
+            os.mkdir(real_dir)
+            os.symlink(real_dir, symlink)
+
+            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
+            self.device.shell(['mkdir', '-p', self.DEVICE_TEMP_DIR])
+
+            # Populate device directory with random files.
+            temp_files = make_random_device_files(
+                self.device, in_dir=self.DEVICE_TEMP_DIR, num_files=32)
+
+            self.device.pull(remote=self.DEVICE_TEMP_DIR, local=host_dir)
+
+            for temp_file in temp_files:
+                host_path = os.path.join(real_dir, temp_file.base_name)
+                self._verify_local(temp_file.checksum, host_path)
+
+            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
+        finally:
+            if host_dir is not None:
+                shutil.rmtree(host_dir)
+
     def test_pull_symlink_dir(self):
         """Pull a symlink to a directory of symlinks to files."""
         try:
diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp
index f985f52..67e583f 100644
--- a/libbacktrace/UnwindCurrent.cpp
+++ b/libbacktrace/UnwindCurrent.cpp
@@ -23,7 +23,6 @@
 #define UNW_LOCAL_ONLY
 #include <libunwind.h>
 
-#include <android-base/strings.h>
 #include <backtrace/Backtrace.h>
 
 #include "BacktraceLog.h"
@@ -125,16 +124,6 @@
         num_ignore_frames--;
       }
     }
-
-    // For now, do not attempt to do local unwinds through .dex, or .oat
-    // maps. We can only unwind through these if there is a compressed
-    // section available, almost all local unwinds are done by ART
-    // which will dump the Java frames separately.
-    // TODO: Come up with a flag to control this.
-    if (android::base::EndsWith(frame->map.name, ".dex")
-        || android::base::EndsWith(frame->map.name, ".oat")) {
-      break;
-    }
     ret = unw_step (cursor.get());
   } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES);
 
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index a4b96d3..2a04880 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -90,7 +90,7 @@
         while(it != times.end()) {
             if (*it == me) {
                 times.erase(it);
-                me->release_Locked();
+                me->release_nodelete_Locked();
                 break;
             }
             it++;
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index f5969df..b66ff9e 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -75,7 +75,13 @@
     void triggerSkip_Locked(log_id_t id, unsigned int skip) { skipAhead[id] = skip; }
     void cleanSkip_Locked(void);
 
-    // Called after LogTimeEntry removed from list, lock implicitly held
+    // These called after LogTimeEntry removed from list, lock implicitly held
+    void release_nodelete_Locked(void) {
+        mRelease = true;
+        pthread_cond_signal(&threadTriggeredCondition);
+        // assumes caller code path will call decRef_Locked()
+    }
+
     void release_Locked(void) {
         mRelease = true;
         pthread_cond_signal(&threadTriggeredCondition);
diff --git a/logd/main.cpp b/logd/main.cpp
index f4d7464..3095f7f 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -165,7 +165,7 @@
         char newkey[PROPERTY_KEY_MAX];
         snprintf(newkey, sizeof(newkey), "ro.%s", key);
         property_get(newkey, property, "");
-        // persist properties set by /data require innoculation with
+        // persist properties set by /data require inoculation with
         // logd-reinit. They may be set in init.rc early and function, but
         // otherwise are defunct unless reset. Do not rely on persist
         // properties for startup-only keys unless you are willing to restart
@@ -265,8 +265,11 @@
     set_sched_policy(0, SP_BACKGROUND);
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND);
 
-    setgid(AID_SYSTEM);
-    setuid(AID_SYSTEM);
+    // If we are AID_ROOT, we should drop to AID_SYSTEM, if we are anything
+    // else, we have even lesser privileges and accept our fate. Not worth
+    // checking for error returns setting this thread's privileges.
+    (void)setgid(AID_SYSTEM);
+    (void)setuid(AID_SYSTEM);
 
     while (reinit_running && !sem_wait(&reinit) && reinit_running) {