]> git.saurik.com Git - android/aapt.git/blobdiff - AaptAssets.cpp
Allow overlays to add resources.
[android/aapt.git] / AaptAssets.cpp
index aa0575a7ffbc44928b64397a1ebc68c527744867..dbcef6d67480afbccc7127db79f8286ebf2e25fe 100644 (file)
@@ -17,7 +17,6 @@ static const char* kWildcardName = "any";
 static const char* kAssetDir = "assets";
 static const char* kResourceDir = "res";
 static const char* kInvalidChars = "/\\:";
-static const char* kExcludeExtension = ".EXCLUDE";
 static const size_t kMaxAssetFileName = 100;
 
 static const String8 kResString(kResourceDir);
@@ -100,7 +99,7 @@ static bool isHidden(const char *root, const char *path)
 
     return true;
 }
+
 // =========================================================================
 // =========================================================================
 // =========================================================================
@@ -139,6 +138,20 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value)
         return 0;
     }
 
+    // screen layout size
+    if (getScreenLayoutSizeName(part.string(), &config)) {
+        *axis = AXIS_SCREENLAYOUTSIZE;
+        *value = (config.screenLayout&ResTable_config::MASK_SCREENSIZE);
+        return 0;
+    }
+
+    // screen layout long
+    if (getScreenLayoutLongName(part.string(), &config)) {
+        *axis = AXIS_SCREENLAYOUTLONG;
+        *value = (config.screenLayout&ResTable_config::MASK_SCREENLONG);
+        return 0;
+    }
+
     // orientation
     if (getOrientationName(part.string(), &config)) {
         *axis = AXIS_ORIENTATION;
@@ -159,28 +172,28 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value)
         *value = config.touchscreen;
         return 0;
     }
-    
+
     // keyboard hidden
     if (getKeysHiddenName(part.string(), &config)) {
         *axis = AXIS_KEYSHIDDEN;
         *value = config.inputFlags;
         return 0;
     }
-    
+
     // keyboard
     if (getKeyboardName(part.string(), &config)) {
         *axis = AXIS_KEYBOARD;
         *value = config.keyboard;
         return 0;
     }
-    
+
     // navigation
     if (getNavigationName(part.string(), &config)) {
         *axis = AXIS_NAVIGATION;
         *value = config.navigation;
         return 0;
     }
-    
+
     // screen size
     if (getScreenSizeName(part.string(), &config)) {
         *axis = AXIS_SCREENSIZE;
@@ -203,7 +216,8 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
 {
     Vector<String8> parts;
 
-    String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, vers;
+    String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
+    String8 touch, key, keysHidden, nav, size, vers;
 
     const char *p = dir;
     const char *q;
@@ -290,6 +304,30 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
         //printf("not region: %s\n", part.string());
     }
 
+    if (getScreenLayoutSizeName(part.string())) {
+        layoutsize = part;
+
+        index++;
+        if (index == N) {
+            goto success;
+        }
+        part = parts[index];
+    } else {
+        //printf("not screen layout size: %s\n", part.string());
+    }
+
+    if (getScreenLayoutLongName(part.string())) {
+        layoutlong = part;
+
+        index++;
+        if (index == N) {
+            goto success;
+        }
+        part = parts[index];
+    } else {
+        //printf("not screen layout long: %s\n", part.string());
+    }
+
     // orientation
     if (getOrientationName(part.string())) {
         orient = part;
@@ -319,7 +357,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
     // touchscreen
     if (getTouchscreenName(part.string())) {
         touch = part;
-        
+
         index++;
         if (index == N) {
             goto success;
@@ -328,11 +366,11 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
     } else {
         //printf("not touchscreen: %s\n", part.string());
     }
-    
+
     // keyboard hidden
     if (getKeysHiddenName(part.string())) {
         keysHidden = part;
-        
+
         index++;
         if (index == N) {
             goto success;
@@ -341,11 +379,11 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
     } else {
         //printf("not keysHidden: %s\n", part.string());
     }
-    
+
     // keyboard
     if (getKeyboardName(part.string())) {
         key = part;
-        
+
         index++;
         if (index == N) {
             goto success;
@@ -354,10 +392,10 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
     } else {
         //printf("not keyboard: %s\n", part.string());
     }
-    
+
     if (getNavigationName(part.string())) {
         nav = part;
-        
+
         index++;
         if (index == N) {
             goto success;
@@ -366,10 +404,10 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
     } else {
         //printf("not navigation: %s\n", part.string());
     }
-    
+
     if (getScreenSizeName(part.string())) {
         size = part;
-        
+
         index++;
         if (index == N) {
             goto success;
@@ -378,10 +416,10 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
     } else {
         //printf("not screen size: %s\n", part.string());
     }
-    
+
     if (getVersionName(part.string())) {
         vers = part;
-        
+
         index++;
         if (index == N) {
             goto success;
@@ -390,7 +428,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
     } else {
         //printf("not version: %s\n", part.string());
     }
-    
+
     // if there are extra parts, it doesn't match
     return false;
 
@@ -398,6 +436,8 @@ success:
     this->mcc = mcc;
     this->mnc = mnc;
     this->locale = loc;
+    this->screenLayoutSize = layoutsize;
+    this->screenLayoutLong = layoutlong;
     this->orientation = orient;
     this->density = den;
     this->touchscreen = touch;
@@ -422,6 +462,10 @@ AaptGroupEntry::toString() const
     s += ",";
     s += this->locale;
     s += ",";
+    s += screenLayoutSize;
+    s += ",";
+    s += screenLayoutLong;
+    s += ",";
     s += this->orientation;
     s += ",";
     s += density;
@@ -456,6 +500,14 @@ AaptGroupEntry::toDirName(const String8& resType) const
         s += "-";
         s += locale;
     }
+    if (this->screenLayoutSize != "") {
+        s += "-";
+        s += screenLayoutSize;
+    }
+    if (this->screenLayoutLong != "") {
+        s += "-";
+        s += screenLayoutLong;
+    }
     if (this->orientation != "") {
         s += "-";
         s += orientation;
@@ -488,7 +540,7 @@ AaptGroupEntry::toDirName(const String8& resType) const
         s += "-";
         s += version;
     }
-    
+
     return s;
 }
 
@@ -506,9 +558,9 @@ bool AaptGroupEntry::getMccName(const char* name,
     c++;
     if (tolower(*c) != 'c') return false;
     c++;
-    
+
     const char* val = c;
-    
+
     while (*c >= '0' && *c <= '9') {
         c++;
     }
@@ -538,9 +590,9 @@ bool AaptGroupEntry::getMncName(const char* name,
     c++;
     if (tolower(*c) != 'c') return false;
     c++;
-    
+
     const char* val = c;
-    
+
     while (*c >= '0' && *c <= '9') {
         c++;
     }
@@ -605,6 +657,57 @@ bool AaptGroupEntry::getLocaleName(const char* fileName,
     return false;
 }
 
+bool AaptGroupEntry::getScreenLayoutSizeName(const char* name,
+                                     ResTable_config* out)
+{
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_ANY;
+        return true;
+    } else if (strcmp(name, "small") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_SMALL;
+        return true;
+    } else if (strcmp(name, "normal") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_NORMAL;
+        return true;
+    } else if (strcmp(name, "large") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_LARGE;
+        return true;
+    }
+
+    return false;
+}
+
+bool AaptGroupEntry::getScreenLayoutLongName(const char* name,
+                                     ResTable_config* out)
+{
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
+                | ResTable_config::SCREENLONG_ANY;
+        return true;
+    } else if (strcmp(name, "long") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
+                | ResTable_config::SCREENLONG_YES;
+        return true;
+    } else if (strcmp(name, "notlong") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
+                | ResTable_config::SCREENLONG_NO;
+        return true;
+    }
+
+    return false;
+}
+
 bool AaptGroupEntry::getOrientationName(const char* name,
                                         ResTable_config* out)
 {
@@ -621,7 +724,7 @@ bool AaptGroupEntry::getOrientationName(const char* name,
         if (out) out->orientation = out->ORIENTATION_SQUARE;
         return true;
     }
-    
+
     return false;
 }
 
@@ -629,9 +732,30 @@ bool AaptGroupEntry::getDensityName(const char* name,
                                     ResTable_config* out)
 {
     if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->density = 0;
+        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
+        return true;
+    }
+    
+    if (strcmp(name, "nodpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_NONE;
+        return true;
+    }
+    
+    if (strcmp(name, "ldpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_LOW;
         return true;
     }
+    
+    if (strcmp(name, "mdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
+        return true;
+    }
+    
+    if (strcmp(name, "hdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_HIGH;
+        return true;
+    }
+    
     char* c = (char*)name;
     while (*c >= '0' && *c <= '9') {
         c++;
@@ -677,7 +801,7 @@ bool AaptGroupEntry::getTouchscreenName(const char* name,
         if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
         return true;
     }
-    
+
     return false;
 }
 
@@ -695,13 +819,16 @@ bool AaptGroupEntry::getKeysHiddenName(const char* name,
     } else if (strcmp(name, "keyshidden") == 0) {
         mask = out->MASK_KEYSHIDDEN;
         value = out->KEYSHIDDEN_YES;
+    } else if (strcmp(name, "keyssoft") == 0) {
+        mask = out->MASK_KEYSHIDDEN;
+        value = out->KEYSHIDDEN_SOFT;
     }
-    
+
     if (mask != 0) {
         if (out) out->inputFlags = (out->inputFlags&~mask) | value;
         return true;
     }
-    
+
     return false;
 }
 
@@ -721,7 +848,7 @@ bool AaptGroupEntry::getKeyboardName(const char* name,
         if (out) out->keyboard = out->KEYBOARD_12KEY;
         return true;
     }
-    
+
     return false;
 }
 
@@ -744,7 +871,7 @@ bool AaptGroupEntry::getNavigationName(const char* name,
         if (out) out->navigation = out->NAVIGATION_WHEEL;
         return true;
     }
-    
+
     return false;
 }
 
@@ -758,29 +885,29 @@ bool AaptGroupEntry::getScreenSizeName(const char* name,
         }
         return true;
     }
-     
+
     const char* x = name;
     while (*x >= '0' && *x <= '9') x++;
     if (x == name || *x != 'x') return false;
     String8 xName(name, x-name);
     x++;
-    
+
     const char* y = x;
     while (*y >= '0' && *y <= '9') y++;
     if (y == name || *y != 0) return false;
     String8 yName(x, y-x);
-    
+
     uint16_t w = (uint16_t)atoi(xName.string());
     uint16_t h = (uint16_t)atoi(yName.string());
     if (w < h) {
         return false;
     }
-    
+
     if (out) {
         out->screenWidth = w;
         out->screenHeight = h;
     }
-    
+
     return true;
 }
 
@@ -794,22 +921,22 @@ bool AaptGroupEntry::getVersionName(const char* name,
         }
         return true;
     }
-    
+
     if (*name != 'v') {
         return false;
     }
-    
+
     name++;
     const char* s = name;
     while (*s >= '0' && *s <= '9') s++;
     if (s == name || *s != 0) return false;
     String8 sdkName(name, s-name);
-    
+
     if (out) {
         out->sdkVersion = (uint16_t)atoi(sdkName.string());
         out->minorVersion = 0;
     }
-    
+
     return true;
 }
 
@@ -819,6 +946,8 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const
     if (v == 0) v = mnc.compare(o.mnc);
     if (v == 0) v = locale.compare(o.locale);
     if (v == 0) v = vendor.compare(o.vendor);
+    if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize);
+    if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong);
     if (v == 0) v = orientation.compare(o.orientation);
     if (v == 0) v = density.compare(o.density);
     if (v == 0) v = touchscreen.compare(o.touchscreen);
@@ -837,6 +966,8 @@ ResTable_config AaptGroupEntry::toParams() const
     getMccName(mcc.string(), &params);
     getMncName(mnc.string(), &params);
     getLocaleName(locale.string(), &params);
+    getScreenLayoutSizeName(screenLayoutSize.string(), &params);
+    getScreenLayoutLongName(screenLayoutLong.string(), &params);
     getOrientationName(orientation.string(), &params);
     getDensityName(density.string(), &params);
     getTouchscreenName(touchscreen.string(), &params);
@@ -1078,29 +1209,29 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,
 
     {
         DIR* dir = NULL;
-    
+
         dir = opendir(srcDir.string());
         if (dir == NULL) {
             fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno));
             return UNKNOWN_ERROR;
         }
-    
+
         /*
          * Slurp the filenames out of the directory.
          */
         while (1) {
             struct dirent* entry;
-    
+
             entry = readdir(dir);
             if (entry == NULL)
                 break;
-  
+
             if (isHidden(srcDir.string(), entry->d_name))
                 continue;
 
             fileNames.add(String8(entry->d_name));
         }
-    
+
         closedir(dir);
     }
 
@@ -1312,7 +1443,7 @@ void AaptAssets::addResource(const String8& leafName, const String8& path,
     sp<AaptDir> subdir = res->makeDir(dirname);
     sp<AaptGroup> grr = new AaptGroup(leafName, path);
     grr->addFile(file);
-    
+
     subdir->addFile(leafName, grr);
 }
 
@@ -1321,10 +1452,10 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
 {
     int count;
     int totalCount = 0;
-    int i;
-    int arg = 0;
     FileType type;
-    const char* res;
+    const Vector<const char *>& resDirs = bundle->getResourceSourceDirs();
+    const size_t dirCount =resDirs.size();
+    sp<AaptAssets> current = this;
 
     const int N = bundle->getFileSpecCount();
 
@@ -1377,28 +1508,35 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
     /*
      * If a directory of resource-specific assets was supplied, slurp 'em up.
      */
-    res = bundle->getResourceSourceDir();
-    if (res) {
-        type = getFileType(res);
-        if (type == kFileTypeNonexistent) {
-            fprintf(stderr, "ERROR: resource directory '%s' does not exist\n", res);
-            return UNKNOWN_ERROR;
-        }
-        if (type == kFileTypeDirectory) {
-            count = slurpResourceTree(bundle, String8(res));
+    for (size_t i=0; i<dirCount; i++) {
+        const char *res = resDirs[i];
+        if (res) {
+            type = getFileType(res);
+            if (type == kFileTypeNonexistent) {
+                fprintf(stderr, "ERROR: resource directory '%s' does not exist\n", res);
+                return UNKNOWN_ERROR;
+            }
+            if (type == kFileTypeDirectory) {
+                if (i>0) {
+                    sp<AaptAssets> nextOverlay = new AaptAssets();
+                    current->setOverlay(nextOverlay);
+                    current = nextOverlay;
+                }
+                count = current->slurpResourceTree(bundle, String8(res));
 
-            if (count < 0) {
-                totalCount = count;
-                goto bail;
+                if (count < 0) {
+                    totalCount = count;
+                    goto bail;
+                }
+                totalCount += count;
+            }
+            else {
+                fprintf(stderr, "ERROR: '%s' is not a directory\n", res);
+                return UNKNOWN_ERROR;
             }
-            totalCount += count;
-        }
-        else {
-            fprintf(stderr, "ERROR: '%s' is not a directory\n", res);
-            return UNKNOWN_ERROR;
         }
+        
     }
-    
     /*
      * Now do any additional raw files.
      */