Home | History | Annotate | Download | only in tileimpl
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
      5  * except in compliance with the License. You may obtain a copy of the License at
      6  *
      7  *      http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the
     10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     11  * KIND, either express or implied. See the License for the specific language governing
     12  * permissions and limitations under the License.
     13  */
     14 
     15 package com.android.systemui.qs.tileimpl;
     16 
     17 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK;
     18 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS;
     19 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK;
     20 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_POSITION;
     21 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE;
     22 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
     23 
     24 import static org.mockito.ArgumentMatchers.any;
     25 import static org.mockito.ArgumentMatchers.anyInt;
     26 import static org.mockito.ArgumentMatchers.eq;
     27 import static org.mockito.Matchers.argThat;
     28 import static org.mockito.Mockito.clearInvocations;
     29 import static org.mockito.Mockito.mock;
     30 import static org.mockito.Mockito.never;
     31 import static org.mockito.Mockito.spy;
     32 import static org.mockito.Mockito.verify;
     33 import static org.mockito.Mockito.when;
     34 
     35 import static java.lang.Thread.sleep;
     36 
     37 import android.content.Intent;
     38 import android.metrics.LogMaker;
     39 import android.support.test.filters.SmallTest;
     40 import android.support.test.InstrumentationRegistry;
     41 import android.testing.AndroidTestingRunner;
     42 import android.testing.TestableLooper;
     43 import android.testing.TestableLooper.RunWithLooper;
     44 
     45 import com.android.internal.logging.MetricsLogger;
     46 import com.android.systemui.Dependency;
     47 import com.android.systemui.SysuiTestCase;
     48 import com.android.systemui.plugins.qs.QSTile;
     49 import com.android.systemui.qs.QSHost;
     50 import com.android.systemui.qs.QSTileHost;
     51 
     52 import org.junit.Before;
     53 import org.junit.Ignore;
     54 import org.junit.Test;
     55 import org.junit.runner.RunWith;
     56 import org.mockito.ArgumentMatcher;
     57 
     58 @RunWith(AndroidTestingRunner.class)
     59 @RunWithLooper
     60 @SmallTest
     61 public class QSTileImplTest extends SysuiTestCase {
     62 
     63     public static final int POSITION = 14;
     64     private TestableLooper mTestableLooper;
     65     private TileImpl mTile;
     66     private QSTileHost mHost;
     67     private MetricsLogger mMetricsLogger;
     68 
     69     @Before
     70     public void setup() throws Exception {
     71         String spec = "spec";
     72         mTestableLooper = TestableLooper.get(this);
     73         mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
     74         mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
     75         mHost = mock(QSTileHost.class);
     76         when(mHost.indexOf(spec)).thenReturn(POSITION);
     77         when(mHost.getContext()).thenReturn(mContext.getBaseContext());
     78 
     79         mTile = spy(new TileImpl(mHost));
     80         mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
     81         mTile.setTileSpec(spec);
     82     }
     83 
     84     @Test
     85     public void testClick_Metrics() {
     86         mTile.click();
     87         verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
     88     }
     89 
     90     @Test
     91     public void testSecondaryClick_Metrics() {
     92         mTile.secondaryClick();
     93         verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
     94     }
     95 
     96     @Test
     97     public void testLongClick_Metrics() {
     98         mTile.longClick();
     99         verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS)));
    100     }
    101 
    102     @Test
    103     public void testPopulate() {
    104         LogMaker maker = mock(LogMaker.class);
    105         when(maker.setSubtype(anyInt())).thenReturn(maker);
    106         when(maker.addTaggedData(anyInt(), any())).thenReturn(maker);
    107         mTile.getState().value = true;
    108         mTile.populate(maker);
    109         verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1));
    110         verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
    111     }
    112 
    113     @Test
    114     @Ignore("flaky")
    115     public void testStaleTimeout() throws InterruptedException {
    116         when(mTile.getStaleTimeout()).thenReturn(5l);
    117         clearInvocations(mTile);
    118 
    119         mTile.handleRefreshState(null);
    120         mTestableLooper.processAllMessages();
    121         verify(mTile, never()).handleStale();
    122 
    123         sleep(10);
    124         mTestableLooper.processAllMessages();
    125         verify(mTile).handleStale();
    126     }
    127 
    128     @Test
    129     public void testStaleListening() {
    130         mTile.handleStale();
    131         mTestableLooper.processAllMessages();
    132         verify(mTile).handleSetListening(eq(true));
    133 
    134         mTile.handleRefreshState(null);
    135         mTestableLooper.processAllMessages();
    136         verify(mTile).handleSetListening(eq(false));
    137     }
    138 
    139     private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
    140 
    141         private final int mCategory;
    142         public String mInvalid;
    143 
    144         public TileLogMatcher(int category) {
    145             mCategory = category;
    146         }
    147 
    148         @Override
    149         public boolean matches(LogMaker arg) {
    150             if (arg.getCategory() != mCategory) {
    151                 mInvalid = "Expected category " + mCategory + " but was " + arg.getCategory();
    152                 return false;
    153             }
    154             if (arg.getType() != TYPE_ACTION) {
    155                 mInvalid = "Expected type " + TYPE_ACTION + " but was " + arg.getType();
    156                 return false;
    157             }
    158             if (arg.getSubtype() != mTile.getMetricsCategory()) {
    159                 mInvalid = "Expected subtype " + mTile.getMetricsCategory() + " but was "
    160                         + arg.getSubtype();
    161                 return false;
    162             }
    163             return true;
    164         }
    165 
    166         @Override
    167         public String toString() {
    168             return mInvalid;
    169         }
    170     }
    171 
    172     private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
    173         protected TileImpl(QSHost host) {
    174             super(host);
    175         }
    176 
    177         @Override
    178         public BooleanState newTileState() {
    179             return new BooleanState();
    180         }
    181 
    182         @Override
    183         protected void handleClick() {
    184 
    185         }
    186 
    187         @Override
    188         protected void handleUpdateState(BooleanState state, Object arg) {
    189 
    190         }
    191 
    192         @Override
    193         public int getMetricsCategory() {
    194             return 42;
    195         }
    196 
    197         @Override
    198         public Intent getLongClickIntent() {
    199             return null;
    200         }
    201 
    202         @Override
    203         protected void handleSetListening(boolean listening) {
    204 
    205         }
    206 
    207         @Override
    208         public CharSequence getTileLabel() {
    209             return null;
    210         }
    211     }
    212 }
    213