aapt now sorts the strings in the resource string pool.

In our current environment with very many translations, this can
save a lot of RAM -- for example over 200K in Gmail just by sorting
the strings in the Gmail .apk (not the framework).

Also add a new aapt command to print the contents of the resource
table string pool.

Change-Id: I1da037b3e2c377b890833ff57ab158965314ac48
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index b741ed6..c496da6 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -444,23 +444,31 @@
 
     void uninit();
 
+    // Return string entry as UTF16; if the pool is UTF8, the string will
+    // be converted before returning.
     inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
         return stringAt(ref.index, outLen);
     }
     const char16_t* stringAt(size_t idx, size_t* outLen) const;
 
+    // Note: returns null if the string pool is not UTF8.
     const char* string8At(size_t idx, size_t* outLen) const;
 
+    // Return string whether the pool is UTF8 or UTF16.  Does not allow you
+    // to distinguish null.
+    const String8 string8ObjectAt(size_t idx) const;
+
     const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
     const ResStringPool_span* styleAt(size_t idx) const;
 
     ssize_t indexOfString(const char16_t* str, size_t strLen) const;
 
     size_t size() const;
+    size_t styleCount() const;
+    size_t bytes() const;
 
-#ifndef HAVE_ANDROID_OS
+    bool isSorted() const;
     bool isUTF8() const;
-#endif
 
 private:
     status_t                    mError;
@@ -746,7 +754,9 @@
 /**
  * Header for a resource table.  Its data contains a series of
  * additional chunks:
- *   * A ResStringPool_header containing all table values.
+ *   * A ResStringPool_header containing all table values.  This string pool
+ *     contains all of the string values in the entire resource table (not
+ *     the names of entries or type identifiers however).
  *   * One or more ResTable_package chunks.
  *
  * Specific entries within a resource table can be uniquely identified
@@ -984,68 +994,15 @@
         uint32_t screenSizeDp;
     };
 
-    inline void copyFromDeviceNoSwap(const ResTable_config& o) {
-        const size_t size = dtohl(o.size);
-        if (size >= sizeof(ResTable_config)) {
-            *this = o;
-        } else {
-            memcpy(this, &o, size);
-            memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
-        }
-    }
+    void copyFromDeviceNoSwap(const ResTable_config& o);
     
-    inline void copyFromDtoH(const ResTable_config& o) {
-        copyFromDeviceNoSwap(o);
-        size = sizeof(ResTable_config);
-        mcc = dtohs(mcc);
-        mnc = dtohs(mnc);
-        density = dtohs(density);
-        screenWidth = dtohs(screenWidth);
-        screenHeight = dtohs(screenHeight);
-        sdkVersion = dtohs(sdkVersion);
-        minorVersion = dtohs(minorVersion);
-        smallestScreenWidthDp = dtohs(smallestScreenWidthDp);
-        screenWidthDp = dtohs(screenWidthDp);
-        screenHeightDp = dtohs(screenHeightDp);
-    }
+    void copyFromDtoH(const ResTable_config& o);
     
-    inline void swapHtoD() {
-        size = htodl(size);
-        mcc = htods(mcc);
-        mnc = htods(mnc);
-        density = htods(density);
-        screenWidth = htods(screenWidth);
-        screenHeight = htods(screenHeight);
-        sdkVersion = htods(sdkVersion);
-        minorVersion = htods(minorVersion);
-        smallestScreenWidthDp = htods(smallestScreenWidthDp);
-        screenWidthDp = htods(screenWidthDp);
-        screenHeightDp = htods(screenHeightDp);
-    }
-    
-    inline int compare(const ResTable_config& o) const {
-        int32_t diff = (int32_t)(imsi - o.imsi);
-        if (diff != 0) return diff;
-        diff = (int32_t)(locale - o.locale);
-        if (diff != 0) return diff;
-        diff = (int32_t)(screenType - o.screenType);
-        if (diff != 0) return diff;
-        diff = (int32_t)(input - o.input);
-        if (diff != 0) return diff;
-        diff = (int32_t)(screenSize - o.screenSize);
-        if (diff != 0) return diff;
-        diff = (int32_t)(version - o.version);
-        if (diff != 0) return diff;
-        diff = (int32_t)(screenLayout - o.screenLayout);
-        if (diff != 0) return diff;
-        diff = (int32_t)(uiMode - o.uiMode);
-        if (diff != 0) return diff;
-        diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);
-        if (diff != 0) return diff;
-        diff = (int32_t)(screenSizeDp - o.screenSizeDp);
-        return (int)diff;
-    }
-    
+    void swapHtoD();
+
+    int compare(const ResTable_config& o) const;
+    int compareLogical(const ResTable_config& o) const;
+
     // Flags indicating a set of config values.  These flag constants must
     // match the corresponding ones in android.content.pm.ActivityInfo and
     // attrs_manifest.xml.
@@ -1068,158 +1025,10 @@
     
     // Compare two configuration, returning CONFIG_* flags set for each value
     // that is different.
-    inline int diff(const ResTable_config& o) const {
-        int diffs = 0;
-        if (mcc != o.mcc) diffs |= CONFIG_MCC;
-        if (mnc != o.mnc) diffs |= CONFIG_MNC;
-        if (locale != o.locale) diffs |= CONFIG_LOCALE;
-        if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
-        if (density != o.density) diffs |= CONFIG_DENSITY;
-        if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
-        if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
-                diffs |= CONFIG_KEYBOARD_HIDDEN;
-        if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
-        if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
-        if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
-        if (version != o.version) diffs |= CONFIG_VERSION;
-        if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
-        if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
-        if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
-        if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
-        return diffs;
-    }
+    int diff(const ResTable_config& o) const;
     
     // Return true if 'this' is more specific than 'o'.
-    inline bool
-    isMoreSpecificThan(const ResTable_config& o) const {
-        // The order of the following tests defines the importance of one
-        // configuration parameter over another.  Those tests first are more
-        // important, trumping any values in those following them.
-        if (imsi || o.imsi) {
-            if (mcc != o.mcc) {
-                if (!mcc) return false;
-                if (!o.mcc) return true;
-            }
-
-            if (mnc != o.mnc) {
-                if (!mnc) return false;
-                if (!o.mnc) return true;
-            }
-        }
-
-        if (locale || o.locale) {
-            if (language[0] != o.language[0]) {
-                if (!language[0]) return false;
-                if (!o.language[0]) return true;
-            }
-
-            if (country[0] != o.country[0]) {
-                if (!country[0]) return false;
-                if (!o.country[0]) return true;
-            }
-        }
-
-        if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
-            if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
-                if (!smallestScreenWidthDp) return false;
-                if (!o.smallestScreenWidthDp) return true;
-            }
-        }
-
-        if (screenSizeDp || o.screenSizeDp) {
-            if (screenWidthDp != o.screenWidthDp) {
-                if (!screenWidthDp) return false;
-                if (!o.screenWidthDp) return true;
-            }
-
-            if (screenHeightDp != o.screenHeightDp) {
-                if (!screenHeightDp) return false;
-                if (!o.screenHeightDp) return true;
-            }
-        }
-
-        if (screenLayout || o.screenLayout) {
-            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
-                if (!(screenLayout & MASK_SCREENSIZE)) return false;
-                if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
-            }
-            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
-                if (!(screenLayout & MASK_SCREENLONG)) return false;
-                if (!(o.screenLayout & MASK_SCREENLONG)) return true;
-            }
-        }
-
-        if (orientation != o.orientation) {
-            if (!orientation) return false;
-            if (!o.orientation) return true;
-        }
-
-        if (uiMode || o.uiMode) {
-            if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {
-                if (!(uiMode & MASK_UI_MODE_TYPE)) return false;
-                if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;
-            }
-            if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {
-                if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;
-                if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;
-            }
-        }
-
-        // density is never 'more specific'
-        // as the default just equals 160
-
-        if (touchscreen != o.touchscreen) {
-            if (!touchscreen) return false;
-            if (!o.touchscreen) return true;
-        }
-
-        if (input || o.input) {
-            if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
-                if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
-                if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
-            }
-
-            if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
-                if (!(inputFlags & MASK_NAVHIDDEN)) return false;
-                if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
-            }
-
-            if (keyboard != o.keyboard) {
-                if (!keyboard) return false;
-                if (!o.keyboard) return true;
-            }
-
-            if (navigation != o.navigation) {
-                if (!navigation) return false;
-                if (!o.navigation) return true;
-            }
-        }
-
-        if (screenSize || o.screenSize) {
-            if (screenWidth != o.screenWidth) {
-                if (!screenWidth) return false;
-                if (!o.screenWidth) return true;
-            }
-
-            if (screenHeight != o.screenHeight) {
-                if (!screenHeight) return false;
-                if (!o.screenHeight) return true;
-            }
-        }
-
-        if (version || o.version) {
-            if (sdkVersion != o.sdkVersion) {
-                if (!sdkVersion) return false;
-                if (!o.sdkVersion) return true;
-            }
-
-            if (minorVersion != o.minorVersion) {
-                if (!minorVersion) return false;
-                if (!o.minorVersion) return true;
-            }
-        }
-        return false;
-    }
+    bool isMoreSpecificThan(const ResTable_config& o) const;
 
     // Return true if 'this' is a better match than 'o' for the 'requested'
     // configuration.  This assumes that match() has already been used to
@@ -1231,222 +1040,7 @@
     // they are not equal then one must be generic because only generic and
     // '==requested' will pass the match() call.  So if this is not generic,
     // it wins.  If this IS generic, o wins (return false).
-    inline bool
-    isBetterThan(const ResTable_config& o,
-            const ResTable_config* requested) const {
-        if (requested) {
-            if (imsi || o.imsi) {
-                if ((mcc != o.mcc) && requested->mcc) {
-                    return (mcc);
-                }
-
-                if ((mnc != o.mnc) && requested->mnc) {
-                    return (mnc);
-                }
-            }
-
-            if (locale || o.locale) {
-                if ((language[0] != o.language[0]) && requested->language[0]) {
-                    return (language[0]);
-                }
-
-                if ((country[0] != o.country[0]) && requested->country[0]) {
-                    return (country[0]);
-                }
-            }
-
-            if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
-                // The configuration closest to the actual size is best.
-                // We assume that larger configs have already been filtered
-                // out at this point.  That means we just want the largest one.
-                return smallestScreenWidthDp >= o.smallestScreenWidthDp;
-            }
-
-            if (screenSizeDp || o.screenSizeDp) {
-                // "Better" is based on the sum of the difference between both
-                // width and height from the requested dimensions.  We are
-                // assuming the invalid configs (with smaller dimens) have
-                // already been filtered.  Note that if a particular dimension
-                // is unspecified, we will end up with a large value (the
-                // difference between 0 and the requested dimension), which is
-                // good since we will prefer a config that has specified a
-                // dimension value.
-                int myDelta = 0, otherDelta = 0;
-                if (requested->screenWidthDp) {
-                    myDelta += requested->screenWidthDp - screenWidthDp;
-                    otherDelta += requested->screenWidthDp - o.screenWidthDp;
-                }
-                if (requested->screenHeightDp) {
-                    myDelta += requested->screenHeightDp - screenHeightDp;
-                    otherDelta += requested->screenHeightDp - o.screenHeightDp;
-                }
-                //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
-                //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
-                //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
-                return (myDelta <= otherDelta);
-            }
-
-            if (screenLayout || o.screenLayout) {
-                if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
-                        && (requested->screenLayout & MASK_SCREENSIZE)) {
-                    // A little backwards compatibility here: undefined is
-                    // considered equivalent to normal.  But only if the
-                    // requested size is at least normal; otherwise, small
-                    // is better than the default.
-                    int mySL = (screenLayout & MASK_SCREENSIZE);
-                    int oSL = (o.screenLayout & MASK_SCREENSIZE);
-                    int fixedMySL = mySL;
-                    int fixedOSL = oSL;
-                    if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
-                        if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
-                        if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
-                    }
-                    // For screen size, the best match is the one that is
-                    // closest to the requested screen size, but not over
-                    // (the not over part is dealt with in match() below).
-                    if (fixedMySL == fixedOSL) {
-                        // If the two are the same, but 'this' is actually
-                        // undefined, then the other is really a better match.
-                        if (mySL == 0) return false;
-                        return true;
-                    }
-                    return fixedMySL >= fixedOSL;
-                }
-                if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
-                        && (requested->screenLayout & MASK_SCREENLONG)) {
-                    return (screenLayout & MASK_SCREENLONG);
-                }
-            }
-
-            if ((orientation != o.orientation) && requested->orientation) {
-                return (orientation);
-            }
-
-            if (uiMode || o.uiMode) {
-                if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
-                        && (requested->uiMode & MASK_UI_MODE_TYPE)) {
-                    return (uiMode & MASK_UI_MODE_TYPE);
-                }
-                if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
-                        && (requested->uiMode & MASK_UI_MODE_NIGHT)) {
-                    return (uiMode & MASK_UI_MODE_NIGHT);
-                }
-            }
-
-            if (screenType || o.screenType) {
-                if (density != o.density) {
-                    // density is tough.  Any density is potentially useful
-                    // because the system will scale it.  Scaling down
-                    // is generally better than scaling up.
-                    // Default density counts as 160dpi (the system default)
-                    // TODO - remove 160 constants
-                    int h = (density?density:160);
-                    int l = (o.density?o.density:160);
-                    bool bImBigger = true;
-                    if (l > h) {
-                        int t = h;
-                        h = l;
-                        l = t;
-                        bImBigger = false;
-                    }
- 
-                    int reqValue = (requested->density?requested->density:160);
-                    if (reqValue >= h) {
-                        // requested value higher than both l and h, give h
-                        return bImBigger;
-                    }
-                    if (l >= reqValue) {
-                        // requested value lower than both l and h, give l
-                        return !bImBigger;
-                    }
-                    // saying that scaling down is 2x better than up
-                    if (((2 * l) - reqValue) * h > reqValue * reqValue) {
-                        return !bImBigger;
-                    } else { 
-                        return bImBigger;
-                    }
-                }
-
-                if ((touchscreen != o.touchscreen) && requested->touchscreen) {
-                    return (touchscreen);
-                }
-            }
-
-            if (input || o.input) {
-                const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
-                const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
-                if (keysHidden != oKeysHidden) {
-                    const int reqKeysHidden =
-                            requested->inputFlags & MASK_KEYSHIDDEN;
-                    if (reqKeysHidden) {
-
-                        if (!keysHidden) return false;
-                        if (!oKeysHidden) return true;
-                        // For compatibility, we count KEYSHIDDEN_NO as being
-                        // the same as KEYSHIDDEN_SOFT.  Here we disambiguate
-                        // these by making an exact match more specific.
-                        if (reqKeysHidden == keysHidden) return true;
-                        if (reqKeysHidden == oKeysHidden) return false;
-                    }
-                }
-
-                const int navHidden = inputFlags & MASK_NAVHIDDEN;
-                const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
-                if (navHidden != oNavHidden) {
-                    const int reqNavHidden =
-                            requested->inputFlags & MASK_NAVHIDDEN;
-                    if (reqNavHidden) {
-
-                        if (!navHidden) return false;
-                        if (!oNavHidden) return true;
-                    }
-                }
-
-                if ((keyboard != o.keyboard) && requested->keyboard) {
-                    return (keyboard);
-                }
-
-                if ((navigation != o.navigation) && requested->navigation) {
-                    return (navigation);
-                }
-            }
-
-            if (screenSize || o.screenSize) {
-                // "Better" is based on the sum of the difference between both
-                // width and height from the requested dimensions.  We are
-                // assuming the invalid configs (with smaller sizes) have
-                // already been filtered.  Note that if a particular dimension
-                // is unspecified, we will end up with a large value (the
-                // difference between 0 and the requested dimension), which is
-                // good since we will prefer a config that has specified a
-                // size value.
-                int myDelta = 0, otherDelta = 0;
-                if (requested->screenWidth) {
-                    myDelta += requested->screenWidth - screenWidth;
-                    otherDelta += requested->screenWidth - o.screenWidth;
-                }
-                if (requested->screenHeight) {
-                    myDelta += requested->screenHeight - screenHeight;
-                    otherDelta += requested->screenHeight - o.screenHeight;
-                }
-                return (myDelta <= otherDelta);
-            }
-
-            if (version || o.version) {
-                if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
-                    return (sdkVersion > o.sdkVersion);
-                }
-
-                if ((minorVersion != o.minorVersion) &&
-                        requested->minorVersion) {
-                    return (minorVersion);
-                }
-            }
-
-            return false;
-        }
-        return isMoreSpecificThan(o);
-    }
+    bool isBetterThan(const ResTable_config& o, const ResTable_config* requested) const;
 
     // Return true if 'this' can be considered a match for the parameters in 
     // 'settings'.
@@ -1454,150 +1048,11 @@
     // but a request for the default should not match odd specifics
     // (ie, request with no mcc should not match a particular mcc's data)
     // settings is the requested settings
-    inline bool match(const ResTable_config& settings) const {
-        if (imsi != 0) {
-            if (mcc != 0 && mcc != settings.mcc) {
-                return false;
-            }
-            if (mnc != 0 && mnc != settings.mnc) {
-                return false;
-            }
-        }
-        if (locale != 0) {
-            if (language[0] != 0
-                && (language[0] != settings.language[0]
-                    || language[1] != settings.language[1])) {
-                return false;
-            }
-            if (country[0] != 0
-                && (country[0] != settings.country[0]
-                    || country[1] != settings.country[1])) {
-                return false;
-            }
-        }
-        if (screenConfig != 0) {
-            const int screenSize = screenLayout&MASK_SCREENSIZE;
-            const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
-            // Any screen sizes for larger screens than the setting do not
-            // match.
-            if (screenSize != 0 && screenSize > setScreenSize) {
-                return false;
-            }
-            
-            const int screenLong = screenLayout&MASK_SCREENLONG;
-            const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
-            if (screenLong != 0 && screenLong != setScreenLong) {
-                return false;
-            }
+    bool match(const ResTable_config& settings) const;
 
-            const int uiModeType = uiMode&MASK_UI_MODE_TYPE;
-            const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
-            if (uiModeType != 0 && uiModeType != setUiModeType) {
-                return false;
-            }
+    void getLocale(char str[6]) const;
 
-            const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
-            const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
-            if (uiModeNight != 0 && uiModeNight != setUiModeNight) {
-                return false;
-            }
-
-            if (smallestScreenWidthDp != 0
-                    && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
-                return false;
-            }
-        }
-        if (screenSizeDp != 0) {
-            if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {
-                //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
-                return false;
-            }
-            if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {
-                //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
-                return false;
-            }
-        }
-        if (screenType != 0) {
-            if (orientation != 0 && orientation != settings.orientation) {
-                return false;
-            }
-            // density always matches - we can scale it.  See isBetterThan
-            if (touchscreen != 0 && touchscreen != settings.touchscreen) {
-                return false;
-            }
-        }
-        if (input != 0) {
-            const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
-            const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
-            if (keysHidden != 0 && keysHidden != setKeysHidden) {
-                // For compatibility, we count a request for KEYSHIDDEN_NO as also
-                // matching the more recent KEYSHIDDEN_SOFT.  Basically
-                // KEYSHIDDEN_NO means there is some kind of keyboard available.
-                //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
-                if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
-                    //ALOGI("No match!");
-                    return false;
-                }
-            }
-            const int navHidden = inputFlags&MASK_NAVHIDDEN;
-            const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
-            if (navHidden != 0 && navHidden != setNavHidden) {
-                return false;
-            }
-            if (keyboard != 0 && keyboard != settings.keyboard) {
-                return false;
-            }
-            if (navigation != 0 && navigation != settings.navigation) {
-                return false;
-            }
-        }
-        if (screenSize != 0) {
-            if (screenWidth != 0 && screenWidth > settings.screenWidth) {
-                return false;
-            }
-            if (screenHeight != 0 && screenHeight > settings.screenHeight) {
-                return false;
-            }
-        }
-        if (version != 0) {
-            if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {
-                return false;
-            }
-            if (minorVersion != 0 && minorVersion != settings.minorVersion) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    void getLocale(char str[6]) const {
-        memset(str, 0, 6);
-        if (language[0]) {
-            str[0] = language[0];
-            str[1] = language[1];
-            if (country[0]) {
-                str[2] = '_';
-                str[3] = country[0];
-                str[4] = country[1];
-            }
-        }
-    }
-
-    String8 toString() const {
-        char buf[200];
-        sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
-                "kbd=%d nav=%d input=%d ssz=%dx%d sw%ddp w%ddp h%ddp sz=%d long=%d "
-                "ui=%d night=%d vers=%d.%d",
-                mcc, mnc,
-                language[0] ? language[0] : '-', language[1] ? language[1] : '-',
-                country[0] ? country[0] : '-', country[1] ? country[1] : '-',
-                orientation, touchscreen, density, keyboard, navigation, inputFlags,
-                screenWidth, screenHeight, smallestScreenWidthDp, screenWidthDp, screenHeightDp,
-                screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG,
-                uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT,
-                sdkVersion, minorVersion);
-        return String8(buf);
-    }
+    String8 toString() const;
 };
 
 /**
@@ -2056,8 +1511,14 @@
     const char16_t* getBasePackageName(size_t idx) const;
     uint32_t getBasePackageId(size_t idx) const;
 
+    // Return the number of resource tables that the object contains.
     size_t getTableCount() const;
+    // Return the values string pool for the resource table at the given
+    // index.  This string pool contains all of the strings for values
+    // contained in the resource table -- that is the item values themselves,
+    // but not the names their entries or types.
     const ResStringPool* getTableStringBlock(size_t index) const;
+    // Return unique cookie identifier for the given resource table.
     void* getTableCookie(size_t index) const;
 
     // Return the configurations (ResTable_config) that we know about