1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.content.res;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.text.TextUtils;
23 
24 import java.util.Arrays;
25 import java.util.Objects;
26 
27 /** @hide */
28 public final class ResourcesKey {
29     @Nullable
30     @UnsupportedAppUsage
31     public final String mResDir;
32 
33     @Nullable
34     @UnsupportedAppUsage
35     public final String[] mSplitResDirs;
36 
37     @Nullable
38     public final String[] mOverlayDirs;
39 
40     @Nullable
41     public final String[] mLibDirs;
42 
43     public final int mDisplayId;
44 
45     @NonNull
46     public final Configuration mOverrideConfiguration;
47 
48     @NonNull
49     public final CompatibilityInfo mCompatInfo;
50 
51     private final int mHash;
52 
53     @UnsupportedAppUsage
ResourcesKey(@ullable String resDir, @Nullable String[] splitResDirs, @Nullable String[] overlayDirs, @Nullable String[] libDirs, int displayId, @Nullable Configuration overrideConfig, @Nullable CompatibilityInfo compatInfo)54     public ResourcesKey(@Nullable String resDir,
55                         @Nullable String[] splitResDirs,
56                         @Nullable String[] overlayDirs,
57                         @Nullable String[] libDirs,
58                         int displayId,
59                         @Nullable Configuration overrideConfig,
60                         @Nullable CompatibilityInfo compatInfo) {
61         mResDir = resDir;
62         mSplitResDirs = splitResDirs;
63         mOverlayDirs = overlayDirs;
64         mLibDirs = libDirs;
65         mDisplayId = displayId;
66         mOverrideConfiguration = new Configuration(overrideConfig != null
67                 ? overrideConfig : Configuration.EMPTY);
68         mCompatInfo = compatInfo != null ? compatInfo : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
69 
70         int hash = 17;
71         hash = 31 * hash + Objects.hashCode(mResDir);
72         hash = 31 * hash + Arrays.hashCode(mSplitResDirs);
73         hash = 31 * hash + Arrays.hashCode(mOverlayDirs);
74         hash = 31 * hash + Arrays.hashCode(mLibDirs);
75         hash = 31 * hash + mDisplayId;
76         hash = 31 * hash + Objects.hashCode(mOverrideConfiguration);
77         hash = 31 * hash + Objects.hashCode(mCompatInfo);
78         mHash = hash;
79     }
80 
hasOverrideConfiguration()81     public boolean hasOverrideConfiguration() {
82         return !Configuration.EMPTY.equals(mOverrideConfiguration);
83     }
84 
isPathReferenced(String path)85     public boolean isPathReferenced(String path) {
86         if (mResDir != null && mResDir.startsWith(path)) {
87             return true;
88         } else {
89             return anyStartsWith(mSplitResDirs, path) || anyStartsWith(mOverlayDirs, path)
90                     || anyStartsWith(mLibDirs, path);
91         }
92     }
93 
anyStartsWith(String[] list, String prefix)94     private static boolean anyStartsWith(String[] list, String prefix) {
95         if (list != null) {
96             for (String s : list) {
97                 if (s != null && s.startsWith(prefix)) {
98                     return true;
99                 }
100             }
101         }
102         return false;
103     }
104 
105     @Override
hashCode()106     public int hashCode() {
107         return mHash;
108     }
109 
110     @Override
equals(Object obj)111     public boolean equals(Object obj) {
112         if (!(obj instanceof ResourcesKey)) {
113             return false;
114         }
115 
116         ResourcesKey peer = (ResourcesKey) obj;
117         if (mHash != peer.mHash) {
118             // If the hashes don't match, the objects can't match.
119             return false;
120         }
121 
122         if (!Objects.equals(mResDir, peer.mResDir)) {
123             return false;
124         }
125         if (!Arrays.equals(mSplitResDirs, peer.mSplitResDirs)) {
126             return false;
127         }
128         if (!Arrays.equals(mOverlayDirs, peer.mOverlayDirs)) {
129             return false;
130         }
131         if (!Arrays.equals(mLibDirs, peer.mLibDirs)) {
132             return false;
133         }
134         if (mDisplayId != peer.mDisplayId) {
135             return false;
136         }
137         if (!Objects.equals(mOverrideConfiguration, peer.mOverrideConfiguration)) {
138             return false;
139         }
140         if (!Objects.equals(mCompatInfo, peer.mCompatInfo)) {
141             return false;
142         }
143         return true;
144     }
145 
146     @Override
toString()147     public String toString() {
148         StringBuilder builder = new StringBuilder().append("ResourcesKey{");
149         builder.append(" mHash=").append(Integer.toHexString(mHash));
150         builder.append(" mResDir=").append(mResDir);
151         builder.append(" mSplitDirs=[");
152         if (mSplitResDirs != null) {
153             builder.append(TextUtils.join(",", mSplitResDirs));
154         }
155         builder.append("]");
156         builder.append(" mOverlayDirs=[");
157         if (mOverlayDirs != null) {
158             builder.append(TextUtils.join(",", mOverlayDirs));
159         }
160         builder.append("]");
161         builder.append(" mLibDirs=[");
162         if (mLibDirs != null) {
163             builder.append(TextUtils.join(",", mLibDirs));
164         }
165         builder.append("]");
166         builder.append(" mDisplayId=").append(mDisplayId);
167         builder.append(" mOverrideConfig=").append(Configuration.resourceQualifierString(
168                 mOverrideConfiguration));
169         builder.append(" mCompatInfo=").append(mCompatInfo);
170         builder.append("}");
171         return builder.toString();
172     }
173 }
174