Introduce BaseDexClassLoader.computeClassLoaderContextsNative

This will be used to compute the contexts that should be sent over to
the dex load reporter. See associated changes in libcore &
frameworks/base.

Motivation: At the moment of committing there are two classloader
context encoders- one in ART and one in the package manager. The
duplicate logic is susceptible to divergences. For example at the moment
if a package uses shared libraries and has secondary dex files then the
context encoded for secondary dex files will be incorrect[1]. In order to
eliminate this bug and future possible bugs lets centralize where all
classloader context computation is done.

[1]: The context will be incorrect because it doesn't take into account
the shared libraries that are loaded at runtime.

Test: m test-art-host-gtest-class_loader_context_test
Test: m test-art-host-gtest
Test: ./test/testrunner/testrunner.py --host -b
Test: Introduced a set of tests for the new API(s)
Test: See tests in associated libcore & framework/base commits

Bug: 148494302
Change-Id: Id39293a2e1d3d05194f2864f4febb3e652bce075
diff --git a/runtime/class_loader_utils.h b/runtime/class_loader_utils.h
index 1c35360..934c92b 100644
--- a/runtime/class_loader_utils.h
+++ b/runtime/class_loader_utils.h
@@ -30,6 +30,14 @@
 
 namespace art {
 
+// Returns true if the given class loader derives from BaseDexClassLoader.
+inline bool IsInstanceOfBaseDexClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
+                                           Handle<mirror::ClassLoader> class_loader)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  return class_loader->InstanceOf(
+      soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_BaseDexClassLoader));
+}
+
 // Returns true if the given class loader is either a PathClassLoader or a DexClassLoader.
 // (they both have the same behaviour with respect to class lookup order)
 inline bool IsPathOrDexClassLoader(ScopedObjectAccessAlreadyRunnable& soa,