Let findSupportedAbi and hasRenderscriptBitcode scan only relevant files

for better performance. Without the optimization, these two functions
may check more than 100k file names in the pre-installed APK files,
which can take a few seconds to finish even on a recent device.

(cherry-pick of 34fe3df8519523dbb4bc27010fa57f259d5e868d)

Bug: 21957428
Change-Id: I5ebe0438019958d883a7fda6bd92ea4484211d23
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index a526223..daa6f82 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -48,7 +48,6 @@
 #define LIB_SUFFIX_LEN (sizeof(LIB_SUFFIX) - 1)
 
 #define RS_BITCODE_SUFFIX ".bc"
-#define RS_BITCODE_SUFFIX_LEN (sizeof(RS_BITCODE_SUFFIX) -1)
 
 #define GDBSERVER "gdbserver"
 #define GDBSERVER_LEN (sizeof(GDBSERVER) - 1)
@@ -322,7 +321,8 @@
 public:
     static NativeLibrariesIterator* create(ZipFileRO* zipFile) {
         void* cookie = NULL;
-        if (!zipFile->startIteration(&cookie)) {
+        // Do not specify a suffix to find both .so files and gdbserver.
+        if (!zipFile->startIteration(&cookie, APK_LIB, NULL /* suffix */)) {
             return NULL;
         }
 
@@ -337,11 +337,6 @@
                 continue;
             }
 
-            // Make sure we're in the lib directory of the ZIP.
-            if (strncmp(fileName, APK_LIB, APK_LIB_LEN)) {
-                continue;
-            }
-
             // Make sure the filename is at least to the minimum library name size.
             const size_t fileNameLen = strlen(fileName);
             static const size_t minLength = APK_LIB_LEN + 2 + LIB_PREFIX_LEN + 1 + LIB_SUFFIX_LEN;
@@ -529,7 +524,7 @@
         jlong apkHandle) {
     ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
     void* cookie = NULL;
-    if (!zipFile->startIteration(&cookie)) {
+    if (!zipFile->startIteration(&cookie, NULL /* prefix */, RS_BITCODE_SUFFIX)) {
         return APK_SCAN_ERROR;
     }
 
@@ -539,12 +534,9 @@
         if (zipFile->getEntryFileName(next, fileName, sizeof(fileName))) {
             continue;
         }
-
-        const size_t fileNameLen = strlen(fileName);
         const char* lastSlash = strrchr(fileName, '/');
         const char* baseName = (lastSlash == NULL) ? fileName : fileName + 1;
-        if (!strncmp(fileName + fileNameLen - RS_BITCODE_SUFFIX_LEN, RS_BITCODE_SUFFIX,
-                     RS_BITCODE_SUFFIX_LEN) && isFilenameSafe(baseName)) {
+        if (isFilenameSafe(baseName)) {
             zipFile->endIteration(cookie);
             return BITCODE_PRESENT;
         }
diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h
index 1410d87..7680342 100644
--- a/include/androidfw/ZipFileRO.h
+++ b/include/androidfw/ZipFileRO.h
@@ -91,6 +91,7 @@
      * a matching call to endIteration with the same cookie.
      */
     bool startIteration(void** cookie);
+    bool startIteration(void** cookie, const char* prefix, const char* suffix);
 
     /**
      * Return the next entry in iteration order, or NULL if there are no more
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index bdb659c..37aae52 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -127,9 +127,17 @@
 
 bool ZipFileRO::startIteration(void** cookie)
 {
+  return startIteration(cookie, NULL, NULL);
+}
+
+bool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix)
+{
     _ZipEntryRO* ze = new _ZipEntryRO;
+    ZipString pe(prefix ? prefix : "");
+    ZipString se(suffix ? suffix : "");
     int32_t error = StartIteration(mHandle, &(ze->cookie),
-                                   NULL /* prefix */, NULL /* suffix */);
+                                   prefix ? &pe : NULL,
+                                   suffix ? &se : NULL);
     if (error) {
         ALOGW("Could not start iteration over %s: %s", mFileName, ErrorCodeString(error));
         delete ze;