Merge "[RenderEngine] Remove overrided methods with GLES implementation from public."
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 0e78e3a..66dece7 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1692,15 +1692,12 @@
             *dexopt_needed_out = NO_DEXOPT_NEEDED; return true;
         case 1:  // dexoptanalyzer: dex2oat_from_scratch
             *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; return true;
-        case 5:  // dexoptanalyzer: dex2oat_for_bootimage_odex
+        case 4:  // dexoptanalyzer: dex2oat_for_bootimage_odex
             *dexopt_needed_out = -DEX2OAT_FOR_BOOT_IMAGE; return true;
-        case 6:  // dexoptanalyzer: dex2oat_for_filter_odex
+        case 5:  // dexoptanalyzer: dex2oat_for_filter_odex
             *dexopt_needed_out = -DEX2OAT_FOR_FILTER; return true;
-        case 7:  // dexoptanalyzer: dex2oat_for_relocation_odex
-            *dexopt_needed_out = -DEX2OAT_FOR_RELOCATION; return true;
         case 2:  // dexoptanalyzer: dex2oat_for_bootimage_oat
         case 3:  // dexoptanalyzer: dex2oat_for_filter_oat
-        case 4:  // dexoptanalyzer: dex2oat_for_relocation_oat
             *error_msg = StringPrintf("Dexoptanalyzer return the status of an oat file."
                                       " Expected odex file status for secondary dex %s"
                                       " : dexoptanalyzer result=%d",
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index bb6fab3..0db11e1 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -31,7 +31,6 @@
 static constexpr int DEX2OAT_FROM_SCRATCH        = 1;
 static constexpr int DEX2OAT_FOR_BOOT_IMAGE      = 2;
 static constexpr int DEX2OAT_FOR_FILTER          = 3;
-static constexpr int DEX2OAT_FOR_RELOCATION      = 4;
 
 // Clear the reference profile identified by the given profile name.
 bool clear_primary_reference_profile(const std::string& pkgname, const std::string& profile_name);
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h
index 86da4d3..0f336dd 100644
--- a/include/input/DisplayViewport.h
+++ b/include/input/DisplayViewport.h
@@ -39,13 +39,13 @@
     int32_t physicalBottom;
     int32_t deviceWidth;
     int32_t deviceHeight;
-    String8 uniqueId;
+    std::string uniqueId;
 
     DisplayViewport() :
             displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
             logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
             physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
-            deviceWidth(0), deviceHeight(0) {
+            deviceWidth(0), deviceHeight(0), uniqueId() {
     }
 
     bool operator==(const DisplayViewport& other) const {
diff --git a/include/input/Input.h b/include/input/Input.h
index 7c4379e..819a89f 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -25,7 +25,6 @@
 #include <utils/BitSet.h>
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
-#include <utils/String8.h>
 #include <utils/Timers.h>
 #include <utils/Vector.h>
 #include <stdint.h>
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index 1ea69d3..34d164c 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -31,9 +31,9 @@
     }
 
     // Information provided by the kernel.
-    String8 name;
-    String8 location;
-    String8 uniqueId;
+    std::string name;
+    std::string location;
+    std::string uniqueId;
     uint16_t bus;
     uint16_t vendor;
     uint16_t product;
@@ -45,7 +45,7 @@
     // It is hashed from whatever kernel provided information is available.
     // Ideally, the way this value is computed should not change between Android releases
     // because that would invalidate persistent settings that rely on it.
-    String8 descriptor;
+    std::string descriptor;
 
     // A value added to uniquely identify a device in the absence of a unique id. This
     // is intended to be a minimum way to distinguish from other active devices and may
@@ -73,16 +73,16 @@
     };
 
     void initialize(int32_t id, int32_t generation, int32_t controllerNumber,
-            const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal,
+            const InputDeviceIdentifier& identifier, const std::string& alias, bool isExternal,
             bool hasMic);
 
     inline int32_t getId() const { return mId; }
     inline int32_t getControllerNumber() const { return mControllerNumber; }
     inline int32_t getGeneration() const { return mGeneration; }
     inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
-    inline const String8& getAlias() const { return mAlias; }
-    inline const String8& getDisplayName() const {
-        return mAlias.isEmpty() ? mIdentifier.name : mAlias;
+    inline const std::string& getAlias() const { return mAlias; }
+    inline const std::string& getDisplayName() const {
+        return mAlias.empty() ? mIdentifier.name : mAlias;
     }
     inline bool isExternal() const { return mIsExternal; }
     inline bool hasMic() const { return mHasMic; }
@@ -121,7 +121,7 @@
     int32_t mGeneration;
     int32_t mControllerNumber;
     InputDeviceIdentifier mIdentifier;
-    String8 mAlias;
+    std::string mAlias;
     bool mIsExternal;
     bool mHasMic;
     uint32_t mSources;
@@ -149,7 +149,7 @@
  *
  * Returns an empty string if not found.
  */
-extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
+extern std::string getInputDeviceConfigurationFilePathByDeviceIdentifier(
         const InputDeviceIdentifier& deviceIdentifier,
         InputDeviceConfigurationFileType type);
 
@@ -162,8 +162,8 @@
  *
  * Returns an empty string if not found.
  */
-extern String8 getInputDeviceConfigurationFilePathByName(
-        const String8& name, InputDeviceConfigurationFileType type);
+extern std::string getInputDeviceConfigurationFilePathByName(
+        const std::string& name, InputDeviceConfigurationFileType type);
 
 } // namespace android
 
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index e8d1345..5fd86b4 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -27,6 +27,8 @@
  * The InputConsumer is used by the application to receive events from the input dispatcher.
  */
 
+#include <string>
+
 #include <input/Input.h>
 #include <utils/Errors.h>
 #include <utils/Timers.h>
diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h
index 33d2757..9f4559f 100644
--- a/include/input/KeyCharacterMap.h
+++ b/include/input/KeyCharacterMap.h
@@ -27,7 +27,6 @@
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/Tokenizer.h>
-#include <utils/String8.h>
 #include <utils/Unicode.h>
 #include <utils/RefBase.h>
 
@@ -75,10 +74,10 @@
     };
 
     /* Loads a key character map from a file. */
-    static status_t load(const String8& filename, Format format, sp<KeyCharacterMap>* outMap);
+    static status_t load(const std::string& filename, Format format, sp<KeyCharacterMap>* outMap);
 
     /* Loads a key character map from its string contents. */
-    static status_t loadContents(const String8& filename,
+    static status_t loadContents(const std::string& filename,
             const char* contents, Format format, sp<KeyCharacterMap>* outMap);
 
     /* Combines a base key character map and an overlay. */
@@ -221,7 +220,7 @@
         status_t parseKey();
         status_t parseKeyProperty();
         status_t finishKey(Key* key);
-        status_t parseModifier(const String8& token, int32_t* outMetaState);
+        status_t parseModifier(const std::string& token, int32_t* outMetaState);
         status_t parseCharacterLiteral(char16_t* outCharacter);
     };
 
diff --git a/include/input/KeyLayoutMap.h b/include/input/KeyLayoutMap.h
index 1e8de71..73815fe 100644
--- a/include/input/KeyLayoutMap.h
+++ b/include/input/KeyLayoutMap.h
@@ -62,7 +62,7 @@
  */
 class KeyLayoutMap : public RefBase {
 public:
-    static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap);
+    static status_t load(const std::string& filename, sp<KeyLayoutMap>* outMap);
 
     status_t mapKey(int32_t scanCode, int32_t usageCode,
             int32_t* outKeyCode, uint32_t* outFlags) const;
diff --git a/include/input/Keyboard.h b/include/input/Keyboard.h
index d4903e9..8b66f69 100644
--- a/include/input/Keyboard.h
+++ b/include/input/Keyboard.h
@@ -21,7 +21,6 @@
 #include <input/InputDevice.h>
 #include <input/InputEventLabels.h>
 #include <utils/Errors.h>
-#include <utils/String8.h>
 #include <utils/PropertyMap.h>
 
 namespace android {
@@ -43,10 +42,10 @@
  */
 class KeyMap {
 public:
-    String8 keyLayoutFile;
+    std::string keyLayoutFile;
     sp<KeyLayoutMap> keyLayoutMap;
 
-    String8 keyCharacterMapFile;
+    std::string keyCharacterMapFile;
     sp<KeyCharacterMap> keyCharacterMap;
 
     KeyMap();
@@ -56,11 +55,11 @@
             const PropertyMap* deviceConfiguration);
 
     inline bool haveKeyLayout() const {
-        return !keyLayoutFile.isEmpty();
+        return !keyLayoutFile.empty();
     }
 
     inline bool haveKeyCharacterMap() const {
-        return !keyCharacterMapFile.isEmpty();
+        return !keyCharacterMapFile.empty();
     }
 
     inline bool isComplete() const {
@@ -68,12 +67,12 @@
     }
 
 private:
-    bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
-    status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
+    bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const std::string& name);
+    status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const std::string& name);
     status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
-            const String8& name);
-    String8 getPath(const InputDeviceIdentifier& deviceIdentifier,
-            const String8& name, InputDeviceConfigurationFileType type);
+            const std::string& name);
+    std::string getPath(const InputDeviceIdentifier& deviceIdentifier,
+            const std::string& name, InputDeviceConfigurationFileType type);
 };
 
 /**
diff --git a/include/input/VirtualKeyMap.h b/include/input/VirtualKeyMap.h
index e245ead..24e0e0e 100644
--- a/include/input/VirtualKeyMap.h
+++ b/include/input/VirtualKeyMap.h
@@ -23,7 +23,6 @@
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/Tokenizer.h>
-#include <utils/String8.h>
 #include <utils/Unicode.h>
 
 namespace android {
@@ -50,7 +49,7 @@
 public:
     ~VirtualKeyMap();
 
-    static status_t load(const String8& filename, VirtualKeyMap** outMap);
+    static status_t load(const std::string& filename, VirtualKeyMap** outMap);
 
     inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {
         return mVirtualKeys;
diff --git a/libs/binder/ndk/AIBinder.cpp b/libs/binder/ndk/AIBinder.cpp
index d0ce98d..58cbf56 100644
--- a/libs/binder/ndk/AIBinder.cpp
+++ b/libs/binder/ndk/AIBinder.cpp
@@ -28,14 +28,29 @@
 using ::android::String16;
 using ::android::wp;
 
+namespace ABBinderTag {
+
+static const void* kId = "ABBinder";
+static void* kValue = static_cast<void*>(new bool{true});
+void cleanId(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */};
+
+static void attach(const sp<IBinder>& binder) {
+    binder->attachObject(kId, kValue, nullptr /*cookie*/, cleanId);
+}
+static bool has(const sp<IBinder>& binder) {
+    return binder != nullptr && binder->findObject(kId) == kValue;
+}
+
+} // namespace ABBinderTag
+
 AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {}
 AIBinder::~AIBinder() {}
 
-sp<AIBinder> AIBinder::associateClass(const AIBinder_Class* clazz) {
+bool AIBinder::associateClass(const AIBinder_Class* clazz) {
     using ::android::String8;
 
-    if (clazz == nullptr) return nullptr;
-    if (mClazz == clazz) return this;
+    if (clazz == nullptr) return false;
+    if (mClazz == clazz) return true;
 
     String8 newDescriptor(clazz->getInterfaceDescriptor());
 
@@ -45,42 +60,31 @@
             LOG(ERROR) << __func__ << ": Class descriptors '" << currentDescriptor
                        << "' match during associateClass, but they are different class objects. "
                           "Class descriptor collision?";
-            return nullptr;
+        } else {
+            LOG(ERROR) << __func__
+                       << ": Class cannot be associated on object which already has a class. "
+                          "Trying to associate to '"
+                       << newDescriptor.c_str() << "' but already set to '"
+                       << currentDescriptor.c_str() << "'.";
         }
 
-        LOG(ERROR) << __func__
-                   << ": Class cannot be associated on object which already has a class. Trying to "
-                      "associate to '"
-                   << newDescriptor.c_str() << "' but already set to '" << currentDescriptor.c_str()
-                   << "'.";
-        return nullptr;
+        // always a failure because we know mClazz != clazz
+        return false;
     }
 
+    CHECK(asABpBinder() != nullptr); // ABBinder always has a descriptor
+
     String8 descriptor(getBinder()->getInterfaceDescriptor());
     if (descriptor != newDescriptor) {
         LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str()
                    << "' but descriptor is actually '" << descriptor.c_str() << "'.";
-        return nullptr;
+        return false;
     }
 
-    // The descriptor matches, so if it is local, this is guaranteed to be the libbinder_ndk class.
-    // An error here can occur if there is a conflict between descriptors (two unrelated classes
-    // define the same descriptor), but this should never happen.
-
-    // if this is a local ABBinder, mClazz should be non-null
-    CHECK(asABBinder() == nullptr);
-    CHECK(asABpBinder() != nullptr);
-
-    if (!isRemote()) {
-        // ABpBinder but proxy to a local object. Therefore that local object must be an ABBinder.
-        ABBinder* binder = static_cast<ABBinder*>(getBinder().get());
-        return binder;
-    }
-
-    // This is a remote object
+    // if this is a local object, it's not one known to libbinder_ndk
     mClazz = clazz;
 
-    return this;
+    return true;
 }
 
 ABBinder::ABBinder(const AIBinder_Class* clazz, void* userData)
@@ -111,24 +115,45 @@
     }
 }
 
-ABpBinder::ABpBinder(::android::sp<::android::IBinder> binder)
+ABpBinder::ABpBinder(const ::android::sp<::android::IBinder>& binder)
       : AIBinder(nullptr /*clazz*/), BpRefBase(binder) {
     CHECK(binder != nullptr);
 }
 ABpBinder::~ABpBinder() {}
 
+sp<AIBinder> ABpBinder::fromBinder(const ::android::sp<::android::IBinder>& binder) {
+    if (binder == nullptr) {
+        return nullptr;
+    }
+    if (ABBinderTag::has(binder)) {
+        return static_cast<ABBinder*>(binder.get());
+    }
+    return new ABpBinder(binder);
+}
+
 struct AIBinder_Weak {
     wp<AIBinder> binder;
 };
 AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder) {
-    if (binder == nullptr) return nullptr;
+    if (binder == nullptr) {
+        return nullptr;
+    }
+
     return new AIBinder_Weak{wp<AIBinder>(binder)};
 }
-void AIBinder_Weak_delete(AIBinder_Weak* weakBinder) {
-    delete weakBinder;
+void AIBinder_Weak_delete(AIBinder_Weak** weakBinder) {
+    if (weakBinder == nullptr) {
+        return;
+    }
+
+    delete *weakBinder;
+    *weakBinder = nullptr;
 }
 AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder) {
-    if (weakBinder == nullptr) return nullptr;
+    if (weakBinder == nullptr) {
+        return nullptr;
+    }
+
     sp<AIBinder> binder = weakBinder->binder.promote();
     AIBinder_incStrong(binder.get());
     return binder.get();
@@ -162,12 +187,14 @@
 
     void* userData = clazz->onCreate(args);
 
-    AIBinder* ret = new ABBinder(clazz, userData);
-    AIBinder_incStrong(ret);
-    return ret;
+    sp<AIBinder> ret = new ABBinder(clazz, userData);
+    ABBinderTag::attach(ret->getBinder());
+
+    AIBinder_incStrong(ret.get());
+    return ret.get();
 }
 
-bool AIBinder_isRemote(AIBinder* binder) {
+bool AIBinder_isRemote(const AIBinder* binder) {
     if (binder == nullptr) {
         return true;
     }
@@ -200,23 +227,12 @@
     return binder->getStrongCount();
 }
 
-void AIBinder_associateClass(AIBinder** binder, const AIBinder_Class* clazz) {
-    if (binder == nullptr || *binder == nullptr) {
-        return;
+bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz) {
+    if (binder == nullptr) {
+        return false;
     }
 
-    sp<AIBinder> result = (*binder)->associateClass(clazz);
-
-    // This function takes one refcount of 'binder' and delivers one refcount of 'result' to the
-    // callee. First we give the callee their refcount and then take it away from binder. This is
-    // done in this order in order to handle the case that the result and the binder are the same
-    // object.
-    if (result != nullptr) {
-        AIBinder_incStrong(result.get());
-    }
-    AIBinder_decStrong(*binder);
-
-    *binder = result.get(); // Maybe no-op
+    return binder->associateClass(clazz);
 }
 
 const AIBinder_Class* AIBinder_getClass(AIBinder* binder) {
diff --git a/libs/binder/ndk/AIBinder_internal.h b/libs/binder/ndk/AIBinder_internal.h
index d44b937..23949bb 100644
--- a/libs/binder/ndk/AIBinder_internal.h
+++ b/libs/binder/ndk/AIBinder_internal.h
@@ -35,23 +35,16 @@
     AIBinder(const AIBinder_Class* clazz);
     virtual ~AIBinder();
 
-    // This returns an AIBinder object with this class associated. If the class is already
-    // associated, 'this' will be returned. If there is a local AIBinder implementation, that will
-    // be returned. If this is a remote object, the class will be associated and this will be ready
-    // to be used for transactions.
-    ::android::sp<AIBinder> associateClass(const AIBinder_Class* clazz);
+    bool associateClass(const AIBinder_Class* clazz);
     const AIBinder_Class* getClass() const { return mClazz; }
 
-    // This does not create the binder if it does not exist in the process.
     virtual ::android::sp<::android::IBinder> getBinder() = 0;
     virtual ABBinder* asABBinder() { return nullptr; }
     virtual ABpBinder* asABpBinder() { return nullptr; }
 
-    bool isRemote() {
-        auto binder = getBinder();
-        // if the binder is nullptr, then it is a local object which hasn't been sent out of process
-        // yet.
-        return binder != nullptr && binder->remoteBinder() != nullptr;
+    bool isRemote() const {
+        ::android::sp<::android::IBinder> binder = const_cast<AIBinder*>(this)->getBinder();
+        return binder->remoteBinder() != nullptr;
     }
 
 private:
@@ -63,7 +56,6 @@
 
 // This is a local AIBinder object with a known class.
 struct ABBinder : public AIBinder, public ::android::BBinder {
-    ABBinder(const AIBinder_Class* clazz, void* userData);
     virtual ~ABBinder();
 
     void* getUserData() { return mUserData; }
@@ -76,6 +68,11 @@
                                ::android::Parcel* reply, binder_flags_t flags) override;
 
 private:
+    ABBinder(const AIBinder_Class* clazz, void* userData);
+
+    // only thing that should create an ABBinder
+    friend AIBinder* AIBinder_new(const AIBinder_Class*, void*);
+
     // Can contain implementation if this is a local binder. This can still be nullptr for a local
     // binder. If it is nullptr, the implication is the implementation state is entirely external to
     // this object and the functionality provided in the AIBinder_Class is sufficient.
@@ -85,11 +82,15 @@
 // This binder object may be remote or local (even though it is 'Bp'). It is not yet associated with
 // a class.
 struct ABpBinder : public AIBinder, public ::android::BpRefBase {
-    ABpBinder(::android::sp<::android::IBinder> binder);
+    static ::android::sp<AIBinder> fromBinder(const ::android::sp<::android::IBinder>& binder);
+
     virtual ~ABpBinder();
 
     ::android::sp<::android::IBinder> getBinder() override { return remote(); }
     ABpBinder* asABpBinder() override { return this; }
+
+private:
+    ABpBinder(const ::android::sp<::android::IBinder>& binder);
 };
 
 struct AIBinder_Class {
diff --git a/libs/binder/ndk/AParcel.cpp b/libs/binder/ndk/AParcel.cpp
index b63b138..f39e732 100644
--- a/libs/binder/ndk/AParcel.cpp
+++ b/libs/binder/ndk/AParcel.cpp
@@ -34,8 +34,9 @@
     if (status != EX_NONE) {
         return status;
     }
-    *binder = new ABpBinder(readBinder);
-    AIBinder_incStrong(*binder);
+    sp<AIBinder> ret = ABpBinder::fromBinder(readBinder);
+    AIBinder_incStrong(ret.get());
+    *binder = ret.get();
     return status;
 }
 binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder) {
@@ -44,8 +45,9 @@
     if (status != EX_NONE) {
         return status;
     }
-    *binder = new ABpBinder(readBinder);
-    AIBinder_incStrong(*binder);
+    sp<AIBinder> ret = ABpBinder::fromBinder(readBinder);
+    AIBinder_incStrong(ret.get());
+    *binder = ret.get();
     return status;
 }
 
diff --git a/libs/binder/ndk/AServiceManager.cpp b/libs/binder/ndk/AServiceManager.cpp
index f61b914..3979945 100644
--- a/libs/binder/ndk/AServiceManager.cpp
+++ b/libs/binder/ndk/AServiceManager.cpp
@@ -41,7 +41,7 @@
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> binder = sm->getService(String16(instance));
 
-    AIBinder* ret = new ABpBinder(binder);
-    AIBinder_incStrong(ret);
-    return ret;
+    sp<AIBinder> ret = ABpBinder::fromBinder(binder);
+    AIBinder_incStrong(ret.get());
+    return ret.get();
 }
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 23136a2..f752008 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -144,7 +144,7 @@
 /**
  * If this is hosted in a process other than the current one.
  */
-bool AIBinder_isRemote(AIBinder* binder);
+bool AIBinder_isRemote(const AIBinder* binder);
 
 /**
  * This can only be called if a strong reference to this object already exists in process.
@@ -167,11 +167,10 @@
  * However, if an object is just intended to be passed through to another process or used as a
  * handle this need not be called.
  *
- * The binder parameter may or may not be updated. If it is updated, the ownership of the original
- * object is transferred to the new object. If the class association fails, ownership of the binder
- * is lost, and it is set to nullptr.
+ * This returns true if the class association succeeds. If it fails, no change is made to the
+ * binder object.
  */
-void AIBinder_associateClass(AIBinder** binder, const AIBinder_Class* clazz);
+bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz);
 
 /*
  * Returns the class that this binder was constructed with or associated with.
@@ -236,7 +235,7 @@
 /*
  * Deletes the weak reference. This will have no impact on the lifetime of the binder.
  */
-void AIBinder_Weak_delete(AIBinder_Weak* weakBinder);
+void AIBinder_Weak_delete(AIBinder_Weak** weakBinder);
 
 /**
  * If promotion succeeds, result will have one strong refcount added to it. Otherwise, this returns
diff --git a/libs/binder/ndk/test/iface.cpp b/libs/binder/ndk/test/iface.cpp
index eed09f0..27553c8 100644
--- a/libs/binder/ndk/test/iface.cpp
+++ b/libs/binder/ndk/test/iface.cpp
@@ -91,7 +91,7 @@
 };
 
 IFoo::~IFoo() {
-    AIBinder_Weak_delete(mWeakBinder);
+    AIBinder_Weak_delete(&mWeakBinder);
 }
 
 binder_status_t IFoo::addService(const char* instance) {
@@ -105,7 +105,7 @@
         // or one strong refcount here
         binder = AIBinder_new(IFoo::kClass, static_cast<void*>(new IFoo_Class_Data{this}));
         if (mWeakBinder != nullptr) {
-            AIBinder_Weak_delete(mWeakBinder);
+            AIBinder_Weak_delete(&mWeakBinder);
         }
         mWeakBinder = AIBinder_Weak_new(binder);
     }
@@ -118,12 +118,15 @@
 
 sp<IFoo> IFoo::getService(const char* instance) {
     AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr
-    AIBinder_associateClass(&binder, IFoo::kClass);
-
     if (binder == nullptr) {
         return nullptr;
     }
 
+    if (!AIBinder_associateClass(binder, IFoo::kClass)) {
+        AIBinder_decStrong(binder);
+        return nullptr;
+    }
+
     if (AIBinder_isRemote(binder)) {
         sp<IFoo> ret = new BpFoo(binder); // takes ownership of binder
         return ret;
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 5d27bf6..778c453 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -20,9 +20,12 @@
 #include <unistd.h>
 #include <ctype.h>
 
+#include <android-base/stringprintf.h>
 #include <input/InputDevice.h>
 #include <input/InputEventLabels.h>
 
+using android::base::StringPrintf;
+
 namespace android {
 
 static const char* CONFIGURATION_FILE_DIR[] = {
@@ -41,8 +44,8 @@
     return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
 }
 
-static void appendInputDeviceConfigurationFileRelativePath(String8& path,
-        const String8& name, InputDeviceConfigurationFileType type) {
+static void appendInputDeviceConfigurationFileRelativePath(std::string& path,
+        const std::string& name, InputDeviceConfigurationFileType type) {
     path.append(CONFIGURATION_FILE_DIR[type]);
     for (size_t i = 0; i < name.length(); i++) {
         char ch = name[i];
@@ -54,28 +57,28 @@
     path.append(CONFIGURATION_FILE_EXTENSION[type]);
 }
 
-String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
+std::string getInputDeviceConfigurationFilePathByDeviceIdentifier(
         const InputDeviceIdentifier& deviceIdentifier,
         InputDeviceConfigurationFileType type) {
     if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
         if (deviceIdentifier.version != 0) {
             // Try vendor product version.
-            String8 versionPath(getInputDeviceConfigurationFilePathByName(
-                    String8::format("Vendor_%04x_Product_%04x_Version_%04x",
+            std::string versionPath = getInputDeviceConfigurationFilePathByName(
+                    StringPrintf("Vendor_%04x_Product_%04x_Version_%04x",
                             deviceIdentifier.vendor, deviceIdentifier.product,
                             deviceIdentifier.version),
-                    type));
-            if (!versionPath.isEmpty()) {
+                    type);
+            if (!versionPath.empty()) {
                 return versionPath;
             }
         }
 
         // Try vendor product.
-        String8 productPath(getInputDeviceConfigurationFilePathByName(
-                String8::format("Vendor_%04x_Product_%04x",
+        std::string productPath = getInputDeviceConfigurationFilePathByName(
+                StringPrintf("Vendor_%04x_Product_%04x",
                         deviceIdentifier.vendor, deviceIdentifier.product),
-                type));
-        if (!productPath.isEmpty()) {
+                type);
+        if (!productPath.empty()) {
             return productPath;
         }
     }
@@ -84,22 +87,25 @@
     return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
 }
 
-String8 getInputDeviceConfigurationFilePathByName(
-        const String8& name, InputDeviceConfigurationFileType type) {
+std::string getInputDeviceConfigurationFilePathByName(
+        const std::string& name, InputDeviceConfigurationFileType type) {
     // Search system repository.
-    String8 path;
+    std::string path;
 
     // Treblized input device config files will be located /odm/usr or /vendor/usr.
     const char *rootsForPartition[] {"/odm", "/vendor", getenv("ANDROID_ROOT")};
     for (size_t i = 0; i < size(rootsForPartition); i++) {
-        path.setTo(rootsForPartition[i]);
-        path.append("/usr/");
+        if (rootsForPartition[i] == nullptr) {
+            continue;
+        }
+        path = rootsForPartition[i];
+        path += "/usr/";
         appendInputDeviceConfigurationFileRelativePath(path, name, type);
 #if DEBUG_PROBE
         ALOGD("Probing for system provided input device configuration file: path='%s'",
-              path.string());
+              path.c_str());
 #endif
-        if (!access(path.string(), R_OK)) {
+        if (!access(path.c_str(), R_OK)) {
 #if DEBUG_PROBE
             ALOGD("Found");
 #endif
@@ -109,13 +115,17 @@
 
     // Search user repository.
     // TODO Should only look here if not in safe mode.
-    path.setTo(getenv("ANDROID_DATA"));
-    path.append("/system/devices/");
+    path = "";
+    char *androidData = getenv("ANDROID_DATA");
+    if (androidData != nullptr) {
+        path += androidData;
+    }
+    path += "/system/devices/";
     appendInputDeviceConfigurationFileRelativePath(path, name, type);
 #if DEBUG_PROBE
-    ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
+    ALOGD("Probing for system user input device configuration file: path='%s'", path.c_str());
 #endif
-    if (!access(path.string(), R_OK)) {
+    if (!access(path.c_str(), R_OK)) {
 #if DEBUG_PROBE
         ALOGD("Found");
 #endif
@@ -125,16 +135,16 @@
     // Not found.
 #if DEBUG_PROBE
     ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
-            name.string(), type);
+            name.c_str(), type);
 #endif
-    return String8();
+    return "";
 }
 
 
 // --- InputDeviceInfo ---
 
 InputDeviceInfo::InputDeviceInfo() {
-    initialize(-1, 0, -1, InputDeviceIdentifier(), String8(), false, false);
+    initialize(-1, 0, -1, InputDeviceIdentifier(), "", false, false);
 }
 
 InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
@@ -150,7 +160,7 @@
 }
 
 void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber,
-        const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal,
+        const InputDeviceIdentifier& identifier, const std::string& alias, bool isExternal,
         bool hasMic) {
     mId = id;
     mGeneration = generation;
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 26747bd..e189d20 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -106,14 +106,14 @@
     }
 }
 
-status_t KeyCharacterMap::load(const String8& filename,
+status_t KeyCharacterMap::load(const std::string& filename,
         Format format, sp<KeyCharacterMap>* outMap) {
     outMap->clear();
 
     Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
+    status_t status = Tokenizer::open(String8(filename.c_str()), &tokenizer);
     if (status) {
-        ALOGE("Error %d opening key character map file %s.", status, filename.string());
+        ALOGE("Error %d opening key character map file %s.", status, filename.c_str());
     } else {
         status = load(tokenizer, format, outMap);
         delete tokenizer;
@@ -121,12 +121,12 @@
     return status;
 }
 
-status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents,
+status_t KeyCharacterMap::loadContents(const std::string& filename, const char* contents,
         Format format, sp<KeyCharacterMap>* outMap) {
     outMap->clear();
 
     Tokenizer* tokenizer;
-    status_t status = Tokenizer::fromContents(filename, contents, &tokenizer);
+    status_t status = Tokenizer::fromContents(String8(filename.c_str()), contents, &tokenizer);
     if (status) {
         ALOGE("Error %d opening key character map.", status);
     } else {
@@ -944,7 +944,7 @@
             properties.add(Property(PROPERTY_NUMBER));
         } else {
             int32_t metaState;
-            status_t status = parseModifier(token, &metaState);
+            status_t status = parseModifier(token.string(), &metaState);
             if (status) {
                 ALOGE("%s: Expected a property name or modifier, got '%s'.",
                         mTokenizer->getLocation().string(), token.string());
@@ -1137,7 +1137,7 @@
     return NO_ERROR;
 }
 
-status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
+status_t KeyCharacterMap::Parser::parseModifier(const std::string& token, int32_t* outMetaState) {
     if (token == "base") {
         *outMetaState = 0;
         return NO_ERROR;
@@ -1145,7 +1145,7 @@
 
     int32_t combinedMeta = 0;
 
-    const char* str = token.string();
+    const char* str = token.c_str();
     const char* start = str;
     for (const char* cur = str; ; cur++) {
         char ch = *cur;
@@ -1164,7 +1164,7 @@
             }
             if (combinedMeta & metaState) {
                 ALOGE("%s: Duplicate modifier combination '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
+                        mTokenizer->getLocation().string(), token.c_str());
                 return BAD_VALUE;
             }
 
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index c440078..88cb0db 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -49,13 +49,13 @@
 KeyLayoutMap::~KeyLayoutMap() {
 }
 
-status_t KeyLayoutMap::load(const String8& filename, sp<KeyLayoutMap>* outMap) {
+status_t KeyLayoutMap::load(const std::string& filename, sp<KeyLayoutMap>* outMap) {
     outMap->clear();
 
     Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
+    status_t status = Tokenizer::open(String8(filename.c_str()), &tokenizer);
     if (status) {
-        ALOGE("Error %d opening key layout map file %s.", status, filename.string());
+        ALOGE("Error %d opening key layout map file %s.", status, filename.c_str());
     } else {
         sp<KeyLayoutMap> map = new KeyLayoutMap();
         if (!map.get()) {
diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp
index 11842ee..0c22bfe 100644
--- a/libs/input/Keyboard.cpp
+++ b/libs/input/Keyboard.cpp
@@ -45,22 +45,22 @@
         String8 keyLayoutName;
         if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
                 keyLayoutName)) {
-            status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName);
+            status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName.c_str());
             if (status == NAME_NOT_FOUND) {
                 ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
                         "it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
+                        deviceIdenfifier.name.c_str(), keyLayoutName.string());
             }
         }
 
         String8 keyCharacterMapName;
         if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
                 keyCharacterMapName)) {
-            status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName);
+            status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName.c_str());
             if (status == NAME_NOT_FOUND) {
                 ALOGE("Configuration for keyboard device '%s' requested keyboard character "
                         "map '%s' but it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
+                        deviceIdenfifier.name.c_str(), keyLayoutName.string());
             }
         }
 
@@ -70,30 +70,30 @@
     }
 
     // Try searching by device identifier.
-    if (probeKeyMap(deviceIdenfifier, String8::empty())) {
+    if (probeKeyMap(deviceIdenfifier, "")) {
         return OK;
     }
 
     // Fall back on the Generic key map.
     // TODO Apply some additional heuristics here to figure out what kind of
     //      generic key map to use (US English, etc.) for typical external keyboards.
-    if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
+    if (probeKeyMap(deviceIdenfifier, "Generic")) {
         return OK;
     }
 
     // Try the Virtual key map as a last resort.
-    if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
+    if (probeKeyMap(deviceIdenfifier, "Virtual")) {
         return OK;
     }
 
     // Give up!
     ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
-            deviceIdenfifier.name.string());
+            deviceIdenfifier.name.c_str());
     return NAME_NOT_FOUND;
 }
 
 bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& keyMapName) {
+        const std::string& keyMapName) {
     if (!haveKeyLayout()) {
         loadKeyLayout(deviceIdentifier, keyMapName);
     }
@@ -104,10 +104,10 @@
 }
 
 status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
+        const std::string& name) {
+    std::string path(getPath(deviceIdentifier, name,
             INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
-    if (path.isEmpty()) {
+    if (path.empty()) {
         return NAME_NOT_FOUND;
     }
 
@@ -116,15 +116,15 @@
         return status;
     }
 
-    keyLayoutFile.setTo(path);
+    keyLayoutFile = path;
     return OK;
 }
 
 status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
-            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
-    if (path.isEmpty()) {
+        const std::string& name) {
+    std::string path = getPath(deviceIdentifier, name,
+            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP);
+    if (path.empty()) {
         return NAME_NOT_FOUND;
     }
 
@@ -134,13 +134,13 @@
         return status;
     }
 
-    keyCharacterMapFile.setTo(path);
+    keyCharacterMapFile = path;
     return OK;
 }
 
-String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name, InputDeviceConfigurationFileType type) {
-    return name.isEmpty()
+std::string KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
+        const std::string& name, InputDeviceConfigurationFileType type) {
+    return name.empty()
             ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
             : getInputDeviceConfigurationFilePathByName(name, type);
 }
@@ -174,7 +174,7 @@
         }
     }
 
-    return strstr(deviceIdentifier.name.string(), "-keypad");
+    return strstr(deviceIdentifier.name.c_str(), "-keypad");
 }
 
 static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
diff --git a/libs/input/VirtualKeyMap.cpp b/libs/input/VirtualKeyMap.cpp
index 9932973..3ec53bf 100644
--- a/libs/input/VirtualKeyMap.cpp
+++ b/libs/input/VirtualKeyMap.cpp
@@ -46,13 +46,13 @@
 VirtualKeyMap::~VirtualKeyMap() {
 }
 
-status_t VirtualKeyMap::load(const String8& filename, VirtualKeyMap** outMap) {
+status_t VirtualKeyMap::load(const std::string& filename, VirtualKeyMap** outMap) {
     *outMap = nullptr;
 
     Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
+    status_t status = Tokenizer::open(String8(filename.c_str()), &tokenizer);
     if (status) {
-        ALOGE("Error %d opening virtual key map file %s.", status, filename.string());
+        ALOGE("Error %d opening virtual key map file %s.", status, filename.c_str());
     } else {
         VirtualKeyMap* map = new VirtualKeyMap();
         if (!map) {
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 77a474f..a964d29 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -76,16 +76,16 @@
     return value ? "true" : "false";
 }
 
-static String8 sha1(const String8& in) {
+static std::string sha1(const std::string& in) {
     SHA_CTX ctx;
     SHA1_Init(&ctx);
-    SHA1_Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size());
+    SHA1_Update(&ctx, reinterpret_cast<const u_char*>(in.c_str()), in.size());
     u_char digest[SHA_DIGEST_LENGTH];
     SHA1_Final(digest, &ctx);
 
-    String8 out;
+    std::string out;
     for (size_t i = 0; i < SHA_DIGEST_LENGTH; i++) {
-        out.appendFormat("%02x", digest[i]);
+        out += StringPrintf("%02x", digest[i]);
     }
     return out;
 }
@@ -141,7 +141,7 @@
 
 // --- EventHub::Device ---
 
-EventHub::Device::Device(int fd, int32_t id, const String8& path,
+EventHub::Device::Device(int fd, int32_t id, const std::string& path,
         const InputDeviceIdentifier& identifier) :
         next(nullptr),
         fd(fd), id(id), path(path), identifier(identifier),
@@ -172,9 +172,9 @@
 }
 
 status_t EventHub::Device::enable() {
-    fd = open(path, O_RDWR | O_CLOEXEC | O_NONBLOCK);
+    fd = open(path.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
     if(fd < 0) {
-        ALOGE("could not open %s, %s\n", path.string(), strerror(errno));
+        ALOGE("could not open %s, %s\n", path.c_str(), strerror(errno));
         return -errno;
     }
     enabled = true;
@@ -307,7 +307,7 @@
             struct input_absinfo info;
             if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
                 ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
-                     axis, device->identifier.name.string(), device->fd, errno);
+                     axis, device->identifier.name.c_str(), device->fd, errno);
                 return -errno;
             }
 
@@ -416,7 +416,7 @@
             struct input_absinfo info;
             if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
                 ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
-                     axis, device->identifier.name.string(), device->fd, errno);
+                     axis, device->identifier.name.c_str(), device->fd, errno);
                 return -errno;
             }
 
@@ -512,7 +512,7 @@
     return NAME_NOT_FOUND;
 }
 
-void EventHub::setExcludedDevices(const Vector<String8>& devices) {
+void EventHub::setExcludedDevices(const std::vector<std::string>& devices) {
     AutoMutex _l(mLock);
 
     mExcludedDevices = devices;
@@ -599,16 +599,16 @@
     return false;
 }
 
-static String8 generateDescriptor(InputDeviceIdentifier& identifier) {
-    String8 rawDescriptor;
-    rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor,
+static std::string generateDescriptor(InputDeviceIdentifier& identifier) {
+    std::string rawDescriptor;
+    rawDescriptor += StringPrintf(":%04x:%04x:", identifier.vendor,
             identifier.product);
     // TODO add handling for USB devices to not uniqueify kbs that show up twice
-    if (!identifier.uniqueId.isEmpty()) {
-        rawDescriptor.append("uniqueId:");
-        rawDescriptor.append(identifier.uniqueId);
+    if (!identifier.uniqueId.empty()) {
+        rawDescriptor += "uniqueId:";
+        rawDescriptor += identifier.uniqueId;
     } else if (identifier.nonce != 0) {
-        rawDescriptor.appendFormat("nonce:%04x", identifier.nonce);
+        rawDescriptor += StringPrintf("nonce:%04x", identifier.nonce);
     }
 
     if (identifier.vendor == 0 && identifier.product == 0) {
@@ -616,12 +616,12 @@
         // built-in so we need to rely on other information to uniquely identify
         // the input device.  Usually we try to avoid relying on the device name or
         // location but for built-in input device, they are unlikely to ever change.
-        if (!identifier.name.isEmpty()) {
-            rawDescriptor.append("name:");
-            rawDescriptor.append(identifier.name);
-        } else if (!identifier.location.isEmpty()) {
-            rawDescriptor.append("location:");
-            rawDescriptor.append(identifier.location);
+        if (!identifier.name.empty()) {
+            rawDescriptor += "name:";
+            rawDescriptor += identifier.name;
+        } else if (!identifier.location.empty()) {
+            rawDescriptor += "location:";
+            rawDescriptor += identifier.location;
         }
     }
     identifier.descriptor = sha1(rawDescriptor);
@@ -637,8 +637,8 @@
     // Ideally, we also want the descriptor to be short and relatively opaque.
 
     identifier.nonce = 0;
-    String8 rawDescriptor = generateDescriptor(identifier);
-    if (identifier.uniqueId.isEmpty()) {
+    std::string rawDescriptor = generateDescriptor(identifier);
+    if (identifier.uniqueId.empty()) {
         // If it didn't have a unique id check for conflicts and enforce
         // uniqueness if necessary.
         while(getDeviceByDescriptorLocked(identifier.descriptor) != nullptr) {
@@ -646,8 +646,8 @@
             rawDescriptor = generateDescriptor(identifier);
         }
     }
-    ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(),
-            identifier.descriptor.string());
+    ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.c_str(),
+            identifier.descriptor.c_str());
 }
 
 void EventHub::vibrate(int32_t deviceId, nsecs_t duration) {
@@ -664,7 +664,7 @@
         effect.replay.delay = 0;
         if (ioctl(device->fd, EVIOCSFF, &effect)) {
             ALOGW("Could not upload force feedback effect to device %s due to error %d.",
-                    device->identifier.name.string(), errno);
+                    device->identifier.name.c_str(), errno);
             return;
         }
         device->ffEffectId = effect.id;
@@ -677,7 +677,7 @@
         ev.value = 1;
         if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
             ALOGW("Could not start force feedback effect on device %s due to error %d.",
-                    device->identifier.name.string(), errno);
+                    device->identifier.name.c_str(), errno);
             return;
         }
         device->ffEffectPlaying = true;
@@ -699,18 +699,18 @@
             ev.value = 0;
             if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
                 ALOGW("Could not stop force feedback effect on device %s due to error %d.",
-                        device->identifier.name.string(), errno);
+                        device->identifier.name.c_str(), errno);
                 return;
             }
         }
     }
 }
 
-EventHub::Device* EventHub::getDeviceByDescriptorLocked(String8& descriptor) const {
+EventHub::Device* EventHub::getDeviceByDescriptorLocked(const std::string& descriptor) const {
     size_t size = mDevices.size();
     for (size_t i = 0; i < size; i++) {
         Device* device = mDevices.valueAt(i);
-        if (descriptor.compare(device->identifier.descriptor) == 0) {
+        if (descriptor == device->identifier.descriptor) {
             return device;
         }
     }
@@ -763,7 +763,7 @@
         while (mClosingDevices) {
             Device* device = mClosingDevices;
             ALOGV("Reporting device closed: id=%d, name=%s\n",
-                 device->id, device->path.string());
+                 device->id, device->path.c_str());
             mClosingDevices = device->next;
             event->when = now;
             event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;
@@ -785,7 +785,7 @@
         while (mOpeningDevices != nullptr) {
             Device* device = mOpeningDevices;
             ALOGV("Reporting device opened: id=%d, name=%s\n",
-                 device->id, device->path.string());
+                 device->id, device->path.c_str());
             mOpeningDevices = device->next;
             event->when = now;
             event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
@@ -867,7 +867,7 @@
                     for (size_t i = 0; i < count; i++) {
                         struct input_event& iev = readBuffer[i];
                         ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d",
-                                device->path.string(),
+                                device->path.c_str(),
                                 (int) iev.time.tv_sec, (int) iev.time.tv_usec,
                                 iev.type, iev.code, iev.value);
 
@@ -936,7 +936,7 @@
                                         "event time %" PRId64 ", current time %" PRId64
                                         ", call time %" PRId64 ".  "
                                         "Using current time instead.",
-                                        device->path.string(), event->when, time, now);
+                                        device->path.c_str(), event->when, time, now);
                                 event->when = time;
                             } else {
                                 ALOGV("Event time is ok but failed the fast path and required "
@@ -962,12 +962,12 @@
                 }
             } else if (eventItem.events & EPOLLHUP) {
                 ALOGI("Removing device %s due to epoll hang-up event.",
-                        device->identifier.name.string());
+                        device->identifier.name.c_str());
                 deviceChanged = true;
                 closeDeviceLocked(device);
             } else {
                 ALOGW("Received unexpected epoll event 0x%08x for device %s.",
-                        eventItem.events, device->identifier.name.string());
+                        eventItem.events, device->identifier.name.c_str());
             }
         }
 
@@ -1125,14 +1125,14 @@
         //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno));
     } else {
         buffer[sizeof(buffer) - 1] = '\0';
-        identifier.name.setTo(buffer);
+        identifier.name = buffer;
     }
 
     // Check to see if the device is on our excluded list
     for (size_t i = 0; i < mExcludedDevices.size(); i++) {
-        const String8& item = mExcludedDevices.itemAt(i);
+        const std::string& item = mExcludedDevices[i];
         if (identifier.name == item) {
-            ALOGI("ignoring event id %s driver %s\n", devicePath, item.string());
+            ALOGI("ignoring event id %s driver %s\n", devicePath, item.c_str());
             close(fd);
             return -1;
         }
@@ -1163,7 +1163,7 @@
         //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
     } else {
         buffer[sizeof(buffer) - 1] = '\0';
-        identifier.location.setTo(buffer);
+        identifier.location = buffer;
     }
 
     // Get device unique id.
@@ -1171,7 +1171,7 @@
         //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
     } else {
         buffer[sizeof(buffer) - 1] = '\0';
-        identifier.uniqueId.setTo(buffer);
+        identifier.uniqueId = buffer;
     }
 
     // Fill in the descriptor.
@@ -1179,7 +1179,7 @@
 
     // Allocate device.  (The device object takes ownership of the fd at this point.)
     int32_t deviceId = mNextDeviceId++;
-    Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
+    Device* device = new Device(fd, deviceId, devicePath, identifier);
 
     ALOGV("add device %d: %s\n", deviceId, devicePath);
     ALOGV("  bus:        %04x\n"
@@ -1187,10 +1187,10 @@
          "  product     %04x\n"
          "  version     %04x\n",
         identifier.bus, identifier.vendor, identifier.product, identifier.version);
-    ALOGV("  name:       \"%s\"\n", identifier.name.string());
-    ALOGV("  location:   \"%s\"\n", identifier.location.string());
-    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.string());
-    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.string());
+    ALOGV("  name:       \"%s\"\n", identifier.name.c_str());
+    ALOGV("  location:   \"%s\"\n", identifier.location.c_str());
+    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.c_str());
+    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.c_str());
     ALOGV("  driver:     v%d.%d.%d\n",
         driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);
 
@@ -1343,7 +1343,7 @@
     // If the device isn't recognized as something we handle, don't monitor it.
     if (device->classes == 0) {
         ALOGV("Dropping device: id=%d, path='%s', name='%s'",
-                deviceId, devicePath, device->identifier.name.string());
+                deviceId, devicePath, device->identifier.name.c_str());
         delete device;
         return -1;
     }
@@ -1374,11 +1374,11 @@
 
     ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
             "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, ",
-         deviceId, fd, devicePath, device->identifier.name.string(),
+         deviceId, fd, devicePath, device->identifier.name.c_str(),
          device->classes,
-         device->configurationFile.string(),
-         device->keyMap.keyLayoutFile.string(),
-         device->keyMap.keyCharacterMapFile.string(),
+         device->configurationFile.c_str(),
+         device->keyMap.keyLayoutFile.c_str(),
+         device->keyMap.keyCharacterMapFile.c_str(),
          toString(mBuiltInKeyboardId == deviceId));
 
     addDeviceLocked(device);
@@ -1392,11 +1392,11 @@
         unsigned int repeatRate[] = {0, 0};
         if (ioctl(device->fd, EVIOCSREP, repeatRate)) {
             ALOGW("Unable to disable kernel key repeat for %s: %s",
-                  device->path.string(), strerror(errno));
+                  device->path.c_str(), strerror(errno));
         }
     }
 
-    String8 wakeMechanism("EPOLLWAKEUP");
+    std::string wakeMechanism = "EPOLLWAKEUP";
     if (!mUsingEpollWakeup) {
 #ifndef EVIOCSSUSPENDBLOCK
         // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels
@@ -1416,7 +1416,7 @@
     // clock.
     int clockId = CLOCK_MONOTONIC;
     bool usingClockIoctl = !ioctl(device->fd, EVIOCSCLOCKID, &clockId);
-    ALOGI("wakeMechanism=%s, usingClockIoctl=%s", wakeMechanism.string(),
+    ALOGI("wakeMechanism=%s, usingClockIoctl=%s", wakeMechanism.c_str(),
           toString(usingClockIoctl));
 }
 
@@ -1473,7 +1473,7 @@
     identifier.uniqueId = "<virtual>";
     assignDescriptorLocked(identifier);
 
-    Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier);
+    Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, "<virtual>", identifier);
     device->classes = INPUT_DEVICE_CLASS_KEYBOARD
             | INPUT_DEVICE_CLASS_ALPHAKEY
             | INPUT_DEVICE_CLASS_DPAD
@@ -1491,26 +1491,26 @@
 void EventHub::loadConfigurationLocked(Device* device) {
     device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
             device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
-    if (device->configurationFile.isEmpty()) {
+    if (device->configurationFile.empty()) {
         ALOGD("No input device configuration file found for device '%s'.",
-                device->identifier.name.string());
+                device->identifier.name.c_str());
     } else {
-        status_t status = PropertyMap::load(device->configurationFile,
+        status_t status = PropertyMap::load(String8(device->configurationFile.c_str()),
                 &device->configuration);
         if (status) {
             ALOGE("Error loading input device configuration file for device '%s'.  "
                     "Using default configuration.",
-                    device->identifier.name.string());
+                    device->identifier.name.c_str());
         }
     }
 }
 
 status_t EventHub::loadVirtualKeyMapLocked(Device* device) {
     // The virtual key map is supplied by the kernel as a system board property file.
-    String8 path;
-    path.append("/sys/board_properties/virtualkeys.");
-    path.append(device->identifier.name);
-    if (access(path.string(), R_OK)) {
+    std::string path;
+    path += "/sys/board_properties/virtualkeys.";
+    path += device->identifier.name;
+    if (access(path.c_str(), R_OK)) {
         return NAME_NOT_FOUND;
     }
     return VirtualKeyMap::load(path, &device->virtualKeyMap);
@@ -1543,7 +1543,7 @@
 int32_t EventHub::getNextControllerNumberLocked(Device* device) {
     if (mControllerNumbers.isFull()) {
         ALOGI("Maximum number of controllers reached, assigning controller number 0 to device %s",
-                device->identifier.name.string());
+                device->identifier.name.c_str());
         return 0;
     }
     // Since the controller number 0 is reserved for non-controllers, translate all numbers up by
@@ -1617,12 +1617,12 @@
 
 void EventHub::closeDeviceLocked(Device* device) {
     ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
-         device->path.string(), device->identifier.name.string(), device->id,
+         device->path.c_str(), device->identifier.name.c_str(), device->id,
          device->fd, device->classes);
 
     if (device->id == mBuiltInKeyboardId) {
         ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
-                device->path.string(), mBuiltInKeyboardId);
+                device->path.c_str(), mBuiltInKeyboardId);
         mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD;
     }
 
@@ -1648,7 +1648,7 @@
         // Unlink the device from the opening devices list then delete it.
         // We don't need to tell the client that the device was closed because
         // it does not even know it was opened in the first place.
-        ALOGI("Device %s was immediately closed after opening.", device->path.string());
+        ALOGI("Device %s was immediately closed after opening.", device->path.c_str());
         if (pred) {
             pred->next = device->next;
         } else {
@@ -1750,28 +1750,28 @@
             const Device* device = mDevices.valueAt(i);
             if (mBuiltInKeyboardId == device->id) {
                 dump += StringPrintf(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n",
-                        device->id, device->identifier.name.string());
+                        device->id, device->identifier.name.c_str());
             } else {
                 dump += StringPrintf(INDENT2 "%d: %s\n", device->id,
-                        device->identifier.name.string());
+                        device->identifier.name.c_str());
             }
             dump += StringPrintf(INDENT3 "Classes: 0x%08x\n", device->classes);
-            dump += StringPrintf(INDENT3 "Path: %s\n", device->path.string());
+            dump += StringPrintf(INDENT3 "Path: %s\n", device->path.c_str());
             dump += StringPrintf(INDENT3 "Enabled: %s\n", toString(device->enabled));
-            dump += StringPrintf(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string());
-            dump += StringPrintf(INDENT3 "Location: %s\n", device->identifier.location.string());
+            dump += StringPrintf(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.c_str());
+            dump += StringPrintf(INDENT3 "Location: %s\n", device->identifier.location.c_str());
             dump += StringPrintf(INDENT3 "ControllerNumber: %d\n", device->controllerNumber);
-            dump += StringPrintf(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string());
+            dump += StringPrintf(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.c_str());
             dump += StringPrintf(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
                     "product=0x%04x, version=0x%04x\n",
                     device->identifier.bus, device->identifier.vendor,
                     device->identifier.product, device->identifier.version);
             dump += StringPrintf(INDENT3 "KeyLayoutFile: %s\n",
-                    device->keyMap.keyLayoutFile.string());
+                    device->keyMap.keyLayoutFile.c_str());
             dump += StringPrintf(INDENT3 "KeyCharacterMapFile: %s\n",
-                    device->keyMap.keyCharacterMapFile.string());
+                    device->keyMap.keyCharacterMapFile.c_str());
             dump += StringPrintf(INDENT3 "ConfigurationFile: %s\n",
-                    device->configurationFile.string());
+                    device->configurationFile.c_str());
             dump += StringPrintf(INDENT3 "HaveKeyboardLayoutOverlay: %s\n",
                     toString(device->overlayKeyMap != nullptr));
         }
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
index dfe3def..ea663b7 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -18,6 +18,8 @@
 #ifndef _RUNTIME_EVENT_HUB_H
 #define _RUNTIME_EVENT_HUB_H
 
+#include <vector>
+
 #include <input/Input.h>
 #include <input/InputDevice.h>
 #include <input/Keyboard.h>
@@ -29,7 +31,6 @@
 #include <utils/List.h>
 #include <utils/Errors.h>
 #include <utils/PropertyMap.h>
-#include <utils/Vector.h>
 #include <utils/KeyedVector.h>
 #include <utils/BitSet.h>
 
@@ -207,7 +208,7 @@
 
     // Sets devices that are excluded from opening.
     // This can be used to ignore input devices for sensors.
-    virtual void setExcludedDevices(const Vector<String8>& devices) = 0;
+    virtual void setExcludedDevices(const std::vector<std::string>& devices) = 0;
 
     /*
      * Wait for events to become available and returns them.
@@ -303,7 +304,7 @@
     virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
             AxisInfo* outAxisInfo) const;
 
-    virtual void setExcludedDevices(const Vector<String8>& devices);
+    virtual void setExcludedDevices(const std::vector<std::string>& devices);
 
     virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
     virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
@@ -344,7 +345,7 @@
 
         int fd; // may be -1 if device is closed
         const int32_t id;
-        const String8 path;
+        const std::string path;
         const InputDeviceIdentifier identifier;
 
         uint32_t classes;
@@ -357,7 +358,7 @@
         uint8_t ffBitmask[(FF_MAX + 1) / 8];
         uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8];
 
-        String8 configurationFile;
+        std::string configurationFile;
         PropertyMap* configuration;
         VirtualKeyMap* virtualKeyMap;
         KeyMap keyMap;
@@ -373,7 +374,8 @@
         int32_t timestampOverrideSec;
         int32_t timestampOverrideUsec;
 
-        Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
+        Device(int fd, int32_t id, const std::string& path,
+                const InputDeviceIdentifier& identifier);
         ~Device();
 
         void close();
@@ -413,7 +415,7 @@
     void scanDevicesLocked();
     status_t readNotifyLocked();
 
-    Device* getDeviceByDescriptorLocked(String8& descriptor) const;
+    Device* getDeviceByDescriptorLocked(const std::string& descriptor) const;
     Device* getDeviceLocked(int32_t deviceId) const;
     Device* getDeviceByPathLocked(const char* devicePath) const;
 
@@ -457,7 +459,7 @@
     bool mNeedToSendFinishedDeviceScan;
     bool mNeedToReopenDevices;
     bool mNeedToScanDevices;
-    Vector<String8> mExcludedDevices;
+    std::vector<std::string> mExcludedDevices;
 
     int mEpollFd;
     int mINotifyFd;
diff --git a/services/inputflinger/InputApplication.h b/services/inputflinger/InputApplication.h
index 724fc2c..9b365b9 100644
--- a/services/inputflinger/InputApplication.h
+++ b/services/inputflinger/InputApplication.h
@@ -17,6 +17,8 @@
 #ifndef _UI_INPUT_APPLICATION_H
 #define _UI_INPUT_APPLICATION_H
 
+#include <string>
+
 #include <input/Input.h>
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index a213b2d..92e0af2 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -31,7 +31,6 @@
 #include <utils/Vector.h>
 #include <utils/Timers.h>
 #include <utils/RefBase.h>
-#include <utils/String8.h>
 
 namespace android {
 
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index a4f83b7..8f12129 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -257,11 +257,12 @@
 // --- InputReaderConfiguration ---
 
 bool InputReaderConfiguration::getDisplayViewport(ViewportType viewportType,
-        const String8* uniqueDisplayId, DisplayViewport* outViewport) const {
+        const std::string& uniqueDisplayId, DisplayViewport* outViewport) const {
     const DisplayViewport* viewport = nullptr;
-    if (viewportType == ViewportType::VIEWPORT_VIRTUAL && uniqueDisplayId != nullptr) {
+    if (viewportType == ViewportType::VIEWPORT_VIRTUAL && !uniqueDisplayId.empty()) {
+
         for (const DisplayViewport& currentViewport : mVirtualDisplays) {
-            if (currentViewport.uniqueId == *uniqueDisplayId) {
+            if (currentViewport.uniqueId == uniqueDisplayId) {
                 viewport = &currentViewport;
                 break;
             }
@@ -473,10 +474,10 @@
 
     if (device->isIgnored()) {
         ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
-                identifier.name.string());
+                identifier.name.c_str());
     } else {
         ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
-                identifier.name.string(), device->getSources());
+                identifier.name.c_str(), device->getSources());
     }
 
     mDevices.add(deviceId, device);
@@ -501,10 +502,10 @@
 
     if (device->isIgnored()) {
         ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
-                device->getId(), device->getName().string());
+                device->getId(), device->getName().c_str());
     } else {
         ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
-                device->getId(), device->getName().string(), device->getSources());
+                device->getId(), device->getName().c_str(), device->getSources());
     }
 
     if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
@@ -687,7 +688,7 @@
     if (now < mDisableVirtualKeysTimeout) {
         ALOGI("Dropping virtual key from device %s because virtual keys are "
                 "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
-                device->getName().string(),
+                device->getName().c_str(),
                 (mDisableVirtualKeysTimeout - now) * 0.000001,
                 keyCode, scanCode);
         return true;
@@ -894,7 +895,7 @@
         if (i != 0) {
             dump += ", ";
         }
-        dump += mConfig.excludedDeviceNames.itemAt(i).string();
+        dump += mConfig.excludedDeviceNames[i];
     }
     dump += "]\n";
     dump += StringPrintf(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
@@ -1077,7 +1078,7 @@
     getDeviceInfo(& deviceInfo);
 
     dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
-            deviceInfo.getDisplayName().string());
+            deviceInfo.getDisplayName().c_str());
     dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
     dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
     dump += StringPrintf(INDENT2 "HasMic:     %s\n", toString(mHasMic));
@@ -1135,7 +1136,7 @@
 
         if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
             if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
-                String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
+                std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
                 if (mAlias != alias) {
                     mAlias = alias;
                     bumpGeneration();
@@ -1196,7 +1197,7 @@
 #endif
             }
         } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
-            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
+            ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
             mDropUntilNextSync = true;
             reset(rawEvent->when);
         } else {
@@ -2294,7 +2295,7 @@
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
         if (mParameters.orientationAware) {
             DisplayViewport dvp;
-            config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, nullptr, &dvp);
+            config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, "", &dvp);
             mViewport = dvp;
         }
     }
@@ -2464,7 +2465,7 @@
             // key was not actually down
             ALOGI("Dropping key up from device %s because the key was not down.  "
                     "keyCode=%d, scanCode=%d",
-                    getDeviceName().string(), keyCode, scanCode);
+                    getDeviceName().c_str(), keyCode, scanCode);
             return;
         }
     }
@@ -2705,7 +2706,7 @@
         mOrientation = DISPLAY_ORIENTATION_0;
         if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
             DisplayViewport v;
-            if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, nullptr, &v)) {
+            if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, "", &v)) {
                 mOrientation = v.orientation;
             }
         }
@@ -3020,7 +3021,7 @@
     }
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
         DisplayViewport v;
-        if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, nullptr, &v)) {
+        if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, "", &v)) {
             mOrientation = v.orientation;
         } else {
             mOrientation = DISPLAY_ORIENTATION_0;
@@ -3394,8 +3395,10 @@
         mParameters.hasAssociatedDisplay = true;
         if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
             mParameters.associatedDisplayIsExternal = getDevice()->isExternal();
+            String8 uniqueDisplayId;
             getDevice()->getConfiguration().tryGetProperty(String8("touch.displayId"),
-                    mParameters.uniqueDisplayId);
+                    uniqueDisplayId);
+            mParameters.uniqueDisplayId = uniqueDisplayId.c_str();
         }
     }
 
@@ -3506,7 +3509,7 @@
     // Ensure we have valid X and Y axes.
     if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
         ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
-                "The device will be inoperable.", getDeviceName().string());
+                "The device will be inoperable.", getDeviceName().c_str());
         mDeviceMode = DEVICE_MODE_DISABLED;
         return;
     }
@@ -3518,15 +3521,15 @@
     // Get associated display dimensions.
     DisplayViewport newViewport;
     if (mParameters.hasAssociatedDisplay) {
-        const String8* uniqueDisplayId = nullptr;
+        std::string uniqueDisplayId;
         ViewportType viewportTypeToUse;
 
         if (mParameters.associatedDisplayIsExternal) {
             viewportTypeToUse = ViewportType::VIEWPORT_EXTERNAL;
-        } else if (!mParameters.uniqueDisplayId.isEmpty()) {
+        } else if (!mParameters.uniqueDisplayId.empty()) {
             // If the IDC file specified a unique display Id, then it expects to be linked to a
             // virtual display with the same unique ID.
-            uniqueDisplayId = &mParameters.uniqueDisplayId;
+            uniqueDisplayId = mParameters.uniqueDisplayId;
             viewportTypeToUse = ViewportType::VIEWPORT_VIRTUAL;
         } else {
             viewportTypeToUse = ViewportType::VIEWPORT_INTERNAL;
@@ -3536,7 +3539,7 @@
             ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
                     "display.  The device will be inoperable until the display size "
                     "becomes available.",
-                    getDeviceName().string());
+                    getDeviceName().c_str());
             mDeviceMode = DEVICE_MODE_DISABLED;
             return;
         }
@@ -3642,7 +3645,7 @@
     if (viewportChanged || deviceModeChanged) {
         ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
                 "display id %d",
-                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
+                getDeviceId(), getDeviceName().c_str(), mSurfaceWidth, mSurfaceHeight,
                 mSurfaceOrientation, mDeviceMode, mViewport.displayId);
 
         // Configure X and Y factors.
@@ -6925,7 +6928,7 @@
 #if DEBUG_POINTERS
             ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
                     "ignoring the rest.",
-                    getDeviceName().string(), MAX_POINTERS);
+                    getDeviceName().c_str(), MAX_POINTERS);
 #endif
             break; // too many fingers!
         }
@@ -7016,7 +7019,7 @@
         if (slotCount > MAX_SLOTS) {
             ALOGW("MultiTouch Device %s reported %zu slots but the framework "
                     "only supports a maximum of %zu slots at this time.",
-                    getDeviceName().string(), slotCount, MAX_SLOTS);
+                    getDeviceName().c_str(), slotCount, MAX_SLOTS);
             slotCount = MAX_SLOTS;
         }
         mMultiTouchMotionAccumulator.configure(getDevice(),
@@ -7259,7 +7262,7 @@
         // Prefer to keep explicitly mapped axes.
         if (mAxes.size() > PointerCoords::MAX_AXES) {
             ALOGI("Joystick '%s' has %zu axes but the framework only supports a maximum of %d.",
-                    getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
+                    getDeviceName().c_str(), mAxes.size(), PointerCoords::MAX_AXES);
             pruneAxes(true);
             pruneAxes(false);
         }
@@ -7281,7 +7284,7 @@
                 } else {
                     ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
                             "have already been assigned to other axes.",
-                            getDeviceName().string(), mAxes.keyAt(i));
+                            getDeviceName().c_str(), mAxes.keyAt(i));
                     mAxes.removeItemsAt(i--);
                     numAxes -= 1;
                 }
@@ -7310,7 +7313,7 @@
             continue;
         }
         ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
-                getDeviceName().string(), mAxes.keyAt(i));
+                getDeviceName().c_str(), mAxes.keyAt(i));
         mAxes.removeItemsAt(i);
     }
 }
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index af26b4f..c06168d 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -101,7 +101,7 @@
 
     // The excluded device names for the platform.
     // Devices with these names will be ignored.
-    Vector<String8> excludedDeviceNames;
+    std::vector<std::string> excludedDeviceNames;
 
     // Velocity control parameters for mouse pointer movements.
     VelocityControlParameters pointerVelocityControlParameters;
@@ -201,7 +201,7 @@
             pointerGestureZoomSpeedRatio(0.3f),
             showTouches(false) { }
 
-    bool getDisplayViewport(ViewportType viewportType, const String8* displayId,
+    bool getDisplayViewport(ViewportType viewportType, const std::string& uniqueDisplayId,
             DisplayViewport* outViewport) const;
     void setPhysicalDisplayViewport(ViewportType viewportType, const DisplayViewport& viewport);
     void setVirtualDisplayViewports(const Vector<DisplayViewport>& viewports);
@@ -274,11 +274,11 @@
             const InputDeviceIdentifier& identifier) = 0;
 
     /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
-    virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
+    virtual std::string getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
 
     /* Gets the affine calibration associated with the specified device. */
     virtual TouchAffineTransformation getTouchAffineTransformation(
-            const String8& inputDeviceDescriptor, int32_t surfaceRotation) = 0;
+            const std::string& inputDeviceDescriptor, int32_t surfaceRotation) = 0;
 };
 
 
@@ -553,8 +553,8 @@
     inline int32_t getId() const { return mId; }
     inline int32_t getControllerNumber() const { return mControllerNumber; }
     inline int32_t getGeneration() const { return mGeneration; }
-    inline const String8& getName() const { return mIdentifier.name; }
-    inline const String8& getDescriptor() { return mIdentifier.descriptor; }
+    inline const std::string getName() const { return mIdentifier.name; }
+    inline const std::string getDescriptor() { return mIdentifier.descriptor; }
     inline uint32_t getClasses() const { return mClasses; }
     inline uint32_t getSources() const { return mSources; }
 
@@ -625,7 +625,7 @@
     int32_t mGeneration;
     int32_t mControllerNumber;
     InputDeviceIdentifier mIdentifier;
-    String8 mAlias;
+    std::string mAlias;
     uint32_t mClasses;
 
     Vector<InputMapper*> mMappers;
@@ -981,7 +981,7 @@
 
     inline InputDevice* getDevice() { return mDevice; }
     inline int32_t getDeviceId() { return mDevice->getId(); }
-    inline const String8 getDeviceName() { return mDevice->getName(); }
+    inline const std::string getDeviceName() { return mDevice->getName(); }
     inline InputReaderContext* getContext() { return mContext; }
     inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
     inline InputListenerInterface* getListener() { return mContext->getListener(); }
@@ -1309,7 +1309,7 @@
         bool associatedDisplayIsExternal;
         bool orientationAware;
         bool hasButtonUnderPad;
-        String8 uniqueDisplayId;
+        std::string uniqueDisplayId;
 
         enum GestureMode {
             GESTURE_MODE_SINGLE_TOUCH,
diff --git a/services/inputflinger/host/InputDriver.cpp b/services/inputflinger/host/InputDriver.cpp
index bd11d56..2f046c3 100644
--- a/services/inputflinger/host/InputDriver.cpp
+++ b/services/inputflinger/host/InputDriver.cpp
@@ -217,18 +217,18 @@
     idi.product = id->productId;
     idi.version = id->version;
 
-    String8 configFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
+    std::string configFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
             idi, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
-    if (configFile.isEmpty()) {
+    if (configFile.empty()) {
         ALOGD("No input device configuration file found for device '%s'.",
-                idi.name.string());
+                idi.name.c_str());
     } else {
         auto propMap = new input_property_map_t();
-        status_t status = PropertyMap::load(configFile, &propMap->propertyMap);
+        status_t status = PropertyMap::load(String8(configFile.c_str()), &propMap->propertyMap);
         if (status) {
             ALOGE("Error loading input device configuration file for device '%s'. "
                     "Using default configuration.",
-                    idi.name.string());
+                    idi.name.c_str());
             delete propMap;
             return nullptr;
         }
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 286cf88..9b985dc 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -142,7 +142,7 @@
     }
 
     void setDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
-            const String8& uniqueId) {
+            const std::string& uniqueId) {
         DisplayViewport v = createDisplayViewport(displayId, width, height, orientation, uniqueId);
         // Set the size of both the internal and external display at the same time.
         mConfig.setPhysicalDisplayViewport(ViewportType::VIEWPORT_INTERNAL, v);
@@ -150,14 +150,14 @@
     }
 
     void setVirtualDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
-            const String8& uniqueId) {
+            const std::string& uniqueId) {
         Vector<DisplayViewport> viewports;
         viewports.push_back(createDisplayViewport(displayId, width, height, orientation, uniqueId));
         mConfig.setVirtualDisplayViewports(viewports);
     }
 
-    void addExcludedDeviceName(const String8& deviceName) {
-        mConfig.excludedDeviceNames.push(deviceName);
+    void addExcludedDeviceName(const std::string& deviceName) {
+        mConfig.excludedDeviceNames.push_back(deviceName);
     }
 
     void addDisabledDevice(int32_t deviceId) {
@@ -188,7 +188,7 @@
         return mInputDevices;
     }
 
-    TouchAffineTransformation getTouchAffineTransformation(const String8& inputDeviceDescriptor,
+    TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
             int32_t surfaceRotation) {
         return transform;
     }
@@ -203,7 +203,7 @@
 
 private:
     DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height,
-            int32_t orientation, const String8& uniqueId) {
+            int32_t orientation, const std::string& uniqueId) {
         bool isRotated = (orientation == DISPLAY_ORIENTATION_90
                 || orientation == DISPLAY_ORIENTATION_270);
         DisplayViewport v;
@@ -239,8 +239,8 @@
         return nullptr;
     }
 
-    virtual String8 getDeviceAlias(const InputDeviceIdentifier&) {
-        return String8::empty();
+    virtual std::string getDeviceAlias(const InputDeviceIdentifier&) {
+        return "";
     }
 };
 
@@ -392,7 +392,7 @@
     };
 
     KeyedVector<int32_t, Device*> mDevices;
-    Vector<String8> mExcludedDevices;
+    std::vector<std::string> mExcludedDevices;
     List<RawEvent> mEvents;
 
 protected:
@@ -405,7 +405,7 @@
 public:
     FakeEventHub() { }
 
-    void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+    void addDevice(int32_t deviceId, const std::string& name, uint32_t classes) {
         Device* device = new Device(classes);
         device->identifier.name = name;
         mDevices.add(deviceId, device);
@@ -534,7 +534,7 @@
         return device->leds.valueFor(led);
     }
 
-    Vector<String8>& getExcludedDevices() {
+    std::vector<std::string>& getExcludedDevices() {
         return mExcludedDevices;
     }
 
@@ -566,7 +566,7 @@
 private:
     Device* getDevice(int32_t deviceId) const {
         ssize_t index = mDevices.indexOfKey(deviceId);
-        return index >= 0 ? mDevices.valueAt(index) : NULL;
+        return index >= 0 ? mDevices.valueAt(index) : nullptr;
     }
 
     virtual uint32_t getDeviceClasses(int32_t deviceId) const {
@@ -658,7 +658,7 @@
         return NAME_NOT_FOUND;
     }
 
-    virtual void setExcludedDevices(const Vector<String8>& devices) {
+    virtual void setExcludedDevices(const std::vector<std::string>& devices) {
         mExcludedDevices = devices;
     }
 
@@ -1052,7 +1052,7 @@
         mNextDevice = device;
     }
 
-    InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const String8& name,
+    InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const std::string& name,
             uint32_t classes) {
         InputDeviceIdentifier identifier;
         identifier.name = name;
@@ -1101,7 +1101,7 @@
         mFakeEventHub.clear();
     }
 
-    void addDevice(int32_t deviceId, const String8& name, uint32_t classes,
+    void addDevice(int32_t deviceId, const std::string& name, uint32_t classes,
             const PropertyMap* configuration) {
         mFakeEventHub->addDevice(deviceId, name, classes);
 
@@ -1129,7 +1129,7 @@
     }
 
     FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber,
-            const String8& name, uint32_t classes, uint32_t sources,
+            const std::string& name, uint32_t classes, uint32_t sources,
             const PropertyMap* configuration) {
         InputDevice* device = mReader->newDevice(deviceId, controllerNumber, name, classes);
         FakeInputMapper* mapper = new FakeInputMapper(device, sources);
@@ -1141,17 +1141,18 @@
 };
 
 TEST_F(InputReaderTest, GetInputDevices) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
+    ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard",
             INPUT_DEVICE_CLASS_KEYBOARD, nullptr));
-    ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("ignored"),
+    ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored",
             0, nullptr)); // no classes so device will be ignored
 
+
     Vector<InputDeviceInfo> inputDevices;
     mReader->getInputDevices(inputDevices);
 
     ASSERT_EQ(1U, inputDevices.size());
     ASSERT_EQ(1, inputDevices[0].getId());
-    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
+    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
     ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
@@ -1160,7 +1161,7 @@
     inputDevices = mFakePolicy->getInputDevices();
     ASSERT_EQ(1U, inputDevices.size());
     ASSERT_EQ(1, inputDevices[0].getId());
-    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
+    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
     ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
@@ -1169,12 +1170,12 @@
 TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
     constexpr int32_t deviceId = 1;
     constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
-    InputDevice* device = mReader->newDevice(deviceId, 0, String8("fake"), deviceClass);
+    InputDevice* device = mReader->newDevice(deviceId, 0, "fake", deviceClass);
     // Must add at least one mapper or the device will be ignored!
     FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD);
     device->addMapper(mapper);
     mReader->setNextDevice(device);
-    addDevice(deviceId, String8("fake"), deviceClass, nullptr);
+    addDevice(deviceId, "fake", deviceClass, nullptr);
 
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
 
@@ -1208,7 +1209,7 @@
 
 TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = nullptr;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake",
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr));
     mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
 
@@ -1235,7 +1236,7 @@
 
 TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = nullptr;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake",
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr));
     mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN);
 
@@ -1262,7 +1263,7 @@
 
 TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = nullptr;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake",
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr));
     mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN);
 
@@ -1289,8 +1290,9 @@
 
 TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = nullptr;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake",
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr));
+
     mapper->addSupportedKeyCode(AKEYCODE_A);
     mapper->addSupportedKeyCode(AKEYCODE_B);
 
@@ -1323,7 +1325,7 @@
 }
 
 TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
-    addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD, nullptr);
+    addDevice(1, "ignored", INPUT_DEVICE_CLASS_KEYBOARD, nullptr);
 
     NotifyConfigurationChangedArgs args;
 
@@ -1333,7 +1335,7 @@
 
 TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
     FakeInputMapper* mapper = nullptr;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake",
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr));
 
     mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1);
@@ -1373,7 +1375,7 @@
         mFakeListener = new FakeInputListener();
         mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
 
-        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
+        mFakeEventHub->addDevice(DEVICE_ID, DEVICE_NAME, 0);
         InputDeviceIdentifier identifier;
         identifier.name = DEVICE_NAME;
         mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
@@ -1399,7 +1401,7 @@
 
 TEST_F(InputDeviceTest, ImmutableProperties) {
     ASSERT_EQ(DEVICE_ID, mDevice->getId());
-    ASSERT_STREQ(DEVICE_NAME, mDevice->getName());
+    ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
     ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses());
 }
 
@@ -1427,7 +1429,7 @@
     InputDeviceInfo info;
     mDevice->getDeviceInfo(&info);
     ASSERT_EQ(DEVICE_ID, info.getId());
-    ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string());
+    ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
     ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
 
@@ -1497,7 +1499,7 @@
     InputDeviceInfo info;
     mDevice->getDeviceInfo(&info);
     ASSERT_EQ(DEVICE_ID, info.getId());
-    ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string());
+    ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
     ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
 
@@ -1570,7 +1572,7 @@
         mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
                 DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
 
-        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
+        mFakeEventHub->addDevice(DEVICE_ID, DEVICE_NAME, 0);
     }
 
     virtual void TearDown() {
@@ -1597,12 +1599,12 @@
 
     void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
             int32_t orientation) {
-        mFakePolicy->setDisplayViewport(displayId, width, height, orientation, String8::empty());
+        mFakePolicy->setDisplayViewport(displayId, width, height, orientation, "");
         configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
     }
 
     void setVirtualDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
-            int32_t orientation, const String8& uniqueId) {
+            int32_t orientation, const std::string& uniqueId) {
         mFakePolicy->setVirtualDisplayViewport(displayId, width, height, orientation, uniqueId);
         configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
     }
@@ -3048,7 +3050,7 @@
 
 void TouchInputMapperTest::prepareVirtualDisplay(int32_t orientation) {
     setVirtualDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
-        VIRTUAL_DISPLAY_HEIGHT, orientation, String8(VIRTUAL_DISPLAY_UNIQUE_ID));
+        VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID);
 }
 
 void TouchInputMapperTest::prepareVirtualKeys() {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index a7c08cf..bb85f4c 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -29,8 +29,15 @@
 
 namespace android {
 
+#define RETURN_VALUE_IF_INVALID(value) \
+    if (handle == nullptr || mConnections.count(handle->id) == 0) return value
+#define RETURN_IF_INVALID() \
+    if (handle == nullptr || mConnections.count(handle->id) == 0) return
+
 std::atomic<int64_t> Scheduler::sNextId = 0;
 
+Scheduler::~Scheduler() = default;
+
 sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
         const char* connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
         impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
@@ -38,11 +45,9 @@
     const int64_t id = sNextId++;
     ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
 
-    std::unique_ptr<VSyncSource> eventThreadSource =
-            std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, connectionName);
     std::unique_ptr<EventThread> eventThread =
-            std::make_unique<impl::EventThread>(std::move(eventThreadSource), resyncCallback,
-                                                interceptCallback, connectionName);
+            makeEventThread(connectionName, dispSync, phaseOffsetNs, resyncCallback,
+                            interceptCallback);
     auto connection = std::make_unique<Connection>(new ConnectionHandle(id),
                                                    eventThread->createEventConnection(),
                                                    std::move(eventThread));
@@ -50,56 +55,55 @@
     return mConnections[id]->handle;
 }
 
+std::unique_ptr<EventThread> Scheduler::makeEventThread(
+        const char* connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
+        impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
+        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
+    std::unique_ptr<VSyncSource> eventThreadSource =
+            std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, connectionName);
+    return std::make_unique<impl::EventThread>(std::move(eventThreadSource), resyncCallback,
+                                               interceptCallback, connectionName);
+}
+
 sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
         const sp<Scheduler::ConnectionHandle>& handle) {
-    if (mConnections.count(handle->id) != 0) {
-        return mConnections[handle->id]->thread->createEventConnection();
-    }
-    return nullptr;
+    RETURN_VALUE_IF_INVALID(nullptr);
+    return mConnections[handle->id]->thread->createEventConnection();
 }
 
 EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& handle) {
-    if (mConnections.count(handle->id) != 0) {
-        return mConnections[handle->id]->thread.get();
-    }
-    return nullptr;
+    RETURN_VALUE_IF_INVALID(nullptr);
+    return mConnections[handle->id]->thread.get();
 }
 
 sp<BnDisplayEventConnection> Scheduler::getEventConnection(const sp<ConnectionHandle>& handle) {
-    if (mConnections.find(handle->id) != mConnections.end()) {
-        return mConnections[handle->id]->eventConnection;
-    }
-    return nullptr;
+    RETURN_VALUE_IF_INVALID(nullptr);
+    return mConnections[handle->id]->eventConnection;
 }
 
 void Scheduler::hotplugReceived(const sp<Scheduler::ConnectionHandle>& handle,
                                 EventThread::DisplayType displayType, bool connected) {
-    if (mConnections.find(handle->id) != mConnections.end()) {
-        mConnections[handle->id]->thread->onHotplugReceived(displayType, connected);
-    }
+    RETURN_IF_INVALID();
+    mConnections[handle->id]->thread->onHotplugReceived(displayType, connected);
 }
 
 void Scheduler::onScreenAcquired(const sp<Scheduler::ConnectionHandle>& handle) {
-    if (mConnections.find(handle->id) != mConnections.end()) {
-        mConnections[handle->id]->thread->onScreenAcquired();
-    }
+    RETURN_IF_INVALID();
+    mConnections[handle->id]->thread->onScreenAcquired();
 }
 
 void Scheduler::onScreenReleased(const sp<Scheduler::ConnectionHandle>& handle) {
-    if (mConnections.find(handle->id) != mConnections.end()) {
-        mConnections[handle->id]->thread->onScreenReleased();
-    }
+    RETURN_IF_INVALID();
+    mConnections[handle->id]->thread->onScreenReleased();
 }
 
 void Scheduler::dump(const sp<Scheduler::ConnectionHandle>& handle, String8& result) const {
-    if (mConnections.find(handle->id) != mConnections.end()) {
-        mConnections.at(handle->id)->thread->dump(result);
-    }
+    RETURN_IF_INVALID();
+    mConnections.at(handle->id)->thread->dump(result);
 }
 
 void Scheduler::setPhaseOffset(const sp<Scheduler::ConnectionHandle>& handle, nsecs_t phaseOffset) {
-    if (mConnections.find(handle->id) != mConnections.end()) {
-        mConnections[handle->id]->thread->setPhaseOffset(phaseOffset);
-    }
+    RETURN_IF_INVALID();
+    mConnections[handle->id]->thread->setPhaseOffset(phaseOffset);
 }
 } // namespace android
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index caccd6f..8efbff4 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -52,7 +52,7 @@
     };
 
     Scheduler() = default;
-    ~Scheduler() = default;
+    virtual ~Scheduler();
 
     /** Creates an EventThread connection. */
     sp<ConnectionHandle> createConnection(
@@ -77,6 +77,12 @@
     // Offers ability to modify phase offset in the event thread.
     void setPhaseOffset(const sp<ConnectionHandle>& handle, nsecs_t phaseOffset);
 
+protected:
+    virtual std::unique_ptr<EventThread> makeEventThread(
+            const char* connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
+            impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
+            impl::EventThread::InterceptVSyncsCallback interceptCallback);
+
 private:
     static std::atomic<int64_t> sNextId;
     std::unordered_map<int64_t, std::unique_ptr<Connection>> mConnections;
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 8f1f5e5..f1f0fbf 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -22,6 +22,7 @@
         "DisplayTransactionTest.cpp",
         "EventControlThreadTest.cpp",
         "EventThreadTest.cpp",
+        "SchedulerTest.cpp",
         "mock/DisplayHardware/MockComposer.cpp",
         "mock/DisplayHardware/MockDisplaySurface.cpp",
         "mock/DisplayHardware/MockPowerAdvisor.cpp",
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
new file mode 100644
index 0000000..c809e82
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -0,0 +1,186 @@
+#undef LOG_TAG
+#define LOG_TAG "SchedulerUnittests"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <log/log.h>
+
+#include "AsyncCallRecorder.h"
+#include "Scheduler/DispSync.h"
+#include "Scheduler/EventThread.h"
+#include "Scheduler/Scheduler.h"
+#include "mock/MockDispSync.h"
+#include "mock/MockEventThread.h"
+
+using testing::_;
+using testing::Return;
+
+namespace android {
+
+class SchedulerTest : public testing::Test {
+protected:
+    class MockEventThreadConnection : public BnDisplayEventConnection {
+    public:
+        MockEventThreadConnection() = default;
+        ~MockEventThreadConnection() = default;
+
+        MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel));
+        MOCK_METHOD1(setVsyncRate, status_t(uint32_t count));
+        MOCK_METHOD0(requestNextVsync, void());
+    };
+
+    /**
+     * This mock Scheduler class uses implementation of mock::EventThread but keeps everything else
+     * the same.
+     */
+    class MockScheduler : public android::Scheduler {
+    public:
+        MockScheduler(std::unique_ptr<EventThread> eventThread)
+              : mEventThread(std::move(eventThread)) {}
+
+        std::unique_ptr<EventThread> makeEventThread(
+                const char* /* connectionName */, DispSync* /* dispSync */,
+                nsecs_t /* phaseOffsetNs */,
+                impl::EventThread::ResyncWithRateLimitCallback /* resyncCallback */,
+                impl::EventThread::InterceptVSyncsCallback /* interceptCallback */) override {
+            return std::move(mEventThread);
+        }
+
+        MockScheduler() = default;
+        ~MockScheduler() override = default;
+
+        std::unique_ptr<EventThread> mEventThread;
+    };
+
+    SchedulerTest();
+    ~SchedulerTest() override;
+
+    sp<Scheduler::ConnectionHandle> mConnectionHandle;
+    mock::DispSync* mPrimaryDispSync = new mock::DispSync();
+    mock::EventThread* mEventThread;
+    std::unique_ptr<MockScheduler> mScheduler;
+    sp<MockEventThreadConnection> mEventThreadConnection;
+
+    AsyncCallRecorder<void (*)()> mResyncCallRecorder;
+    AsyncCallRecorder<void (*)(nsecs_t)> mInterceptVSyncCallRecorder;
+};
+
+SchedulerTest::SchedulerTest() {
+    const ::testing::TestInfo* const test_info =
+            ::testing::UnitTest::GetInstance()->current_test_info();
+    ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+
+    std::unique_ptr<mock::EventThread> eventThread = std::make_unique<mock::EventThread>();
+    mEventThread = eventThread.get();
+    mScheduler = std::make_unique<MockScheduler>(std::move(eventThread));
+    mEventThreadConnection = new MockEventThreadConnection();
+
+    // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
+    // sure that call gets executed and returns an EventThread::Connection object.
+    EXPECT_CALL(*mEventThread, createEventConnection())
+            .WillRepeatedly(Return(mEventThreadConnection));
+
+    mConnectionHandle = mScheduler->createConnection("appConnection", mPrimaryDispSync, 16,
+                                                     mResyncCallRecorder.getInvocable(),
+                                                     mInterceptVSyncCallRecorder.getInvocable());
+}
+
+SchedulerTest::~SchedulerTest() {
+    const ::testing::TestInfo* const test_info =
+            ::testing::UnitTest::GetInstance()->current_test_info();
+    ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
+}
+
+namespace {
+/* ------------------------------------------------------------------------
+ * Test cases
+ */
+TEST_F(SchedulerTest, canCreateAndDestroyTest) {
+    EXPECT_FALSE(mResyncCallRecorder.waitForCall().has_value());
+    EXPECT_FALSE(mInterceptVSyncCallRecorder.waitForCall().has_value());
+    EXPECT_EQ(0, mConnectionHandle->id);
+}
+
+TEST_F(SchedulerTest, testNullPtr) {
+    // Passing a null pointer for ConnectionHandle is a valid argument. The code doesn't throw any
+    // exceptions, just gracefully continues.
+    sp<IDisplayEventConnection> returnedValue;
+    ASSERT_NO_FATAL_FAILURE(returnedValue = mScheduler->createDisplayEventConnection(nullptr));
+    EXPECT_TRUE(returnedValue == nullptr);
+    EXPECT_TRUE(mScheduler->getEventThread(nullptr) == nullptr);
+    EXPECT_TRUE(mScheduler->getEventConnection(nullptr) == nullptr);
+    ASSERT_NO_FATAL_FAILURE(
+            mScheduler->hotplugReceived(nullptr, EventThread::DisplayType::Primary, false));
+    ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(nullptr));
+    ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(nullptr));
+    String8 testString;
+    ASSERT_NO_FATAL_FAILURE(mScheduler->dump(nullptr, testString));
+    EXPECT_TRUE(testString == "");
+    ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(nullptr, 10));
+}
+
+TEST_F(SchedulerTest, invalidConnectionHandle) {
+    // Passing an invalid ConnectionHandle is a valid argument. The code doesn't throw any
+    // exceptions, just gracefully continues.
+    sp<Scheduler::ConnectionHandle> connectionHandle = new Scheduler::ConnectionHandle(20);
+
+    sp<IDisplayEventConnection> returnedValue;
+    ASSERT_NO_FATAL_FAILURE(returnedValue =
+                                    mScheduler->createDisplayEventConnection(connectionHandle));
+    EXPECT_TRUE(returnedValue == nullptr);
+    EXPECT_TRUE(mScheduler->getEventThread(connectionHandle) == nullptr);
+    EXPECT_TRUE(mScheduler->getEventConnection(connectionHandle) == nullptr);
+
+    // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
+    EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(connectionHandle,
+                                                        EventThread::DisplayType::Primary, false));
+
+    EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(0);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(connectionHandle));
+
+    EXPECT_CALL(*mEventThread, onScreenReleased()).Times(0);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(connectionHandle));
+
+    String8 testString;
+    EXPECT_CALL(*mEventThread, dump(_)).Times(0);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->dump(connectionHandle, testString));
+    EXPECT_TRUE(testString == "");
+
+    EXPECT_CALL(*mEventThread, setPhaseOffset(_)).Times(0);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(connectionHandle, 10));
+}
+
+TEST_F(SchedulerTest, validConnectionHandle) {
+    sp<IDisplayEventConnection> returnedValue;
+    ASSERT_NO_FATAL_FAILURE(returnedValue =
+                                    mScheduler->createDisplayEventConnection(mConnectionHandle));
+    EXPECT_TRUE(returnedValue != nullptr);
+    ASSERT_EQ(returnedValue, mEventThreadConnection);
+
+    EXPECT_TRUE(mScheduler->getEventThread(mConnectionHandle) != nullptr);
+    EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle) != nullptr);
+
+    EXPECT_CALL(*mEventThread, onHotplugReceived(EventThread::DisplayType::Primary, false))
+            .Times(1);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(mConnectionHandle,
+                                                        EventThread::DisplayType::Primary, false));
+
+    EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(1);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(mConnectionHandle));
+
+    EXPECT_CALL(*mEventThread, onScreenReleased()).Times(1);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(mConnectionHandle));
+
+    String8 testString("dump");
+    EXPECT_CALL(*mEventThread, dump(testString)).Times(1);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->dump(mConnectionHandle, testString));
+    EXPECT_TRUE(testString != "");
+
+    EXPECT_CALL(*mEventThread, setPhaseOffset(10)).Times(1);
+    ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(mConnectionHandle, 10));
+}
+
+} // namespace
+} // namespace android
\ No newline at end of file