Home | History | Annotate | Download | only in aapt
      1 //
      2 // Copyright 2011 The Android Open Source Project
      3 //
      4 // Build resource files from raw assets.
      5 //
      6 
      7 #ifndef RESOURCE_FILTER_H
      8 #define RESOURCE_FILTER_H
      9 
     10 #include <androidfw/ResourceTypes.h>
     11 #include <set>
     12 #include <utility>
     13 #include <utils/Errors.h>
     14 #include <utils/String8.h>
     15 #include <utils/StrongPointer.h>
     16 #include <utils/Vector.h>
     17 
     18 #include "AaptAssets.h"
     19 #include "ConfigDescription.h"
     20 
     21 class ResourceFilter : public virtual android::RefBase {
     22 public:
     23     virtual bool match(const android::ResTable_config& config) const = 0;
     24 };
     25 
     26 /**
     27  * Implements logic for parsing and handling "-c" options.
     28  */
     29 class WeakResourceFilter : public ResourceFilter {
     30 public:
     31     WeakResourceFilter()
     32         : mContainsPseudoAccented(false)
     33         , mContainsPseudoBidi(false) {}
     34 
     35     android::status_t parse(const android::String8& str);
     36 
     37     bool match(const android::ResTable_config& config) const;
     38 
     39     inline bool isEmpty() const {
     40         return mConfigMask == 0;
     41     }
     42 
     43     inline bool containsPseudo() const {
     44         return mContainsPseudoAccented;
     45     }
     46 
     47     inline bool containsPseudoBidi() const {
     48         return mContainsPseudoBidi;
     49     }
     50 
     51 private:
     52     ConfigDescription mDefault;
     53     uint32_t mConfigMask;
     54     android::Vector<std::pair<ConfigDescription, uint32_t> > mConfigs;
     55 
     56     bool mContainsPseudoAccented;
     57     bool mContainsPseudoBidi;
     58 };
     59 
     60 /**
     61  * Matches resources that have at least one of the configurations
     62  * that this filter is looking for. In order to match a configuration,
     63  * the resource must have the exact same configuration.
     64  *
     65  * This filter acts as a logical OR when matching resources.
     66  *
     67  * For example, if the filter is looking for resources with
     68  * fr-land, de-land, or sw600dp:
     69  *
     70  * (PASS) fr-land
     71  * (FAIL) fr
     72  * (PASS) de-land
     73  * (FAIL) de
     74  * (FAIL) de-sw600dp
     75  * (PASS) sw600dp
     76  * (FAIL) sw600dp-land
     77  */
     78 class StrongResourceFilter : public ResourceFilter {
     79 public:
     80     StrongResourceFilter() {}
     81     explicit StrongResourceFilter(const std::set<ConfigDescription>& configs)
     82         : mConfigs(configs) {}
     83 
     84     android::status_t parse(const android::String8& str);
     85 
     86     bool match(const android::ResTable_config& config) const {
     87         std::set<ConfigDescription>::const_iterator iter = mConfigs.begin();
     88         for (; iter != mConfigs.end(); iter++) {
     89             if (iter->compare(config) == 0) {
     90                 return true;
     91             }
     92         }
     93         return false;
     94     }
     95 
     96     inline const std::set<ConfigDescription>& getConfigs() const {
     97         return mConfigs;
     98     }
     99 
    100 private:
    101     std::set<ConfigDescription> mConfigs;
    102 };
    103 
    104 /**
    105  * Negates the response of the target filter.
    106  */
    107 class InverseResourceFilter : public ResourceFilter {
    108 public:
    109     explicit InverseResourceFilter(const android::sp<ResourceFilter>& filter)
    110         : mFilter(filter) {}
    111 
    112     bool match(const android::ResTable_config& config) const {
    113         return !mFilter->match(config);
    114     }
    115 
    116 private:
    117     const android::sp<ResourceFilter> mFilter;
    118 };
    119 
    120 /**
    121  * A logical AND of all the added filters.
    122  */
    123 class AndResourceFilter : public ResourceFilter {
    124 public:
    125     void addFilter(const android::sp<ResourceFilter>& filter) {
    126         mFilters.add(filter);
    127     }
    128 
    129     bool match(const android::ResTable_config& config) const {
    130         const size_t N = mFilters.size();
    131         for (size_t i = 0; i < N; i++) {
    132             if (!mFilters[i]->match(config)) {
    133                 return false;
    134             }
    135         }
    136         return true;
    137     }
    138 
    139 private:
    140     android::Vector<android::sp<ResourceFilter> > mFilters;
    141 };
    142 #endif
    143