Rootless GPU Debug

Add the ability to load GPU debug layers from the base
directory of debuggable applications.

This update concides with changes to framework/base to
control the enabling logic in GraphicsEnvironment.

This commit changes the Vulkan loader to:
* Scan an additional location for debug layers.
* Use the provided order of layers from GraphicsEnvironment,
  overriding system properties.
* Use the first instance of a layer found, in the case of duplicates.
* Move layers paths and namespace to GraphicsEnv, removing vulkan_loader_data

Bug: 63708377
Test: Manual, CTS tests to follow

Change-Id: I38dc91bbc26671f5093ee1b12454fc024c0b5892
diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp
index 05856d3..3a59208 100644
--- a/vulkan/libvulkan/layers_extensions.cpp
+++ b/vulkan/libvulkan/layers_extensions.cpp
@@ -29,11 +29,10 @@
 #include <android/dlext.h>
 #include <android-base/strings.h>
 #include <cutils/properties.h>
+#include <graphicsenv/GraphicsEnv.h>
 #include <log/log.h>
 #include <ziparchive/zip_archive.h>
 
-#include <vulkan/vulkan_loader_data.h>
-
 // TODO(jessehall): The whole way we deal with extensions is pretty hokey, and
 // not a good long-term solution. Having a hard-coded enum of extensions is
 // bad, of course. Representing sets of extensions (requested, supported, etc.)
@@ -69,11 +68,16 @@
 
 class LayerLibrary {
    public:
-    explicit LayerLibrary(const std::string& path)
-        : path_(path), dlhandle_(nullptr), refcount_(0) {}
+    explicit LayerLibrary(const std::string& path,
+                          const std::string& filename)
+        : path_(path),
+          filename_(filename),
+          dlhandle_(nullptr),
+          refcount_(0) {}
 
     LayerLibrary(LayerLibrary&& other)
         : path_(std::move(other.path_)),
+          filename_(std::move(other.filename_)),
           dlhandle_(other.dlhandle_),
           refcount_(other.refcount_) {
         other.dlhandle_ = nullptr;
@@ -94,9 +98,14 @@
                  const char* gpa_name,
                  size_t gpa_name_len) const;
 
+    const std::string GetFilename() { return filename_; }
+
    private:
     const std::string path_;
 
+    // Track the filename alone so we can detect duplicates
+    const std::string filename_;
+
     std::mutex mutex_;
     void* dlhandle_;
     size_t refcount_;
@@ -111,7 +120,7 @@
         // any symbol dependencies will be resolved by system libraries. They
         // can't safely use libc++_shared, for example. Which is one reason
         // (among several) we only allow them in non-user builds.
-        auto app_namespace = LoaderData::GetInstance().app_namespace;
+        auto app_namespace = android::GraphicsEnv::getInstance().getAppNamespace();
         if (app_namespace &&
             !android::base::StartsWith(path_, kSystemLayerLibraryDir)) {
             android_dlextinfo dlextinfo = {};
@@ -305,8 +314,8 @@
 std::vector<LayerLibrary> g_layer_libraries;
 std::vector<Layer> g_instance_layers;
 
-void AddLayerLibrary(const std::string& path) {
-    LayerLibrary library(path);
+void AddLayerLibrary(const std::string& path, const std::string& filename) {
+    LayerLibrary library(path + "/" + filename, filename);
     if (!library.Open())
         return;
 
@@ -398,7 +407,25 @@
         ForEachFileInPath(path, [&](const std::string& filename) {
             if (android::base::StartsWith(filename, "libVkLayer") &&
                 android::base::EndsWith(filename, ".so")) {
-                AddLayerLibrary(path + "/" + filename);
+
+                // Check to ensure we haven't seen this layer already
+                // Let the first instance of the shared object be enumerated
+                // We're searching for layers in following order:
+                // 1. system path
+                // 2. libraryPermittedPath (if enabled)
+                // 3. libraryPath
+
+                bool duplicate = false;
+                for (auto& layer : g_layer_libraries) {
+                    if (layer.GetFilename() == filename) {
+                        ALOGV("Skipping duplicate layer %s in %s",
+                              filename.c_str(), path.c_str());
+                        duplicate = true;
+                    }
+                }
+
+                if (!duplicate)
+                    AddLayerLibrary(path, filename);
             }
         });
     }
@@ -428,8 +455,8 @@
         prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
         DiscoverLayersInPathList(kSystemLayerLibraryDir);
     }
-    if (!LoaderData::GetInstance().layer_path.empty())
-        DiscoverLayersInPathList(LoaderData::GetInstance().layer_path);
+    if (!android::GraphicsEnv::getInstance().getLayerPaths().empty())
+        DiscoverLayersInPathList(android::GraphicsEnv::getInstance().getLayerPaths());
 }
 
 uint32_t GetLayerCount() {