blob: ccc9afcd4296b8a09ee578cf60b94fa2baf2b750 [file] [log] [blame]
Amin Shaikhac1c3102019-06-27 12:44:22 -04001/*
2 * Copyright (C) 2019 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
17package com.android.systemui;
18
19import static junit.framework.Assert.fail;
20
21import static org.junit.Assert.assertEquals;
22
23import android.annotation.DrawableRes;
24import android.content.pm.PackageManager;
25import android.content.res.Resources;
26import android.content.res.TypedArray;
27import android.content.res.XmlResourceParser;
28import android.text.TextUtils;
29import android.util.TypedValue;
30
31import androidx.test.filters.MediumTest;
32import androidx.test.runner.AndroidJUnit4;
33
34import com.android.internal.util.XmlUtils;
35
36import org.junit.After;
37import org.junit.Before;
38import org.junit.Test;
39import org.junit.runner.RunWith;
40import org.xmlpull.v1.XmlPullParserException;
41
42import java.io.IOException;
43
44@RunWith(AndroidJUnit4.class)
45@MediumTest
46public class IconPackOverlayTest extends SysuiTestCase {
47
48 private static final String[] ICON_PACK_OVERLAY_PACKAGES = {
49 "com.android.theme.icon_pack.circular.systemui",
50 "com.android.theme.icon_pack.rounded.systemui",
51 "com.android.theme.icon_pack.filled.systemui",
52 };
53
54 private static final int[] VECTOR_ATTRIBUTES = {
55 android.R.attr.tint,
56 android.R.attr.height,
57 android.R.attr.width,
58 android.R.attr.alpha,
59 android.R.attr.autoMirrored,
60 };
61
62 private final TypedValue mTargetTypedValue = new TypedValue();
63 private final TypedValue mOverlayTypedValue = new TypedValue();
64
65 private Resources mResources;
66 private TypedArray mOverlayableIcons;
67
68 @Before
69 public void setup() {
70 mResources = mContext.getResources();
71 mOverlayableIcons = mResources.obtainTypedArray(R.array.overlayable_icons);
72 }
73
74 @After
75 public void teardown() {
76 mOverlayableIcons.recycle();
77 }
78
79 /**
80 * Ensure that all icons contained in overlayable_icons_test.xml exist in all 3 overlay icon
81 * packs for systemui. This test fails if you remove or rename an overlaid icon. If so,
82 * make the same change to the corresponding drawables in {@link #ICON_PACK_OVERLAY_PACKAGES}.
83 */
84 @Test
85 public void testIconPack_containAllOverlayedIcons() {
86 StringBuilder errors = new StringBuilder();
87
88 for (String overlayPackage : ICON_PACK_OVERLAY_PACKAGES) {
89 Resources overlayResources;
90 try {
91 overlayResources = mContext.getPackageManager()
92 .getResourcesForApplication(overlayPackage);
93 } catch (PackageManager.NameNotFoundException e) {
94 continue; // No need to test overlay resources if apk is not on the system.
95 }
96
97 for (int i = 0; i < mOverlayableIcons.length(); i++) {
98 int sysuiRid = mOverlayableIcons.getResourceId(i, 0);
99 String sysuiResourceName = mResources.getResourceName(sysuiRid);
100 String overlayResourceName = sysuiResourceName
101 .replace(mContext.getPackageName(), overlayPackage);
102 if (overlayResources.getIdentifier(overlayResourceName, null, null)
103 == Resources.ID_NULL) {
104 errors.append(String.format("[%s] is not contained in overlay package [%s]",
105 overlayResourceName, overlayPackage));
106 }
107 }
108 }
109
110 if (!TextUtils.isEmpty(errors)) {
111 fail(errors.toString());
112 }
113 }
114
115 /**
116 * Ensures that all overlay icons have the same values for {@link #VECTOR_ATTRIBUTES} as the
117 * underlying drawable in systemui. To fix this test, make the attribute change to all of the
118 * corresponding drawables in {@link #ICON_PACK_OVERLAY_PACKAGES}.
119 */
120 @Test
121 public void testIconPacks_haveEqualVectorDrawableAttributes() {
122 StringBuilder errors = new StringBuilder();
123
124 for (String overlayPackage : ICON_PACK_OVERLAY_PACKAGES) {
125 Resources overlayResources;
126 try {
127 overlayResources = mContext.getPackageManager()
128 .getResourcesForApplication(overlayPackage);
129 } catch (PackageManager.NameNotFoundException e) {
130 continue; // No need to test overlay resources if apk is not on the system.
131 }
132
133 for (int i = 0; i < mOverlayableIcons.length(); i++) {
134 int sysuiRid = mOverlayableIcons.getResourceId(i, 0);
135 String sysuiResourceName = mResources.getResourceName(sysuiRid);
136 TypedArray sysuiAttrs = getAVDAttributes(mResources, sysuiRid);
137 if (sysuiAttrs == null) {
138 errors.append(String.format("[%s] does not exist or is not a valid AVD.",
139 sysuiResourceName));
140 continue;
141 }
142
143 String overlayResourceName = sysuiResourceName
144 .replace(mContext.getPackageName(), overlayPackage);
145 int overlayRid = overlayResources.getIdentifier(overlayResourceName, null, null);
146 TypedArray overlayAttrs = getAVDAttributes(overlayResources, overlayRid);
147 if (overlayAttrs == null) {
148 errors.append(String.format("[%s] does not exist or is not a valid AVD.",
149 overlayResourceName));
150 continue;
151 }
152
153 if (!attributesEquals(sysuiAttrs, overlayAttrs)) {
154 errors.append(String.format("[%s] AVD attributes do not match [%s]\n",
155 sysuiResourceName, overlayResourceName));
156 }
157 sysuiAttrs.recycle();
158 overlayAttrs.recycle();
159 }
160 }
161
162 if (!TextUtils.isEmpty(errors)) {
163 fail(errors.toString());
164 }
165 }
166
167 private TypedArray getAVDAttributes(Resources resources, @DrawableRes int rid) {
168 try {
169 XmlResourceParser parser = resources.getXml(rid);
170 XmlUtils.nextElement(parser);
171 return resources.obtainAttributes(parser, VECTOR_ATTRIBUTES);
172 } catch (XmlPullParserException | IOException | Resources.NotFoundException e) {
173 return null;
174 }
175 }
176
177 private boolean attributesEquals(TypedArray target, TypedArray overlay) {
178 assertEquals(target.length(), overlay.length());
179 for (int i = 0; i < target.length(); i++) {
180 target.getValue(i, mTargetTypedValue);
181 overlay.getValue(i, mOverlayTypedValue);
182 if (!attributesEquals(mTargetTypedValue, mOverlayTypedValue)) {
183 return false;
184 }
185 }
186 return true;
187 }
188
189 private boolean attributesEquals(TypedValue target, TypedValue overlay) {
190 return target.type == overlay.type && target.data == overlay.data;
191 }
192}