Implement fallback strategy of device memory allocation.

Currently, NNAPI will always fallback to ashmem if the driver fails to
allocate device memory, or if memory domain is not supported on the
related devices. This CL changes this behavior to only fallback if the
related compilations are not created with introspection API.

Bug: 147886012
Test: NNT_static
Change-Id: I93486c6bcb2edd12e0095d79f49bdde679c82d73
Merged-In: I93486c6bcb2edd12e0095d79f49bdde679c82d73
Merged-In: I93486c6bcb2edd12e0095d79f49bdde679c82d73
(cherry picked from commit 02249d9e0e515cd0b71abaa93df1243f09a21936)
(cherry picked from commit 26a3beaade8ef2f45e55bc795069178e9d1a1853)
diff --git a/runtime/Memory.cpp b/runtime/Memory.cpp
index 5c8136f..9bddcd9 100644
--- a/runtime/Memory.cpp
+++ b/runtime/Memory.cpp
@@ -456,6 +456,10 @@
         logMemoryDescriptorToInfo(mDesc, mOperand.value());
     }
     mAllocator = selectDeviceMemoryAllocator(mDesc);
+    mShouldFallback = std::none_of(mRoles.begin(), mRoles.end(), [](const auto& role) {
+        const auto* cb = std::get<const CompilationBuilder*>(role);
+        return cb->createdWithExplicitDeviceList();
+    });
     mFinished = true;
     return ANEURALNETWORKS_NO_ERROR;
 }
@@ -480,13 +484,12 @@
 
     // Try allocate the memory on device.
     if (mAllocator != nullptr) {
-        std::tie(n, memory) = mAllocator->allocate(mDesc);
+        std::tie(n, memory) = mAllocator->allocate(mDesc, mOperand->type);
     }
 
     // If failed, fallback to ashmem.
-    // TODO(xusongw): Decide on the fallback strategy.
     // TODO(xusongw): Use BLOB mode hardware buffer when possible.
-    if (n != ANEURALNETWORKS_NO_ERROR) {
+    if (n != ANEURALNETWORKS_NO_ERROR && mShouldFallback) {
         VLOG(MEMORY) << "MemoryBuilder::allocate -- fallback to ashmem.";
         std::tie(n, memory) = MemoryAshmem::create(size);
     }