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