ResourceFilter.h revision fab50875b98e8274ac8ee44b38ba42521bbbf1f9
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" and "--preferred-configurations"
28 * options.
29 */
30class WeakResourceFilter : public ResourceFilter {
31public:
32    WeakResourceFilter()
33        : mContainsPseudoAccented(false)
34        , mContainsPseudoBidi(false) {}
35
36    android::status_t parse(const android::String8& str);
37
38    bool match(const android::ResTable_config& config) const;
39
40    inline bool isEmpty() const {
41        return mConfigMask == 0;
42    }
43
44    inline bool containsPseudo() const {
45        return mContainsPseudoAccented;
46    }
47
48    inline bool containsPseudoBidi() const {
49        return mContainsPseudoBidi;
50    }
51
52private:
53    ConfigDescription mDefault;
54    uint32_t mConfigMask;
55    android::Vector<std::pair<ConfigDescription, uint32_t> > mConfigs;
56
57    bool mContainsPseudoAccented;
58    bool mContainsPseudoBidi;
59};
60
61/**
62 * Matches resources that have at least one of the configurations
63 * that this filter is looking for. In order to match a configuration,
64 * the resource must have the exact same configuration.
65 *
66 * This filter acts as a logical OR when matching resources.
67 *
68 * For example, if the filter is looking for resources with
69 * fr-land, de-land, or sw600dp:
70 *
71 * (PASS) fr-land
72 * (FAIL) fr
73 * (PASS) de-land
74 * (FAIL) de
75 * (FAIL) de-sw600dp
76 * (PASS) sw600dp
77 * (FAIL) sw600dp-land
78 */
79class StrongResourceFilter : public ResourceFilter {
80public:
81    StrongResourceFilter() {}
82    StrongResourceFilter(const std::set<ConfigDescription>& configs)
83        : mConfigs(configs) {}
84
85    android::status_t parse(const android::String8& str);
86
87    bool match(const android::ResTable_config& config) const {
88        std::set<ConfigDescription>::const_iterator iter = mConfigs.begin();
89        for (; iter != mConfigs.end(); iter++) {
90            if (iter->compare(config) == 0) {
91                return true;
92            }
93        }
94        return false;
95    }
96
97    inline const std::set<ConfigDescription>& getConfigs() const {
98        return mConfigs;
99    }
100
101private:
102    std::set<ConfigDescription> mConfigs;
103};
104
105/**
106 * Negates the response of the target filter.
107 */
108class InverseResourceFilter : public ResourceFilter {
109public:
110    InverseResourceFilter(const android::sp<ResourceFilter>& filter)
111        : mFilter(filter) {}
112
113    bool match(const android::ResTable_config& config) const {
114        return !mFilter->match(config);
115    }
116
117private:
118    const android::sp<ResourceFilter> mFilter;
119};
120
121/**
122 * A logical AND of all the added filters.
123 */
124class AndResourceFilter : public ResourceFilter {
125public:
126    void addFilter(const android::sp<ResourceFilter>& filter) {
127        mFilters.add(filter);
128    }
129
130    bool match(const android::ResTable_config& config) const {
131        const size_t N = mFilters.size();
132        for (size_t i = 0; i < N; i++) {
133            if (!mFilters[i]->match(config)) {
134                return false;
135            }
136        }
137        return true;
138    }
139
140private:
141    android::Vector<android::sp<ResourceFilter> > mFilters;
142};
143#endif
144