1 /*
2  * Copyright (C) 2016 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 package com.android.settingslib.core.instrumentation;
17 
18 import static com.android.settingslib.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
19 
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.anyInt;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.ArgumentMatchers.nullable;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.never;
26 import static org.mockito.Mockito.times;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.Activity;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.os.Bundle;
34 
35 import androidx.fragment.app.FragmentActivity;
36 
37 import com.android.internal.logging.nano.MetricsProto;
38 
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.mockito.Mock;
43 import org.mockito.MockitoAnnotations;
44 import org.robolectric.Robolectric;
45 import org.robolectric.RobolectricTestRunner;
46 import org.robolectric.android.controller.ActivityController;
47 
48 @RunWith(RobolectricTestRunner.class)
49 public class VisibilityLoggerMixinTest {
50 
51     @Mock
52     private MetricsFeatureProvider mMetricsFeature;
53 
54     private VisibilityLoggerMixin mMixin;
55 
56     @Before
init()57     public void init() {
58         MockitoAnnotations.initMocks(this);
59         mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC, mMetricsFeature);
60     }
61 
62     @Test
shouldLogVisibleOnResume()63     public void shouldLogVisibleOnResume() {
64         mMixin.onResume();
65 
66         verify(mMetricsFeature, times(1))
67                 .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.VIEW_UNKNOWN),
68                         eq(TestInstrumentable.TEST_METRIC), anyInt());
69     }
70 
71     @Test
shouldLogVisibleWithSource()72     public void shouldLogVisibleWithSource() {
73         final Intent sourceIntent = new Intent()
74                 .putExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY,
75                         MetricsProto.MetricsEvent.SETTINGS_GESTURES);
76         final Activity activity = mock(Activity.class);
77         when(activity.getIntent()).thenReturn(sourceIntent);
78         mMixin.setSourceMetricsCategory(activity);
79         mMixin.onResume();
80 
81         verify(mMetricsFeature, times(1))
82                 .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.SETTINGS_GESTURES),
83                         eq(TestInstrumentable.TEST_METRIC), anyInt());
84     }
85 
86     @Test
shouldLogHideOnPause()87     public void shouldLogHideOnPause() {
88         mMixin.onPause();
89 
90         verify(mMetricsFeature, times(1))
91                 .hidden(nullable(Context.class), eq(TestInstrumentable.TEST_METRIC), anyInt());
92     }
93 
94     @Test
shouldNotLogIfMetricsFeatureIsNull()95     public void shouldNotLogIfMetricsFeatureIsNull() {
96         mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC, null);
97         mMixin.onResume();
98         mMixin.onPause();
99 
100         verify(mMetricsFeature, never())
101                 .hidden(nullable(Context.class), anyInt(), anyInt());
102     }
103 
104     @Test
shouldNotLogIfMetricsCategoryIsUnknown()105     public void shouldNotLogIfMetricsCategoryIsUnknown() {
106         mMixin = new VisibilityLoggerMixin(METRICS_CATEGORY_UNKNOWN, mMetricsFeature);
107 
108         mMixin.onResume();
109         mMixin.onPause();
110 
111         verify(mMetricsFeature, never())
112                 .hidden(nullable(Context.class), anyInt(), anyInt());
113     }
114 
115     @Test
activityShouldBecomeVisibleAndHide()116     public void activityShouldBecomeVisibleAndHide() {
117         ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
118         TestActivity testActivity = ac.get();
119         MockitoAnnotations.initMocks(testActivity);
120         ac.create().start().resume();
121         verify(testActivity.mMetricsFeatureProvider, times(1)).visible(any(), anyInt(), anyInt(),
122                 anyInt());
123         ac.pause().stop().destroy();
124         verify(testActivity.mMetricsFeatureProvider, times(1)).hidden(any(), anyInt(), anyInt());
125     }
126 
127     public static class TestActivity extends FragmentActivity {
128         @Mock
129         MetricsFeatureProvider mMetricsFeatureProvider;
130 
131         @Override
onCreate(Bundle savedInstanceState)132         public void onCreate(Bundle savedInstanceState) {
133             VisibilityLoggerMixin mixin = new VisibilityLoggerMixin(
134                     TestInstrumentable.TEST_METRIC, mMetricsFeatureProvider);
135             getLifecycle().addObserver(mixin);
136             super.onCreate(savedInstanceState);
137         }
138     }
139 
140     private final class TestInstrumentable implements Instrumentable {
141 
142         private static final int TEST_METRIC = 12345;
143 
144         @Override
getMetricsCategory()145         public int getMetricsCategory() {
146             return TEST_METRIC;
147         }
148     }
149 }
150