merge in nyc-release history after reset to nyc-dev
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index b9c9e75..5fe1f90 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -625,6 +625,15 @@
     return true;
 }
 
+static void dump_iptables() {
+    run_command("IPTABLES", 10, "iptables", "-L", "-nvx", NULL);
+    run_command("IP6TABLES", 10, "ip6tables", "-L", "-nvx", NULL);
+    run_command("IPTABLE NAT", 10, "iptables", "-t", "nat", "-L", "-nvx", NULL);
+    /* no ip6 nat */
+    run_command("IPTABLE RAW", 10, "iptables", "-t", "raw", "-L", "-nvx", NULL);
+    run_command("IP6TABLE RAW", 10, "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
+}
+
 static void dumpstate(const std::string& screenshot_path, const std::string& version) {
     DurationReporter duration_reporter("DUMPSTATE");
     unsigned long timeout;
@@ -798,16 +807,7 @@
     run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL);
     run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL);
     run_command("MULTICAST ADDRESSES", 10, "ip", "maddr", NULL);
-
-    run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
-    run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
-    run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
-    /* no ip6 nat */
-    run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL);
-    run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
-
-    run_command("WIFI NETWORKS", 20,
-            SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL);
+    run_command("WIFI NETWORKS", 20, "wpa_cli", "IFNAME=wlan0", "list_networks", NULL);
 
 #ifdef FWDUMP_bcmdhd
     run_command("ND OFFLOAD TABLE", 5,
@@ -1281,12 +1281,13 @@
     /* collect stack traces from Dalvik and native processes (needs root) */
     dump_traces_path = dump_traces();
 
-    /* Get the tombstone fds, recovery files, and mount info here while we are running as root. */
+    /* Run some operations that require root. */
     get_tombstone_fds(tombstone_data);
     add_dir(RECOVERY_DIR, true);
     add_dir(RECOVERY_DATA_DIR, true);
     add_dir(LOGPERSIST_DATA_DIR, false);
     add_mountinfo();
+    dump_iptables();
 
     if (!drop_root_user()) {
         return -1;
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 3f60741..094fd16 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -89,7 +89,14 @@
     bool isDynamicSensor() const;
     bool hasAdditionalInfo() const;
     int32_t getReportingMode() const;
+
+    // Note that after setId() has been called, getUuid() no longer
+    // returns the UUID.
+    // TODO(b/29547335): Remove getUuid(), add getUuidIndex(), and
+    //     make sure setId() doesn't change the UuidIndex.
     const uuid_t& getUuid() const;
+    int32_t getId() const;
+    void setId(int32_t id);
 
     // LightFlattenable protocol
     inline bool isFixedSize() const { return false; }
@@ -116,6 +123,9 @@
     int32_t mRequiredAppOp;
     int32_t mMaxDelay;
     uint32_t mFlags;
+    // TODO(b/29547335): Get rid of this field and replace with an index.
+    //     The index will be into a separate global vector of UUIDs.
+    //     Also add an mId field (and change flatten/unflatten appropriately).
     uuid_t  mUuid;
     static void flattenString8(void*& buffer, size_t& size, const String8& string8);
     static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8);
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index cc865d1..053d153 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -408,6 +408,15 @@
     return mUuid;
 }
 
+void Sensor::setId(int32_t id) {
+    mUuid.i64[0] = id;
+    mUuid.i64[1] = 0;
+}
+
+int32_t Sensor::getId() const {
+    return int32_t(mUuid.i64[0]);
+}
+
 size_t Sensor::getFlattenedSize() const {
     size_t fixedSize =
             sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) +
@@ -448,7 +457,18 @@
     FlattenableUtils::write(buffer, size, mRequiredAppOp);
     FlattenableUtils::write(buffer, size, mMaxDelay);
     FlattenableUtils::write(buffer, size, mFlags);
-    FlattenableUtils::write(buffer, size, mUuid);
+    if (mUuid.i64[1] != 0) {
+        // We should never hit this case with our current API, but we
+        // could via a careless API change.  If that happens,
+        // this code will keep us from leaking our UUID (while probably
+        // breaking dynamic sensors).  See b/29547335.
+        ALOGW("Sensor with UUID being flattened; sending 0.  Expect "
+              "bad dynamic sensor behavior");
+        uuid_t tmpUuid;  // default constructor makes this 0.
+        FlattenableUtils::write(buffer, size, tmpUuid);
+    } else {
+        FlattenableUtils::write(buffer, size, mUuid);
+    }
     return NO_ERROR;
 }
 
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index 5a36961..7b10319 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -34,7 +34,8 @@
     liblog \
     libbinder \
     libui \
-    libgui
+    libgui \
+    libcrypto
 
 LOCAL_MODULE:= libsensorservice
 
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 6caa85b..fb83eff 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -26,6 +26,10 @@
 #include <hardware/sensors.h>
 #include <hardware_legacy/power.h>
 
+#include <openssl/digest.h>
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
+
 #include "BatteryService.h"
 #include "CorrectedGyroSensor.h"
 #include "GravitySensor.h"
@@ -44,8 +48,10 @@
 #include <inttypes.h>
 #include <math.h>
 #include <stdint.h>
-#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -60,6 +66,12 @@
  */
 
 const char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock";
+uint8_t SensorService::sHmacGlobalKey[128] = {};
+bool SensorService::sHmacGlobalKeyIsValid = false;
+
+#define SENSOR_SERVICE_DIR "/data/system/sensor_service"
+#define SENSOR_SERVICE_HMAC_KEY_FILE  SENSOR_SERVICE_DIR "/hmac_key"
+
 // Permissions.
 static const String16 sDump("android.permission.DUMP");
 
@@ -68,10 +80,49 @@
       mWakeLockAcquired(false) {
 }
 
+bool SensorService::initializeHmacKey() {
+    int fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_RDONLY|O_CLOEXEC);
+    if (fd != -1) {
+        int result = read(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey));
+        close(fd);
+        if (result == sizeof(sHmacGlobalKey)) {
+            return true;
+        }
+        ALOGW("Unable to read HMAC key; generating new one.");
+    }
+
+    if (RAND_bytes(sHmacGlobalKey, sizeof(sHmacGlobalKey)) == -1) {
+        ALOGW("Can't generate HMAC key; dynamic sensor getId() will be wrong.");
+        return false;
+    }
+
+    // We need to make sure this is only readable to us.
+    bool wroteKey = false;
+    mkdir(SENSOR_SERVICE_DIR, S_IRWXU);
+    fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC,
+              S_IRUSR|S_IWUSR);
+    if (fd != -1) {
+        int result = write(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey));
+        close(fd);
+        wroteKey = (result == sizeof(sHmacGlobalKey));
+    }
+    if (wroteKey) {
+        ALOGI("Generated new HMAC key.");
+    } else {
+        ALOGW("Unable to write HMAC key; dynamic sensor getId() will change "
+              "after reboot.");
+    }
+    // Even if we failed to write the key we return true, because we did
+    // initialize the HMAC key.
+    return true;
+}
+
 void SensorService::onFirstRef() {
     ALOGD("nuSensorService starting...");
     SensorDevice& dev(SensorDevice::getInstance());
 
+    sHmacGlobalKeyIsValid = initializeHmacKey();
+
     if (dev.initCheck() == NO_ERROR) {
         sensor_t const* list;
         ssize_t count = dev.getSensorList(&list);
@@ -719,6 +770,85 @@
     return sensor != nullptr && sensor->getSensor().isWakeUpSensor();
 }
 
+int32_t SensorService::getIdFromUuid(const Sensor::uuid_t &uuid) const {
+    if ((uuid.i64[0] == 0) && (uuid.i64[1] == 0)) {
+        // UUID is not supported for this device.
+        return 0;
+    }
+    if ((uuid.i64[0] == INT64_C(~0)) && (uuid.i64[1] == INT64_C(~0))) {
+        // This sensor can be uniquely identified in the system by
+        // the combination of its type and name.
+        return -1;
+    }
+
+    // We have a dynamic sensor.
+
+    if (!sHmacGlobalKeyIsValid) {
+        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
+        ALOGW("HMAC key failure; dynamic sensor getId() will be wrong.");
+        return 0;
+    }
+
+    // We want each app author/publisher to get a different ID, so that the
+    // same dynamic sensor cannot be tracked across apps by multiple
+    // authors/publishers.  So we use both our UUID and our User ID.
+    // Note potential confusion:
+    //     UUID => Universally Unique Identifier.
+    //     UID  => User Identifier.
+    // We refrain from using "uid" except as needed by API to try to
+    // keep this distinction clear.
+
+    auto appUserId = IPCThreadState::self()->getCallingUid();
+    uint8_t uuidAndApp[sizeof(uuid) + sizeof(appUserId)];
+    memcpy(uuidAndApp, &uuid, sizeof(uuid));
+    memcpy(uuidAndApp + sizeof(uuid), &appUserId, sizeof(appUserId));
+
+    // Now we use our key on our UUID/app combo to get the hash.
+    uint8_t hash[EVP_MAX_MD_SIZE];
+    unsigned int hashLen;
+    if (HMAC(EVP_sha256(),
+             sHmacGlobalKey, sizeof(sHmacGlobalKey),
+             uuidAndApp, sizeof(uuidAndApp),
+             hash, &hashLen) == nullptr) {
+        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
+        ALOGW("HMAC failure; dynamic sensor getId() will be wrong.");
+        return 0;
+    }
+
+    int32_t id = 0;
+    if (hashLen < sizeof(id)) {
+        // We never expect this case, but out of paranoia, we handle it.
+        // Our 'id' length is already quite small, we don't want the
+        // effective length of it to be even smaller.
+        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
+        ALOGW("HMAC insufficient; dynamic sensor getId() will be wrong.");
+        return 0;
+    }
+
+    // This is almost certainly less than all of 'hash', but it's as secure
+    // as we can be with our current 'id' length.
+    memcpy(&id, hash, sizeof(id));
+
+    // Note at the beginning of the function that we return the values of
+    // 0 and -1 to represent special cases.  As a result, we can't return
+    // those as dynamic sensor IDs.  If we happened to hash to one of those
+    // values, we change 'id' so we report as a dynamic sensor, and not as
+    // one of those special cases.
+    if (id == -1) {
+        id = -2;
+    } else if (id == 0) {
+        id = 1;
+    }
+    return id;
+}
+
+void SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const {
+    for (auto &sensor : sensorList) {
+        int32_t id = getIdFromUuid(sensor.getUuid());
+        sensor.setId(id);
+    }
+}
+
 Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
     char value[PROPERTY_VALUE_MAX];
     property_get("debug.sensors", value, "0");
@@ -736,6 +866,7 @@
                   sensor.getRequiredAppOp());
         }
     }
+    makeUuidsIntoIdsForSensorList(accessibleSensorList);
     return accessibleSensorList;
 }
 
@@ -755,6 +886,7 @@
                 }
                 return true;
             });
+    makeUuidsIntoIdsForSensorList(accessibleSensorList);
     return accessibleSensorList;
 }
 
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 0d04478..c8de621 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -208,6 +208,17 @@
     status_t resetToNormalMode();
     status_t resetToNormalModeLocked();
 
+    // Transforms the UUIDs for all the sensors into proper IDs.
+    void makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const;
+    // Gets the appropriate ID from the given UUID.
+    int32_t getIdFromUuid(const Sensor::uuid_t &uuid) const;
+    // Either read from storage or create a new one.
+    static bool initializeHmacKey();
+
+
+    static uint8_t sHmacGlobalKey[128];
+    static bool sHmacGlobalKeyIsValid;
+
     SensorList mSensors;
     status_t mInitCheck;