1 /*
2  * Copyright (C) 2018 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 com.android.documentsui.ui;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.content.Context;
22 import android.content.res.CompatibilityInfo;
23 import android.content.res.Configuration;
24 import android.content.res.Resources;
25 import android.content.res.TypedArray;
26 import android.util.DisplayMetrics;
27 
28 import androidx.test.InstrumentationRegistry;
29 import androidx.test.filters.SmallTest;
30 import androidx.test.runner.AndroidJUnit4;
31 
32 import com.android.documentsui.R;
33 
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.runner.RunWith;
37 
38 /**
39  * The TestBase class define getThemeByUiMode API and prepare setUp and tearDown for Theme test
40  */
41 @SmallTest
42 @RunWith(AndroidJUnit4.class)
43 public abstract class ThemeUiTestBase {
44     protected Context mTargetContext;
45     protected Configuration mConfiguration;
46     protected DisplayMetrics mDisplayMetrics;
47     protected CompatibilityInfo mCompatibilityInfo;
48     protected Resources.Theme mTheme;
49 
50     @Before
setUp()51     public void setUp() throws Exception {
52         mTargetContext = InstrumentationRegistry.getTargetContext();
53         mConfiguration = mTargetContext.getResources().getConfiguration();
54         mDisplayMetrics = mTargetContext.getResources().getDisplayMetrics();
55         mCompatibilityInfo = mTargetContext.getResources().getCompatibilityInfo();
56     }
57 
58     @After
tearDown()59     public void tearDown() throws Exception {
60         mTargetContext.getResources().updateConfiguration(mConfiguration, mDisplayMetrics,
61                 mCompatibilityInfo);
62     }
63 
64     /**
65      * The method to return the customized theme base on UI_MODE_NIGHT_YES or UI_MODE_NIGHT_NO
66      *
67      * @param context       The applicationContext from Test App
68      * @param nightModeFlag Only support Configuration.UI_MODE_NIGHT_YES or UI_MODE_NIGHT_NO
69      * @return Resources.Theme Applied target App's style/DocumentsTheme
70      */
getThemeByUiMode(Context context, int nightModeFlag)71     protected Resources.Theme getThemeByUiMode(Context context, int nightModeFlag) {
72         final CompatibilityInfo ci = context.getResources().getCompatibilityInfo();
73         final DisplayMetrics dm = context.getResources().getDisplayMetrics();
74         final Configuration nightConfig = new Configuration(
75                 context.getResources().getConfiguration());
76         nightConfig.uiMode &= ~Configuration.UI_MODE_NIGHT_MASK;
77         nightConfig.uiMode |= nightModeFlag;
78         context.getResources().updateConfiguration(nightConfig, dm, ci);
79         // Resources.theme won't be updated by updateConfiguration()
80         // hence, we need to create new Resources.theme to force apply again
81         final Resources.Theme theme = context.getResources().newTheme();
82         theme.applyStyle(R.style.DocumentsTheme, true);
83         theme.applyStyle(R.style.DocumentsDefaultTheme, false);
84         return theme;
85     }
86 
87     /**
88      * The method to assert target theme defined color match expected color
89      *
90      * @param styleable The scope of attrs defined in the theme
91      * @param attr      The specific target color to retrieve
92      * @param expected  The expected color in the theme
93      */
assertTheme(int[] styleable, int attr, int expected)94     protected void assertTheme(int[] styleable, int attr, int expected) {
95         final TypedArray ta = mTheme.obtainStyledAttributes(styleable);
96         final int targetColor = ta.getColor(attr, ~expected);
97         ta.recycle();
98         assertThat(targetColor).isEqualTo(expected);
99     }
100 
101     /**
102      * The method to assert target theme defined config match expected boolean
103      *
104      * @param styleable The scope of attrs defined in the theme
105      * @param attr      The specific target config to retrieve
106      * @param expected  The expected boolean of defined attr in the theme
107      */
assertTheme(int[] styleable, int attr, boolean expected)108     protected void assertTheme(int[] styleable, int attr, boolean expected) {
109         final TypedArray ta = mTheme.obtainStyledAttributes(styleable);
110         final boolean targetBoolean = ta.getBoolean(attr, !expected);
111         ta.recycle();
112         assertThat(targetBoolean).isEqualTo(expected);
113     }
114 }
115