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