Merge "Revert "Add new AHardwareBuffer formats and usages with latest HAL change.""
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 93f8d43..2eb11cb 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -657,12 +657,18 @@
     return 0;
 }
 
-/* timeout in ms */
-static unsigned long logcat_timeout(const char *name) {
-    log_id_t id = android_name_to_log_id(name);
-    unsigned long property_size = __android_logger_get_buffer_size(id);
-    /* Engineering margin is ten-fold our guess */
-    return 10 * (property_size + worst_write_perf) / worst_write_perf;
+static const long MINIMUM_LOGCAT_TIMEOUT_MS = 50000;
+
+/* timeout in ms to read a list of buffers */
+static unsigned long logcat_timeout(const std::vector<std::string>& buffers) {
+    unsigned long timeout_ms = 0;
+    for (const auto& buffer : buffers) {
+        log_id_t id = android_name_to_log_id(buffer.c_str());
+        unsigned long property_size = __android_logger_get_buffer_size(id);
+        /* Engineering margin is ten-fold our guess */
+        timeout_ms += 10 * (property_size + worst_write_perf) / worst_write_perf;
+    }
+    return timeout_ms > MINIMUM_LOGCAT_TIMEOUT_MS ? timeout_ms : MINIMUM_LOGCAT_TIMEOUT_MS;
 }
 
 void Dumpstate::PrintHeader() const {
@@ -831,13 +837,8 @@
     }
 }
 
-static const long MINIMUM_LOGCAT_TIMEOUT_MS = 50000;
-
 static void DoKernelLogcat() {
-    unsigned long timeout_ms = logcat_timeout("kernel");
-    if (timeout_ms < MINIMUM_LOGCAT_TIMEOUT_MS) {
-        timeout_ms = MINIMUM_LOGCAT_TIMEOUT_MS;
-    }
+    unsigned long timeout_ms = logcat_timeout({"kernel"});
     RunCommand(
         "KERNEL LOG",
         {"logcat", "-b", "kernel", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
@@ -848,25 +849,21 @@
     unsigned long timeout_ms;
     // DumpFile("EVENT LOG TAGS", "/etc/event-log-tags");
     // calculate timeout
-    timeout_ms = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash");
-    if (timeout_ms < MINIMUM_LOGCAT_TIMEOUT_MS) {
-        timeout_ms = MINIMUM_LOGCAT_TIMEOUT_MS;
-    }
+    timeout_ms = logcat_timeout({"main", "system", "crash"});
     RunCommand("SYSTEM LOG",
                {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
                CommandOptions::WithTimeoutInMs(timeout_ms).Build());
-    timeout_ms = logcat_timeout("events");
-    if (timeout_ms < MINIMUM_LOGCAT_TIMEOUT_MS) {
-        timeout_ms = MINIMUM_LOGCAT_TIMEOUT_MS;
-    }
+    timeout_ms = logcat_timeout({"events"});
     RunCommand(
         "EVENT LOG",
         {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
         CommandOptions::WithTimeoutInMs(timeout_ms).Build());
-    timeout_ms = logcat_timeout("radio");
-    if (timeout_ms < MINIMUM_LOGCAT_TIMEOUT_MS) {
-        timeout_ms = MINIMUM_LOGCAT_TIMEOUT_MS;
-    }
+    timeout_ms = logcat_timeout({"stats"});
+    RunCommand(
+        "STATS LOG",
+        {"logcat", "-b", "stats", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
+        CommandOptions::WithTimeoutInMs(timeout_ms).Build());
+    timeout_ms = logcat_timeout({"radio"});
     RunCommand(
         "RADIO LOG",
         {"logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
@@ -1136,7 +1133,7 @@
                 }
                 RunCommandToFd(fd,
                         "",
-                        {"lshal", "debug", interface},
+                        {"lshal", "debug", "-E", interface},
                         CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
 
                 bool empty = 0 == lseek(fd, 0, SEEK_END);
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 80e18d3..0f635e0 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -217,7 +217,7 @@
         const char* input_file_name, const char* output_file_name, int swap_fd,
         const char* instruction_set, const char* compiler_filter,
         bool debuggable, bool post_bootcomplete, bool background_job_compile, int profile_fd,
-        const char* class_loader_context, int target_sdk_version) {
+        const char* class_loader_context, int target_sdk_version, bool disable_hidden_api_checks) {
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
 
     if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
@@ -443,7 +443,8 @@
                      + (have_dex2oat_large_app_threshold ? 1 : 0)
                      + (disable_cdex ? 1 : 0)
                      + (generate_minidebug_info ? 1 : 0)
-                     + (target_sdk_version != 0 ? 2 : 0)];
+                     + (target_sdk_version != 0 ? 2 : 0)
+                     + (disable_hidden_api_checks ? 2 : 0)];
     int i = 0;
     argv[i++] = dex2oat_bin;
     argv[i++] = zip_fd_arg;
@@ -517,6 +518,10 @@
         argv[i++] = RUNTIME_ARG;
         argv[i++] = target_sdk_version_arg;
     }
+    if (disable_hidden_api_checks) {
+        argv[i++] = RUNTIME_ARG;
+        argv[i++] = "-Xno-hidden-api-checks";
+    }
 
     // Do not add after dex2oat_flags, they should override others for debugging.
     argv[i] = NULL;
@@ -1801,6 +1806,7 @@
     bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
     bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0;
     bool background_job_compile = (dexopt_flags & DEXOPT_IDLE_BACKGROUND_JOB) != 0;
+    bool disable_hidden_api_checks = (dexopt_flags & DEXOPT_DISABLE_HIDDEN_API_CHECKS) != 0;
 
     // Check if we're dealing with a secondary dex file and if we need to compile it.
     std::string oat_dir_str;
@@ -1897,7 +1903,8 @@
                     background_job_compile,
                     reference_profile_fd.get(),
                     class_loader_context,
-                    target_sdk_version);
+                    target_sdk_version,
+                    disable_hidden_api_checks);
         _exit(68);   /* only get here on exec failure */
     } else {
         int res = wait_child(pid);
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index b49057d..9b6714d 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -52,6 +52,7 @@
 // Tells the compiler that it is invoked from the background service.  This
 // controls whether extra debugging flags can be used (taking more compile time.)
 constexpr int DEXOPT_IDLE_BACKGROUND_JOB = 1 << 9;
+constexpr int DEXOPT_DISABLE_HIDDEN_API_CHECKS = 1 << 10;
 
 /* all known values for dexopt flags */
 constexpr int DEXOPT_MASK =
@@ -62,7 +63,8 @@
     | DEXOPT_SECONDARY_DEX
     | DEXOPT_FORCE
     | DEXOPT_STORAGE_CE
-    | DEXOPT_STORAGE_DE;
+    | DEXOPT_STORAGE_DE
+    | DEXOPT_DISABLE_HIDDEN_API_CHECKS;
 
 // NOTE: keep in sync with StorageManager
 constexpr int FLAG_STORAGE_DE = 1 << 0;
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 0e36c33..dbd7051 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -78,8 +78,10 @@
 static_assert(DEXOPT_FORCE          == 1 << 6, "DEXOPT_FORCE unexpected.");
 static_assert(DEXOPT_STORAGE_CE     == 1 << 7, "DEXOPT_STORAGE_CE unexpected.");
 static_assert(DEXOPT_STORAGE_DE     == 1 << 8, "DEXOPT_STORAGE_DE unexpected.");
+static_assert(DEXOPT_DISABLE_HIDDEN_API_CHECKS == 1 << 10,
+        "DEXOPT_DISABLE_HIDDEN_API_CHECKS unexpected");
 
-static_assert(DEXOPT_MASK           == 0x1fe, "DEXOPT_MASK unexpected.");
+static_assert(DEXOPT_MASK           == 0x5fe, "DEXOPT_MASK unexpected.");
 
 
 
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 2030997..c402c3c 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -59,6 +59,12 @@
 // The file descriptor denoted by status-fd will be closed. The rest of the parameters will
 // be passed on to otapreopt in the chroot.
 static int otapreopt_chroot(const int argc, char **arg) {
+    // Validate arguments
+    // We need the command, status channel and target slot, at a minimum.
+    if(argc < 3) {
+        PLOG(ERROR) << "Not enough arguments.";
+        exit(208);
+    }
     // Close all file descriptors. They are coming from the caller, we do not want to pass them
     // on across our fork/exec into a different domain.
     // 1) Default descriptors.
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index f371320..dd8812d 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -35,6 +35,14 @@
     if (optind >= arg.argc) {
         return USAGE;
     }
+
+    // Optargs cannnot be used because the flag should not be considered set
+    // if it should really be contained in mOptions.
+    if (std::string(arg.argv[optind]) == "-E") {
+        mExcludesParentInstances = true;
+        optind++;
+    }
+
     mInterfaceName = arg.argv[optind];
     ++optind;
     for (; optind < arg.argc; ++optind) {
@@ -59,6 +67,7 @@
 
     return mLshal.emitDebugInfo(
             pair.first, pair.second.empty() ? "default" : pair.second, mOptions,
+            mExcludesParentInstances,
             mLshal.out().buf(),
             mLshal.err());
 }
@@ -67,8 +76,9 @@
 
     static const std::string debug =
             "debug:\n"
-            "    lshal debug <interface> [options [options [...]]] \n"
+            "    lshal debug [-E] <interface> [options [options [...]]] \n"
             "        Print debug information of a specified interface.\n"
+            "        -E: excludes debug output if HAL is actually a subclass.\n"
             "        <inteface>: Format is `android.hardware.foo@1.0::IFoo/default`.\n"
             "            If instance name is missing `default` is used.\n"
             "        options: space separated options to IBase::debug.\n";
diff --git a/cmds/lshal/DebugCommand.h b/cmds/lshal/DebugCommand.h
index 9b91084..6e12008 100644
--- a/cmds/lshal/DebugCommand.h
+++ b/cmds/lshal/DebugCommand.h
@@ -43,6 +43,10 @@
     std::string mInterfaceName;
     std::vector<std::string> mOptions;
 
+    // Outputs the actual descriptor of a hal instead of the debug output
+    // if the arguments provided are a superclass of the actual hal impl.
+    bool mExcludesParentInstances;
+
     DISALLOW_COPY_AND_ASSIGN(DebugCommand);
 };
 
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index 7399692..e4b3c90 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -397,7 +397,8 @@
             emitDebugInfo = [this](const auto& iName) {
                 std::stringstream ss;
                 auto pair = splitFirst(iName, '/');
-                mLshal.emitDebugInfo(pair.first, pair.second, {}, ss,
+                mLshal.emitDebugInfo(pair.first, pair.second, {},
+                                     false /* excludesParentInstances */, ss,
                                      NullableOStream<std::ostream>(nullptr));
                 return ss.str();
             };
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index c6f28ac..8c83457 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -23,6 +23,7 @@
 #include <string>
 
 #include <hidl/ServiceManagement.h>
+#include <hidl/HidlTransportUtils.h>
 
 #include "DebugCommand.h"
 #include "ListCommand.h"
@@ -97,9 +98,11 @@
         const std::string &interfaceName,
         const std::string &instanceName,
         const std::vector<std::string> &options,
+        bool excludesParentInstances,
         std::ostream &out,
         NullableOStream<std::ostream> err) const {
     using android::hidl::base::V1_0::IBase;
+    using android::hardware::details::getDescriptor;
 
     hardware::Return<sp<IBase>> retBase = serviceManager()->get(interfaceName, instanceName);
 
@@ -120,6 +123,18 @@
         return NO_INTERFACE;
     }
 
+    if (excludesParentInstances) {
+        const std::string descriptor = getDescriptor(base.get());
+        if (descriptor.empty()) {
+            std::string msg = interfaceName + "/" + instanceName + " getDescriptor failed";
+            err << msg << std::endl;
+            LOG(ERROR) << msg;
+        }
+        if (descriptor != interfaceName) {
+            return OK;
+        }
+    }
+
     PipeRelay relay(out);
 
     if (relay.initCheck() != OK) {
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index 690f30e..9457f1e 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -51,6 +51,7 @@
             const std::string &interfaceName,
             const std::string &instanceName,
             const std::vector<std::string> &options,
+            bool excludesParentInstances,
             std::ostream &out,
             NullableOStream<std::ostream> err) const;
 
diff --git a/headers/media_plugin/media/arcvideobridge/IArcVideoBridge.h b/headers/media_plugin/media/arcvideobridge/IArcVideoBridge.h
new file mode 100644
index 0000000..b32c92e
--- /dev/null
+++ b/headers/media_plugin/media/arcvideobridge/IArcVideoBridge.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IARC_VIDEO_BRIDGE_H
+#define ANDROID_IARC_VIDEO_BRIDGE_H
+
+#include <arc/IArcBridgeService.h>
+#include <binder/IInterface.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+class IArcVideoBridge : public IInterface {
+public:
+    DECLARE_META_INTERFACE(ArcVideoBridge);
+
+    // Returns MojoBootstrapResult for creating mojo ipc channel of
+    // VideoAcceleratorFactory.
+    virtual ::arc::MojoBootstrapResult bootstrapVideoAcceleratorFactory() = 0;
+
+    // Get the version of the remote VideoHost on Chromium side.
+    virtual int32_t hostVersion() = 0;
+};
+
+class BnArcVideoBridge : public BnInterface<IArcVideoBridge> {
+public:
+    virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
+};
+
+};  // namespace android
+
+#endif // ANDROID_IARC_VIDEO_BRIDGE_H
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index ce7804b..067dc5c 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -110,6 +110,11 @@
 
         /*
         DISABLE_RINGTONE_SYNC                 = IBinder::FIRST_CALL_TRANSACTION + 71,
+        GET_FOCUS_RAMP_TIME_MS                = IBinder::FIRST_CALL_TRANSACTION + 72,
+        DISPATCH_FOCUS_CHANGE                 = IBinder::FIRST_CALL_TRANSACTION + 73,
+        PLAYER_HAS_OP_PLAY_AUDIO              = IBinder::FIRST_CALL_TRANSACTION + 74,
+        SET_BLUETOOTH_A2DP_DEVICE_CONNECTION_STATE_SUPPRESS_NOISY_INTENT
+                                              = IBinder::FIRST_CALL_TRANSACTION + 75,
         */
     };
 
diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp
index 2904718..7724bf1 100644
--- a/libs/binder/ActivityManager.cpp
+++ b/libs/binder/ActivityManager.cpp
@@ -39,7 +39,7 @@
             if (startTime == 0) {
                 startTime = uptimeMillis();
                 ALOGI("Waiting for activity service");
-            } else if ((uptimeMillis() - startTime) > 10000) {
+            } else if ((uptimeMillis() - startTime) > 1000000) {
                 ALOGW("Waiting too long for activity service, giving up");
                 service = NULL;
                 break;
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 239c04d..6103188 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -63,6 +63,7 @@
         "MemoryHeapBase.cpp",
         "Parcel.cpp",
         "PermissionCache.cpp",
+        "PermissionController.cpp",
         "PersistableBundle.cpp",
         "ProcessInfoService.cpp",
         "ProcessState.cpp",
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
index 674bddf..ef67ab8 100644
--- a/libs/binder/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -78,6 +78,18 @@
         if (reply.readExceptionCode() != 0) return false;
         return reply.readInt32() != 0;
     }
+
+    virtual int getPackageUid(const String16& package, int flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
+        data.writeString16(package);
+        data.writeInt32(flags);
+        remote()->transact(GET_PACKAGE_UID_TRANSACTION, data, &reply);
+        // fail on exception
+        if (reply.readExceptionCode() != 0) return false;
+        return reply.readInt32();
+    }
 };
 
 IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
@@ -122,6 +134,16 @@
             return NO_ERROR;
         } break;
 
+        case GET_PACKAGE_UID_TRANSACTION: {
+            CHECK_INTERFACE(IPermissionController, data, reply);
+            String16 package = data.readString16();
+            int flags = data.readInt32();
+            const int uid = getPackageUid(package, flags);
+            reply->writeNoException();
+            reply->writeInt32(uid);
+            return NO_ERROR;
+        } break;
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/binder/PermissionController.cpp b/libs/binder/PermissionController.cpp
new file mode 100644
index 0000000..25748ca
--- /dev/null
+++ b/libs/binder/PermissionController.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mutex>
+#include <binder/PermissionController.h>
+#include <binder/Binder.h>
+#include <binder/IServiceManager.h>
+
+#include <utils/SystemClock.h>
+
+namespace android {
+
+PermissionController::PermissionController()
+{
+}
+
+sp<IPermissionController> PermissionController::getService()
+{
+    std::lock_guard<Mutex> scoped_lock(mLock);
+    int64_t startTime = 0;
+    sp<IPermissionController> service = mService;
+    while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
+        sp<IBinder> binder = defaultServiceManager()->checkService(String16("permission"));
+        if (binder == nullptr) {
+            // Wait for the activity service to come back...
+            if (startTime == 0) {
+                startTime = uptimeMillis();
+                ALOGI("Waiting for permission service");
+            } else if ((uptimeMillis() - startTime) > 10000) {
+                ALOGW("Waiting too long for permission service, giving up");
+                service = NULL;
+                break;
+            }
+            sleep(1);
+        } else {
+            service = interface_cast<IPermissionController>(binder);
+            mService = service;
+        }
+    }
+    return service;
+}
+
+bool PermissionController::checkPermission(const String16& permission, int32_t pid, int32_t uid)
+{
+    sp<IPermissionController> service = getService();
+    return service != NULL ? service->checkPermission(permission, pid, uid) : false;
+}
+
+void PermissionController::getPackagesForUid(const uid_t uid, Vector<String16> &packages)
+{
+    sp<IPermissionController> service = getService();
+    if (service != nullptr) {
+        service->getPackagesForUid(uid, packages);
+    }
+}
+
+bool PermissionController::isRuntimePermission(const String16& permission)
+{
+    sp<IPermissionController> service = getService();
+    return service != nullptr ? service->isRuntimePermission(permission) : false;
+}
+
+int PermissionController::getPackageUid(const String16& package, int flags)
+{
+    sp<IPermissionController> service = getService();
+    return service != nullptr ? service->getPackageUid(package, flags) : -1;
+}
+
+}; // namespace android
diff --git a/libs/binder/include/binder/IPermissionController.h b/libs/binder/include/binder/IPermissionController.h
index 25f3431..2f63677 100644
--- a/libs/binder/include/binder/IPermissionController.h
+++ b/libs/binder/include/binder/IPermissionController.h
@@ -36,10 +36,13 @@
 
     virtual bool isRuntimePermission(const String16& permission) = 0;
 
+    virtual int getPackageUid(const String16& package, int flags) = 0;
+
     enum {
         CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
         GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1,
-        IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2
+        IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2,
+        GET_PACKAGE_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 3
     };
 };
 
diff --git a/libs/binder/include/binder/PermissionController.h b/libs/binder/include/binder/PermissionController.h
new file mode 100644
index 0000000..c4c98d0
--- /dev/null
+++ b/libs/binder/include/binder/PermissionController.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PERMISSION_CONTROLLER_H
+#define ANDROID_PERMISSION_CONTROLLER_H
+
+#include <binder/IPermissionController.h>
+
+#include <utils/threads.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class PermissionController
+{
+public:
+
+    enum {
+        MATCH_SYSTEM_ONLY = 1<<16,
+        MATCH_UNINSTALLED_PACKAGES = 1<<13,
+        MATCH_FACTORY_ONLY = 1<<21,
+        MATCH_INSTANT = 1<<23
+    };
+
+    PermissionController();
+
+    bool checkPermission(const String16& permission, int32_t pid, int32_t uid);
+    void getPackagesForUid(const uid_t uid, Vector<String16>& packages);
+    bool isRuntimePermission(const String16& permission);
+    int getPackageUid(const String16& package, int flags);
+
+private:
+    Mutex mLock;
+    sp<IPermissionController> mService;
+
+    sp<IPermissionController> getService();
+};
+
+
+}; // namespace android
+// ---------------------------------------------------------------------------
+#endif // ANDROID_PERMISSION_CONTROLLER_H
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index cd29d4a..8060b6e 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -22,6 +22,7 @@
 #include <binder/ProcessState.h>
 #include <configstore/Utils.h>
 #include <cutils/properties.h>
+#include <inttypes.h>
 #include <gui/BufferItemConsumer.h>
 #include <gui/IDisplayEventConnection.h>
 #include <gui/IProducerListener.h>
@@ -869,7 +870,7 @@
                 (iOldFrame == NO_FRAME_INDEX) ? nullptr : &mFrames[iOldFrame];
         FrameEvents* newFrame = &mFrames[iNewFrame];
 
-        uint64_t nOldFrame = iOldFrame + 1;
+        uint64_t nOldFrame = (iOldFrame == NO_FRAME_INDEX) ? 0 : iOldFrame + 1;
         uint64_t nNewFrame = iNewFrame + 1;
 
         // Latch, Composite, and Release the frames in a plausible order.
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index 57eee12..e54f147 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -107,7 +107,7 @@
 // this is the strategy that applications will actually use.  Be very careful
 // when adjusting the default strategy because it can dramatically affect
 // (often in a bad way) the user experience.
-const char* VelocityTracker::DEFAULT_STRATEGY = "impulse";
+const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
 
 VelocityTracker::VelocityTracker(const char* strategy) :
         mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp
index efbbf7d..5200545 100644
--- a/libs/sensor/ISensorServer.cpp
+++ b/libs/sensor/ISensorServer.cpp
@@ -27,6 +27,7 @@
 
 #include <binder/Parcel.h>
 #include <binder/IInterface.h>
+#include <binder/IResultReceiver.h>
 
 #include <sensor/Sensor.h>
 #include <sensor/ISensorEventConnection.h>
@@ -227,6 +228,30 @@
             reply->writeInt32(ret);
             return NO_ERROR;
         }
+        case SHELL_COMMAND_TRANSACTION: {
+            int in = data.readFileDescriptor();
+            int out = data.readFileDescriptor();
+            int err = data.readFileDescriptor();
+            int argc = data.readInt32();
+            Vector<String16> args;
+            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
+               args.add(data.readString16());
+            }
+            sp<IBinder> unusedCallback;
+            sp<IResultReceiver> resultReceiver;
+            status_t status;
+            if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
+                return status;
+            }
+            if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
+                return status;
+            }
+            status = shellCommand(in, out, err, args);
+            if (resultReceiver != nullptr) {
+                resultReceiver->send(status);
+            }
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
diff --git a/libs/sensor/include/sensor/ISensorServer.h b/libs/sensor/include/sensor/ISensorServer.h
index edf3e0f..402678f 100644
--- a/libs/sensor/include/sensor/ISensorServer.h
+++ b/libs/sensor/include/sensor/ISensorServer.h
@@ -60,6 +60,9 @@
 class BnSensorServer : public BnInterface<ISensorServer>
 {
 public:
+    virtual status_t shellCommand(int in, int out, int err,
+                                  Vector<String16>& args) = 0;
+
     virtual status_t    onTransact( uint32_t code,
                                     const Parcel& data,
                                     Parcel* reply,
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 5d796dc..4f5d548 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -457,13 +457,6 @@
     layer.Prepare();
   }
 
-  HWC::Error error = Validate(composer_callback_->GetDisplayId());
-  if (error != HWC::Error::None) {
-    ALOGE("HardwareComposer::PostLayers: Validate failed: %s",
-          error.to_string().c_str());
-    return;
-  }
-
   // Now that we have taken in a frame from the application, we have a chance
   // to drop the frame before passing the frame along to HWC.
   // If the display driver has become backed up, we detect it here and then
@@ -504,6 +497,13 @@
   }
 #endif
 
+  HWC::Error error = Validate(composer_callback_->GetDisplayId());
+  if (error != HWC::Error::None) {
+    ALOGE("HardwareComposer::PostLayers: Validate failed: %s",
+          error.to_string().c_str());
+    return;
+  }
+
   error = Present(composer_callback_->GetDisplayId());
   if (error != HWC::Error::None) {
     ALOGE("HardwareComposer::PostLayers: Present failed: %s",
@@ -862,17 +862,13 @@
       ATRACE_INT64("sleep_time_ns", sleep_time_ns);
       if (sleep_time_ns > 0) {
         int error = SleepUntil(wakeup_time_ns);
-        ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
+        ALOGE_IF(error < 0 && error != kPostThreadInterrupted,
+                 "HardwareComposer::PostThread: Failed to sleep: %s",
                  strerror(-error));
-        if (error == kPostThreadInterrupted) {
-          if (layer_config_changed) {
-            // If the layer config changed we need to validateDisplay() even if
-            // we're going to drop the frame, to flush the Composer object's
-            // internal command buffer and apply our layer changes.
-            Validate(composer_callback_->GetDisplayId());
-          }
-          continue;
-        }
+        // If the sleep was interrupted (error == kPostThreadInterrupted),
+        // we still go through and present this frame because we may have set
+        // layers earlier and we want to flush the Composer's internal command
+        // buffer by continuing through to validate and present.
       }
     }
 
diff --git a/services/media/arcvideobridge/Android.bp b/services/media/arcvideobridge/Android.bp
new file mode 100644
index 0000000..ed0f613
--- /dev/null
+++ b/services/media/arcvideobridge/Android.bp
@@ -0,0 +1,29 @@
+cc_library_shared {
+    name: "libarcvideobridge",
+    product_variables: {
+        arc: {
+            srcs: [
+                "IArcVideoBridge.cpp",
+            ],
+            // TODO: remove the suffix "_bp" after finishing migration to Android.bp.
+            shared_libs: [
+                "libarcbridge",
+                "libarcbridgeservice",
+                "libbinder",
+                "libchrome",
+                "liblog",
+                "libmojo_bp",
+                "libutils",
+            ],
+            cflags: [
+                "-Wall",
+                "-Werror",
+                "-Wunused",
+                "-Wunreachable-code",
+            ],
+            include_dirs: [
+                "frameworks/native/include/media/arcvideobridge",
+            ]
+        }
+    }
+}
diff --git a/services/media/arcvideobridge/IArcVideoBridge.cpp b/services/media/arcvideobridge/IArcVideoBridge.cpp
new file mode 100644
index 0000000..468b76b
--- /dev/null
+++ b/services/media/arcvideobridge/IArcVideoBridge.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "IArcVideoBridge"
+//#define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "IArcVideoBridge.h"
+#include <binder/Parcel.h>
+#include <utils/Log.h>
+
+namespace android {
+
+enum {
+    BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY = IBinder::FIRST_CALL_TRANSACTION,
+    HOST_VERSION,
+};
+
+class BpArcVideoBridge : public BpInterface<IArcVideoBridge> {
+public:
+    BpArcVideoBridge(const sp<IBinder>& impl) : BpInterface<IArcVideoBridge>(impl) { }
+
+    virtual ::arc::MojoBootstrapResult bootstrapVideoAcceleratorFactory() {
+        Parcel data, reply;
+        ALOGV("bootstrapVideoAcceleratorFactory");
+        data.writeInterfaceToken(IArcVideoBridge::getInterfaceDescriptor());
+        status_t status = remote()->transact(
+                BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY, data, &reply, 0);
+        if (status != 0) {
+            ALOGE("transact failed: %d", status);
+            return arc::MojoBootstrapResult();
+        }
+        return arc::MojoBootstrapResult::createFromParcel(reply);
+    }
+
+    virtual int32_t hostVersion() {
+        Parcel data, reply;
+        ALOGV("hostVersion");
+        data.writeInterfaceToken(IArcVideoBridge::getInterfaceDescriptor());
+        status_t status = remote()->transact(HOST_VERSION, data, &reply, 0);
+        if (status != 0) {
+            ALOGE("transact failed: %d", status);
+            return false;
+        }
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(ArcVideoBridge, "android.os.IArcVideoBridge");
+
+status_t BnArcVideoBridge::onTransact(
+        uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+    switch(code) {
+        case BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY: {
+            ALOGV("BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY");
+            CHECK_INTERFACE(IArcVideoBridge, data, reply);
+            arc::MojoBootstrapResult result = bootstrapVideoAcceleratorFactory();
+            return result.writeToParcel(reply);
+        }
+        case HOST_VERSION: {
+            ALOGV("HOST_VERSION");
+            CHECK_INTERFACE(IArcVideoBridge, data, reply);
+            reply->writeInt32(hostVersion());
+            return OK;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}  // namespace android
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 0a05dd1..956844f 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -29,11 +29,11 @@
 
 SensorService::SensorEventConnection::SensorEventConnection(
         const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
-        const String16& opPackageName)
+        const String16& opPackageName, bool hasSensorAccess)
     : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
       mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
       mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName),
-      mDestroyed(false) {
+      mDestroyed(false), mHasSensorAccess(hasSensorAccess) {
     mChannel = new BitTube(mService->mSocketBufferSize);
 #if DEBUG_CONNECTIONS
     mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -223,6 +223,9 @@
         sensors_event_t* scratch,
         wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
     // filter out events not for this connection
+
+    sensors_event_t* sanitizedBuffer = nullptr;
+
     int count = 0;
     Mutex::Autolock _l(mConnectionLock);
     if (scratch) {
@@ -273,24 +276,36 @@
                     if (mapFlushEventsToConnections[i] == this) {
                         scratch[count++] = buffer[i];
                     }
-                    ++i;
                 } else {
                     // Regular sensor event, just copy it to the scratch buffer.
-                    scratch[count++] = buffer[i++];
+                    if (mHasSensorAccess) {
+                        scratch[count++] = buffer[i];
+                    }
                 }
+                i++;
             } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
                                         buffer[i].type != SENSOR_TYPE_META_DATA) ||
                                        (buffer[i].type == SENSOR_TYPE_META_DATA  &&
                                         buffer[i].meta_data.sensor == sensor_handle)));
         }
     } else {
-        scratch = const_cast<sensors_event_t *>(buffer);
-        count = numEvents;
+        if (mHasSensorAccess) {
+            scratch = const_cast<sensors_event_t *>(buffer);
+            count = numEvents;
+        } else {
+            scratch = sanitizedBuffer = new sensors_event_t[numEvents];
+            for (size_t i = 0; i < numEvents; i++) {
+                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+                    scratch[count++] = buffer[i++];
+                }
+            }
+        }
     }
 
     sendPendingFlushEventsLocked();
     // Early return if there are no events for this connection.
     if (count == 0) {
+        delete sanitizedBuffer;
         return status_t(NO_ERROR);
     }
 
@@ -308,6 +323,7 @@
             // the max cache size that is desired.
             if (mCacheSize + count < computeMaxCacheSizeLocked()) {
                 reAllocateCacheLocked(scratch, count);
+                delete sanitizedBuffer;
                 return status_t(NO_ERROR);
             }
             // Some events need to be dropped.
@@ -326,16 +342,20 @@
             memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
                                             numEventsDropped * sizeof(sensors_event_t));
         }
+        delete sanitizedBuffer;
         return status_t(NO_ERROR);
     }
 
-    int index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
-    if (index_wake_up_event >= 0) {
-        scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
-        ++mWakeLockRefCount;
+    int index_wake_up_event = -1;
+    if (mHasSensorAccess) {
+        index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
+        if (index_wake_up_event >= 0) {
+            scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
+            ++mWakeLockRefCount;
 #if DEBUG_CONNECTIONS
-        ++mTotalAcksNeeded;
+            ++mTotalAcksNeeded;
 #endif
+        }
     }
 
     // NOTE: ASensorEvent and sensors_event_t are the same type.
@@ -364,6 +384,7 @@
         // Add this file descriptor to the looper to get a callback when this fd is available for
         // writing.
         updateLooperRegistrationLocked(mService->getLooper());
+        delete sanitizedBuffer;
         return size;
     }
 
@@ -373,9 +394,15 @@
     }
 #endif
 
+    delete sanitizedBuffer;
     return size < 0 ? status_t(size) : status_t(NO_ERROR);
 }
 
+void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
+    Mutex::Autolock _l(mConnectionLock);
+    mHasSensorAccess = hasAccess;
+}
+
 void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
                                                                  int count) {
     sensors_event_t *eventCache_new;
@@ -437,15 +464,18 @@
     sendPendingFlushEventsLocked();
     for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
         const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
-        int index_wake_up_event =
-                  findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
-        if (index_wake_up_event >= 0) {
-            mEventCache[index_wake_up_event + numEventsSent].flags |=
-                    WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
-            ++mWakeLockRefCount;
+        int index_wake_up_event = -1;
+        if (mHasSensorAccess) {
+            index_wake_up_event =
+                      findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
+            if (index_wake_up_event >= 0) {
+                mEventCache[index_wake_up_event + numEventsSent].flags |=
+                        WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
+                ++mWakeLockRefCount;
 #if DEBUG_CONNECTIONS
-            ++mTotalAcksNeeded;
+                ++mTotalAcksNeeded;
 #endif
+            }
         }
 
         ssize_t size = SensorEventQueue::write(mChannel,
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 6f282cd..032721e 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -49,7 +49,8 @@
 
 public:
     SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName,
-                          bool isDataInjectionMode, const String16& opPackageName);
+                          bool isDataInjectionMode, const String16& opPackageName,
+                          bool hasSensorAccess);
 
     status_t sendEvents(sensors_event_t const* buffer, size_t count, sensors_event_t* scratch,
                         wp<const SensorEventConnection> const * mapFlushEventsToConnections = NULL);
@@ -66,6 +67,8 @@
 
     uid_t getUid() const { return mUid; }
 
+    void setSensorAccess(const bool hasAccess);
+
 private:
     virtual ~SensorEventConnection();
     virtual void onFirstRef();
@@ -167,6 +170,7 @@
 
     mutable Mutex mDestroyLock;
     bool mDestroyed;
+    bool mHasSensorAccess;
 };
 
 } // namepsace android
diff --git a/services/sensorservice/SensorRegistrationInfo.h b/services/sensorservice/SensorRegistrationInfo.h
index 75e8989..bba8372 100644
--- a/services/sensorservice/SensorRegistrationInfo.h
+++ b/services/sensorservice/SensorRegistrationInfo.h
@@ -35,12 +35,12 @@
     }
 
     SensorRegistrationInfo(int32_t handle, const String8 &packageName,
-                           int32_t samplingRateNs, int32_t maxReportLatencyNs, bool activate) {
+                           int64_t samplingRateNs, int64_t maxReportLatencyNs, bool activate) {
         mSensorHandle = handle;
         mPackageName = packageName;
 
-        mSamplingRateUs = static_cast<int32_t>(samplingRateNs/1000);
-        mMaxReportLatencyUs = static_cast<int32_t>(maxReportLatencyNs/1000);
+        mSamplingRateUs = static_cast<int64_t>(samplingRateNs/1000);
+        mMaxReportLatencyUs = static_cast<int64_t>(maxReportLatencyNs/1000);
         mActivated = activate;
 
         IPCThreadState *thread = IPCThreadState::self();
@@ -82,8 +82,8 @@
     String8 mPackageName;
     pid_t   mPid;
     uid_t   mUid;
-    int32_t mSamplingRateUs;
-    int32_t mMaxReportLatencyUs;
+    int64_t mSamplingRateUs;
+    int64_t mMaxReportLatencyUs;
     bool mActivated;
     int8_t mHour, mMin, mSec;
 
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index dc491d9..c32ffb9 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -13,11 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <binder/ActivityManager.h>
 #include <binder/AppOpsManager.h>
 #include <binder/BinderService.h>
 #include <binder/IServiceManager.h>
 #include <binder/PermissionCache.h>
+#include <binder/PermissionController.h>
 #include <cutils/ashmem.h>
+#include <cutils/misc.h>
 #include <cutils/properties.h>
 #include <hardware/sensors.h>
 #include <hardware_legacy/power.h>
@@ -52,6 +55,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <private/android_filesystem_config.h>
+
 namespace android {
 // ---------------------------------------------------------------------------
 
@@ -75,6 +80,7 @@
 // Permissions.
 static const String16 sDumpPermission("android.permission.DUMP");
 static const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE");
+static const String16 sManageSensorsPermission("android.permission.MANAGE_SENSORS");
 
 SensorService::SensorService()
     : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
@@ -274,6 +280,23 @@
 
             // priority can only be changed after run
             enableSchedFifoMode();
+
+            // Start watching UID changes to apply policy.
+            mUidPolicy = new UidPolicy(this);
+            mUidPolicy->registerSelf();
+        }
+    }
+}
+
+void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
+    SortedVector< sp<SensorEventConnection> > activeConnections;
+    populateActiveConnections(&activeConnections);
+    {
+        Mutex::Autolock _l(mLock);
+        for (size_t i = 0 ; i < activeConnections.size(); i++) {
+            if (activeConnections[i] != 0 && activeConnections[i]->getUid() == uid) {
+                activeConnections[i]->setSensorAccess(hasAccess);
+            }
         }
     }
 }
@@ -312,6 +335,7 @@
     for (auto && entry : mRecentEvent) {
         delete entry.second;
     }
+    mUidPolicy->unregisterSelf();
 }
 
 status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -488,6 +512,82 @@
     return NO_ERROR;
 }
 
+// NOTE: This is a remote API - make sure all args are validated
+status_t SensorService::shellCommand(int in, int out, int err, Vector<String16>& args) {
+    if (!checkCallingPermission(sManageSensorsPermission, nullptr, nullptr)) {
+        return PERMISSION_DENIED;
+    }
+    if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
+        return BAD_VALUE;
+    }
+    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
+        return handleSetUidState(args, err);
+    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
+        return handleResetUidState(args, err);
+    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
+        return handleGetUidState(args, out, err);
+    } else if (args.size() == 1 && args[0] == String16("help")) {
+        printHelp(out);
+        return NO_ERROR;
+    }
+    printHelp(err);
+    return BAD_VALUE;
+}
+
+status_t SensorService::handleSetUidState(Vector<String16>& args, int err) {
+    PermissionController pc;
+    int uid = pc.getPackageUid(args[1], 0);
+    if (uid <= 0) {
+        ALOGE("Unknown package: '%s'", String8(args[1]).string());
+        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
+        return BAD_VALUE;
+    }
+    bool active = false;
+    if (args[2] == String16("active")) {
+        active = true;
+    } else if ((args[2] != String16("idle"))) {
+        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
+        return BAD_VALUE;
+    }
+    mUidPolicy->addOverrideUid(uid, active);
+    return NO_ERROR;
+}
+
+status_t SensorService::handleResetUidState(Vector<String16>& args, int err) {
+    PermissionController pc;
+    int uid = pc.getPackageUid(args[1], 0);
+    if (uid < 0) {
+        ALOGE("Unknown package: '%s'", String8(args[1]).string());
+        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
+        return BAD_VALUE;
+    }
+    mUidPolicy->removeOverrideUid(uid);
+    return NO_ERROR;
+}
+
+status_t SensorService::handleGetUidState(Vector<String16>& args, int out, int err) {
+    PermissionController pc;
+    int uid = pc.getPackageUid(args[1], 0);
+    if (uid < 0) {
+        ALOGE("Unknown package: '%s'", String8(args[1]).string());
+        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
+        return BAD_VALUE;
+    }
+    if (mUidPolicy->isUidActive(uid)) {
+        return dprintf(out, "active\n");
+    } else {
+        return dprintf(out, "idle\n");
+    }
+}
+
+status_t SensorService::printHelp(int out) {
+    return dprintf(out, "Sensor service commands:\n"
+        "  get-uid-state <PACKAGE> gets the uid state\n"
+        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
+        "  reset-uid-state <PACKAGE> clears the uid state override\n"
+        "  help print this message\n");
+}
+
 //TODO: move to SensorEventConnection later
 void SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
         sensors_event_t const* buffer, const int count) {
@@ -677,7 +777,6 @@
             }
         }
 
-
         // Send our events to clients. Check the state of wake lock for each client and release the
         // lock if none of the clients need it.
         bool needsWakeLock = false;
@@ -939,8 +1038,9 @@
             (packageName == "") ? String8::format("unknown_package_pid_%d", pid) : packageName;
     String16 connOpPackageName =
             (opPackageName == String16("")) ? String16(connPackageName) : opPackageName;
+    bool hasSensorAccess = mUidPolicy->isUidActive(uid);
     sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
-            requestedMode == DATA_INJECTION, connOpPackageName));
+            requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess));
     if (requestedMode == DATA_INJECTION) {
         if (mActiveConnections.indexOf(result) < 0) {
             mActiveConnections.add(result);
@@ -1530,4 +1630,98 @@
     return false;
 }
 
+void SensorService::UidPolicy::registerSelf() {
+    ActivityManager am;
+    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
+            | ActivityManager::UID_OBSERVER_IDLE
+            | ActivityManager::UID_OBSERVER_ACTIVE,
+            ActivityManager::PROCESS_STATE_UNKNOWN,
+            String16("android"));
+}
+
+void SensorService::UidPolicy::unregisterSelf() {
+    ActivityManager am;
+    am.unregisterUidObserver(this);
+}
+
+void SensorService::UidPolicy::onUidGone(__unused uid_t uid, __unused bool disabled) {
+    onUidIdle(uid, disabled);
+}
+
+void SensorService::UidPolicy::onUidActive(uid_t uid) {
+    {
+        Mutex::Autolock _l(mUidLock);
+        mActiveUids.insert(uid);
+    }
+    sp<SensorService> service = mService.promote();
+    if (service != nullptr) {
+        service->setSensorAccess(uid, true);
+    }
+}
+
+void SensorService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
+    bool deleted = false;
+    {
+        Mutex::Autolock _l(mUidLock);
+        if (mActiveUids.erase(uid) > 0) {
+            deleted = true;
+        }
+    }
+    if (deleted) {
+        sp<SensorService> service = mService.promote();
+        if (service != nullptr) {
+            service->setSensorAccess(uid, false);
+        }
+    }
+}
+
+void SensorService::UidPolicy::addOverrideUid(uid_t uid, bool active) {
+    updateOverrideUid(uid, active, true);
+}
+
+void SensorService::UidPolicy::removeOverrideUid(uid_t uid) {
+    updateOverrideUid(uid, false, false);
+}
+
+void SensorService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
+    bool wasActive = false;
+    bool isActive = false;
+    {
+        Mutex::Autolock _l(mUidLock);
+        wasActive = isUidActiveLocked(uid);
+        mOverrideUids.erase(uid);
+        if (insert) {
+            mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
+        }
+        isActive = isUidActiveLocked(uid);
+    }
+    if (wasActive != isActive) {
+        sp<SensorService> service = mService.promote();
+        if (service != nullptr) {
+            service->setSensorAccess(uid, isActive);
+        }
+    }
+}
+
+bool SensorService::UidPolicy::isUidActive(uid_t uid) {
+    // Non-app UIDs are considered always active
+    if (uid < FIRST_APPLICATION_UID) {
+        return true;
+    }
+    Mutex::Autolock _l(mUidLock);
+    return isUidActiveLocked(uid);
+}
+
+bool SensorService::UidPolicy::isUidActiveLocked(uid_t uid) {
+    // Non-app UIDs are considered always active
+    if (uid < FIRST_APPLICATION_UID) {
+        return true;
+    }
+    auto it = mOverrideUids.find(uid);
+    if (it != mOverrideUids.end()) {
+        return it->second;
+    }
+    return mActiveUids.find(uid) != mActiveUids.end();
+}
+
 }; // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 3e18394..f71723d 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -21,6 +21,7 @@
 #include "RecentEventLogger.h"
 
 #include <binder/BinderService.h>
+#include <binder/IUidObserver.h>
 #include <cutils/compiler.h>
 #include <sensor/ISensorServer.h>
 #include <sensor/ISensorEventConnection.h>
@@ -85,6 +86,9 @@
     status_t flushSensor(const sp<SensorEventConnection>& connection,
                          const String16& opPackageName);
 
+
+    virtual status_t shellCommand(int in, int out, int err, Vector<String16>& args);
+
 private:
     friend class BinderService<SensorService>;
 
@@ -93,6 +97,40 @@
     class SensorEventAckReceiver;
     class SensorRegistrationInfo;
 
+    // If accessing a sensor we need to make sure the UID has access to it. If
+    // the app UID is idle then it cannot access sensors and gets no trigger
+    // events, no on-change events, flush event behavior does not change, and
+    // recurring events are the same as the first one delivered in idle state
+    // emulating no sensor change. As soon as the app UID transitions to an
+    // active state we will start reporting events as usual and vise versa. This
+    // approach transparently handles observing sensors while the app UID transitions
+    // between idle/active state avoiding to get stuck in a state receiving sensor
+    // data while idle or not receiving sensor data while active.
+    class UidPolicy : public BnUidObserver {
+        public:
+            explicit UidPolicy(wp<SensorService> service)
+                    : mService(service) {}
+            void registerSelf();
+            void unregisterSelf();
+
+            bool isUidActive(uid_t uid);
+
+            void onUidGone(uid_t uid, bool disabled);
+            void onUidActive(uid_t uid);
+            void onUidIdle(uid_t uid, bool disabled);
+
+            void addOverrideUid(uid_t uid, bool active);
+            void removeOverrideUid(uid_t uid);
+        private:
+            bool isUidActiveLocked(uid_t uid);
+            void updateOverrideUid(uid_t uid, bool active, bool insert);
+
+            Mutex mUidLock;
+            wp<SensorService> mService;
+            std::unordered_set<uid_t> mActiveUids;
+            std::unordered_map<uid_t, bool> mOverrideUids;
+    };
+
     enum Mode {
        // The regular operating mode where any application can register/unregister/call flush on
        // sensors.
@@ -161,7 +199,6 @@
     virtual int setOperationParameter(
             int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints);
     virtual status_t dump(int fd, const Vector<String16>& args);
-
     String8 getSensorName(int handle) const;
     bool isVirtualSensor(int handle) const;
     sp<SensorInterface> getSensorInterfaceFromHandle(int handle) const;
@@ -225,6 +262,18 @@
     // Enable SCHED_FIFO priority for thread
     void enableSchedFifoMode();
 
+    // Sets whether the given UID can get sensor data
+    void setSensorAccess(uid_t uid, bool hasAccess);
+
+    // Overrides the UID state as if it is idle
+    status_t handleSetUidState(Vector<String16>& args, int err);
+    // Clears the override for the UID state
+    status_t handleResetUidState(Vector<String16>& args, int err);
+    // Gets the UID state
+    status_t handleGetUidState(Vector<String16>& args, int out, int err);
+    // Prints the shell command help
+    status_t printHelp(int out);
+
     static uint8_t sHmacGlobalKey[128];
     static bool sHmacGlobalKeyIsValid;
 
@@ -257,6 +306,8 @@
 
     int mNextSensorRegIndex;
     Vector<SensorRegistrationInfo> mLastNSensorRegistrations;
+
+    sp<UidPolicy> mUidPolicy;
 };
 
 } // namespace android