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 21class ResourceFilter : public virtual android::RefBase { 22public: 23 virtual bool match(const android::ResTable_config& config) const = 0; 24}; 25 26/** 27 * Implements logic for parsing and handling "-c" options. 28 */ 29class WeakResourceFilter : public ResourceFilter { 30public: 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 51private: 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 */ 78class StrongResourceFilter : public ResourceFilter { 79public: 80 StrongResourceFilter() {} 81 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 100private: 101 std::set<ConfigDescription> mConfigs; 102}; 103 104/** 105 * Negates the response of the target filter. 106 */ 107class InverseResourceFilter : public ResourceFilter { 108public: 109 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 116private: 117 const android::sp<ResourceFilter> mFilter; 118}; 119 120/** 121 * A logical AND of all the added filters. 122 */ 123class AndResourceFilter : public ResourceFilter { 124public: 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 139private: 140 android::Vector<android::sp<ResourceFilter> > mFilters; 141}; 142#endif 143