188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner/*
288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * Copyright (C) 2013 The Android Open Source Project
388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *
488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * Licensed under the Apache License, Version 2.0 (the "License");
588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * you may not use this file except in compliance with the License.
688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * You may obtain a copy of the License at
788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *
888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *      http://www.apache.org/licenses/LICENSE-2.0
988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *
1088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * Unless required by applicable law or agreed to in writing, software
1188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * distributed under the License is distributed on an "AS IS" BASIS,
1288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * See the License for the specific language governing permissions and
1488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * limitations under the License.
1588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner */
1688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
1788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerpackage android.content.res;
1888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
19a01f48681cdaf34e0943609683d0bbb26e761a58Filip Gruszczynskiimport android.annotation.NonNull;
20082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinskiimport android.annotation.Nullable;
21082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinskiimport android.text.TextUtils;
22a01f48681cdaf34e0943609683d0bbb26e761a58Filip Gruszczynski
23082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinskiimport java.util.Arrays;
2460454dbc4d815c90ff2713e224953d6547fc3ad5Wale Ogunwaleimport java.util.Objects;
2588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
2688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner/** @hide */
2788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerpublic final class ResourcesKey {
28082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    @Nullable
29082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    public final String mResDir;
30082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski
31082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    @Nullable
32082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    public final String[] mSplitResDirs;
33082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski
34082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    @Nullable
35082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    public final String[] mOverlayDirs;
36082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski
37082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    @Nullable
38082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    public final String[] mLibDirs;
3988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
4088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public final int mDisplayId;
41082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski
42a01f48681cdaf34e0943609683d0bbb26e761a58Filip Gruszczynski    @NonNull
4360454dbc4d815c90ff2713e224953d6547fc3ad5Wale Ogunwale    public final Configuration mOverrideConfiguration;
4488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
45082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    @NonNull
46082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    public final CompatibilityInfo mCompatInfo;
47082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski
48082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    private final int mHash;
49082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski
50082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski    public ResourcesKey(@Nullable String resDir,
51082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski                        @Nullable String[] splitResDirs,
52082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski                        @Nullable String[] overlayDirs,
53082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski                        @Nullable String[] libDirs,
54082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski                        int displayId,
55082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski                        @Nullable Configuration overrideConfig,
56082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski                        @Nullable CompatibilityInfo compatInfo) {
5788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        mResDir = resDir;
58082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        mSplitResDirs = splitResDirs;
59082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        mOverlayDirs = overlayDirs;
60082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        mLibDirs = libDirs;
6188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        mDisplayId = displayId;
62a8a9bc5860c5d6139366f01b2f66e3f592da92e1Andrii Kulian        mOverrideConfiguration = new Configuration(overrideConfig != null
63a8a9bc5860c5d6139366f01b2f66e3f592da92e1Andrii Kulian                ? overrideConfig : Configuration.EMPTY);
64082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        mCompatInfo = compatInfo != null ? compatInfo : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
6588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
6688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        int hash = 17;
67082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        hash = 31 * hash + Objects.hashCode(mResDir);
68082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        hash = 31 * hash + Arrays.hashCode(mSplitResDirs);
69082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        hash = 31 * hash + Arrays.hashCode(mOverlayDirs);
70082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        hash = 31 * hash + Arrays.hashCode(mLibDirs);
7188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        hash = 31 * hash + mDisplayId;
72082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        hash = 31 * hash + Objects.hashCode(mOverrideConfiguration);
73082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        hash = 31 * hash + Objects.hashCode(mCompatInfo);
7488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        mHash = hash;
7588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
7688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
7788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public boolean hasOverrideConfiguration() {
78a01f48681cdaf34e0943609683d0bbb26e761a58Filip Gruszczynski        return !Configuration.EMPTY.equals(mOverrideConfiguration);
7988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
8088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
8198bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey    public boolean isPathReferenced(String path) {
8298bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey        if (mResDir != null && mResDir.startsWith(path)) {
8398bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey            return true;
8498bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey        } else {
8598bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey            return anyStartsWith(mSplitResDirs, path) || anyStartsWith(mOverlayDirs, path)
8698bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey                    || anyStartsWith(mLibDirs, path);
8798bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey        }
8898bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey    }
8998bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey
9098bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey    private static boolean anyStartsWith(String[] list, String prefix) {
9198bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey        if (list != null) {
9298bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey            for (String s : list) {
9398bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey                if (s != null && s.startsWith(prefix)) {
9498bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey                    return true;
9598bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey                }
9698bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey            }
9798bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey        }
9898bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey        return false;
9998bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey    }
10098bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey
10188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    @Override
10288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public int hashCode() {
10388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        return mHash;
10488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
10588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
10688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    @Override
10788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public boolean equals(Object obj) {
10888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (!(obj instanceof ResourcesKey)) {
10988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return false;
11088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
111082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski
11288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        ResourcesKey peer = (ResourcesKey) obj;
113082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (mHash != peer.mHash) {
114082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            // If the hashes don't match, the objects can't match.
115082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            return false;
116082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        }
11705e6dde3a0b9ba1eb3d13d511fe2e27a0d10c851Wink Saville
11860454dbc4d815c90ff2713e224953d6547fc3ad5Wale Ogunwale        if (!Objects.equals(mResDir, peer.mResDir)) {
11905e6dde3a0b9ba1eb3d13d511fe2e27a0d10c851Wink Saville            return false;
12005e6dde3a0b9ba1eb3d13d511fe2e27a0d10c851Wink Saville        }
121082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (!Arrays.equals(mSplitResDirs, peer.mSplitResDirs)) {
122082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            return false;
123082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        }
124082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (!Arrays.equals(mOverlayDirs, peer.mOverlayDirs)) {
125082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            return false;
126082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        }
127082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (!Arrays.equals(mLibDirs, peer.mLibDirs)) {
128082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            return false;
129082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        }
13088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (mDisplayId != peer.mDisplayId) {
13188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return false;
13288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
133082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (!Objects.equals(mOverrideConfiguration, peer.mOverrideConfiguration)) {
134a01f48681cdaf34e0943609683d0bbb26e761a58Filip Gruszczynski            return false;
13588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
136082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (!Objects.equals(mCompatInfo, peer.mCompatInfo)) {
13788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return false;
13888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
13988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        return true;
14088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
14188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
14288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    @Override
14388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public String toString() {
144082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        StringBuilder builder = new StringBuilder().append("ResourcesKey{");
145082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mHash=").append(Integer.toHexString(mHash));
146082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mResDir=").append(mResDir);
147082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mSplitDirs=[");
148082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (mSplitResDirs != null) {
149082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            builder.append(TextUtils.join(",", mSplitResDirs));
150082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        }
151082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append("]");
152082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mOverlayDirs=[");
153082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (mOverlayDirs != null) {
154082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            builder.append(TextUtils.join(",", mOverlayDirs));
155082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        }
156082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append("]");
157082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mLibDirs=[");
158082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        if (mLibDirs != null) {
159082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski            builder.append(TextUtils.join(",", mLibDirs));
160082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        }
161082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append("]");
162082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mDisplayId=").append(mDisplayId);
163082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mOverrideConfig=").append(Configuration.resourceQualifierString(
164082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski                mOverrideConfiguration));
165082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append(" mCompatInfo=").append(mCompatInfo);
166082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        builder.append("}");
167082614c6a57a115ee0c5975e3579bf34a178c0f8Adam Lesinski        return builder.toString();
16888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
16988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner}
170