1 /*
2  * Copyright (C) 2021 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.settings.notification;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.app.Instrumentation;
22 import android.content.Intent;
23 import android.provider.Settings;
24 import android.util.Log;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.LinearLayout;
28 import android.widget.TextView;
29 
30 import androidx.test.core.app.ActivityScenario;
31 import androidx.test.ext.junit.rules.ActivityScenarioRule;
32 import androidx.test.ext.junit.runners.AndroidJUnit4;
33 import androidx.test.filters.SmallTest;
34 import androidx.test.platform.app.InstrumentationRegistry;
35 import androidx.test.runner.lifecycle.Stage;
36 
37 import com.android.settings.testutils.CommonUtils;
38 import com.android.settings.testutils.UiUtils;
39 
40 import org.junit.Rule;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.Arrays;
45 import java.util.List;
46 
47 @RunWith(AndroidJUnit4.class)
48 @SmallTest
49 public class AppNotificationComponentTest {
50     private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
51     private final String mNoSlientAppName = "com.google.android.dialer";
52     public final String TAG = this.getClass().getName();
53 
54     @Rule
55     public ActivityScenarioRule<com.android.settings.Settings.AppNotificationSettingsActivity>
56             rule = new ActivityScenarioRule<>(
57             new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
58                     .putExtra(Settings.EXTRA_APP_PACKAGE, mNoSlientAppName)
59                     .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
60 
61     /**
62      * Tests user should not able to modify notification settings for some system apps.
63      * In this case, test `phone` app that will disabled notification configuration.
64      * Steps:
65      * 1. Open notification page of phone app.
66      * 2. Checks system privilege notification should not able to be changed.
67      */
68     @Test
test_special_app_could_not_disable_notification()69     public void test_special_app_could_not_disable_notification() {
70         List<String> disabledList = Arrays.asList("Default", "Incoming calls",
71                 "Background Processing", "Missed calls",
72                 "Ongoing calls", "Voicemails");
73 
74         ActivityScenario ac = rule.getScenario();
75         ac.onActivity(
76                 activity -> {
77                     View recyclerView = activity.findViewById(
78                             CommonUtils.getResId("recycler_view"));
79 
80                     if (recyclerView == null) {
81                         Log.d("UI_UTILS",
82                                 "Target not found: R.id.recycler_view #" + Integer.toHexString(
83                                         CommonUtils.getResId("recycler_view")));
84                         UiUtils.dumpView(UiUtils.getFirstViewFromActivity(activity));
85                         assertThat(Boolean.TRUE).isFalse();
86                     }
87 
88                     UiUtils.waitUntilCondition(5000,
89                             () -> recyclerView.findViewById(CommonUtils.getResId("recycler_view"))
90                                     != null);
91 
92                     View mainSwitchBar = recyclerView.findViewById(
93                             CommonUtils.getResId("main_switch_bar"));
94 
95                     assertThat(mainSwitchBar.isEnabled()).isEqualTo(false);
96                     Log.d(TAG, "main switch bar = " + mainSwitchBar.isEnabled());
97 
98                     UiUtils.waitForActivitiesInStage(10000, Stage.RESUMED);
99                     Log.d(TAG, "In stage!.");
100 
101                     UiUtils.dumpView(UiUtils.getFirstViewFromActivity(activity));
102 
103                     // The privileges are under the recycle view. Fetch all of them and check.
104                     ViewGroup viewGroup = (ViewGroup) recyclerView;
105 
106                     for (int i = 0; i < viewGroup.getChildCount(); i++) {
107                         if (viewGroup.getChildAt(i) instanceof LinearLayout) {
108                             // A notification in Settings should have both switch_widget and text.
109                             // There has another circle pin is no belongs to Settings package.
110                             // But belongs to Switch in Android.
111                             View sWidget = viewGroup.getChildAt(i).findViewById(
112                                     CommonUtils.getResId("switchWidget"));
113                             TextView sText = viewGroup.getChildAt(i).findViewById(
114                                     android.R.id.title);
115                             if (sText != null && sWidget != null
116                                     && disabledList.stream().anyMatch(
117                                             str -> str.equals(sText.getText().toString().trim()))) {
118 
119                                 assertThat(sWidget.isEnabled()).isFalse();
120                             }
121                         }
122                     }
123                 }
124         );
125     }
126 }
127