Home | History | Annotate | Download | only in external
      1 /*
      2  * Copyright (C) 2015 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.systemui.qs.external;
     17 
     18 import static junit.framework.Assert.assertFalse;
     19 import static junit.framework.Assert.assertTrue;
     20 
     21 import static org.junit.Assert.assertEquals;
     22 import static org.mockito.Mockito.any;
     23 import static org.mockito.Mockito.anyInt;
     24 import static org.mockito.Mockito.anyString;
     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.content.ComponentName;
     31 import android.content.Intent;
     32 import android.content.pm.PackageInfo;
     33 import android.content.pm.ServiceInfo;
     34 import android.net.Uri;
     35 import android.os.Bundle;
     36 import android.os.Handler;
     37 import android.os.HandlerThread;
     38 import android.os.UserHandle;
     39 import android.service.quicksettings.IQSService;
     40 import android.service.quicksettings.IQSTileService;
     41 import android.service.quicksettings.Tile;
     42 import android.service.quicksettings.TileService;
     43 import android.support.test.runner.AndroidJUnit4;
     44 import android.test.suitebuilder.annotation.SmallTest;
     45 
     46 import com.android.systemui.SysuiTestCase;
     47 
     48 import org.junit.After;
     49 import org.junit.Before;
     50 import org.junit.Test;
     51 import org.junit.runner.RunWith;
     52 import org.mockito.Mockito;
     53 
     54 @SmallTest
     55 @RunWith(AndroidJUnit4.class)
     56 public class TileLifecycleManagerTest extends SysuiTestCase {
     57     private static final int TEST_FAIL_TIMEOUT = 5000;
     58 
     59     private final PackageManagerAdapter mMockPackageManagerAdapter =
     60             Mockito.mock(PackageManagerAdapter.class);
     61     private final IQSTileService.Stub mMockTileService = Mockito.mock(IQSTileService.Stub.class);
     62     private ComponentName mTileServiceComponentName;
     63     private Intent mTileServiceIntent;
     64     private UserHandle mUser;
     65     private HandlerThread mThread;
     66     private Handler mHandler;
     67     private TileLifecycleManager mStateManager;
     68 
     69     @Before
     70     public void setUp() throws Exception {
     71         setPackageEnabled(true);
     72         mTileServiceComponentName = new ComponentName(mContext, "FakeTileService.class");
     73 
     74         // Stub.asInterface will just return itself.
     75         when(mMockTileService.queryLocalInterface(anyString())).thenReturn(mMockTileService);
     76 
     77         mContext.addMockService(mTileServiceComponentName, mMockTileService);
     78 
     79 
     80         mTileServiceIntent = new Intent().setComponent(mTileServiceComponentName);
     81         mUser = new UserHandle(UserHandle.myUserId());
     82         mThread = new HandlerThread("TestThread");
     83         mThread.start();
     84         mHandler = Handler.createAsync(mThread.getLooper());
     85         mStateManager = new TileLifecycleManager(mHandler, mContext,
     86                 Mockito.mock(IQSService.class), new Tile(),
     87                 mTileServiceIntent,
     88                 mUser,
     89                 mMockPackageManagerAdapter);
     90     }
     91 
     92     @After
     93     public void tearDown() throws Exception {
     94         mThread.quit();
     95     }
     96 
     97     private void setPackageEnabled(boolean enabled) throws Exception {
     98         ServiceInfo defaultServiceInfo = null;
     99         if (enabled) {
    100             defaultServiceInfo = new ServiceInfo();
    101             defaultServiceInfo.metaData = new Bundle();
    102             defaultServiceInfo.metaData.putBoolean(TileService.META_DATA_ACTIVE_TILE, true);
    103         }
    104         when(mMockPackageManagerAdapter.getServiceInfo(any(), anyInt(), anyInt()))
    105                 .thenReturn(defaultServiceInfo);
    106         when(mMockPackageManagerAdapter.getServiceInfo(any(), anyInt()))
    107                 .thenReturn(defaultServiceInfo);
    108         PackageInfo defaultPackageInfo = new PackageInfo();
    109         when(mMockPackageManagerAdapter.getPackageInfoAsUser(anyString(), anyInt(), anyInt()))
    110                 .thenReturn(defaultPackageInfo);
    111     }
    112 
    113     private void verifyBind(int times) {
    114         assertEquals(times > 0, mContext.isBound(mTileServiceComponentName));
    115     }
    116 
    117     @Test
    118     public void testBind() {
    119         mStateManager.setBindService(true);
    120         verifyBind(1);
    121     }
    122 
    123     @Test
    124     public void testUnbind() {
    125         mStateManager.setBindService(true);
    126         mStateManager.setBindService(false);
    127         assertFalse(mContext.isBound(mTileServiceComponentName));
    128     }
    129 
    130     @Test
    131     public void testTileServiceCallbacks() throws Exception {
    132         mStateManager.setBindService(true);
    133         mStateManager.onTileAdded();
    134         verify(mMockTileService).onTileAdded();
    135         mStateManager.onStartListening();
    136         verify(mMockTileService).onStartListening();
    137         mStateManager.onClick(null);
    138         verify(mMockTileService).onClick(null);
    139         mStateManager.onStopListening();
    140         verify(mMockTileService).onStopListening();
    141         mStateManager.onTileRemoved();
    142         verify(mMockTileService).onTileRemoved();
    143     }
    144 
    145     @Test
    146     public void testAddedBeforeBind() throws Exception {
    147         mStateManager.onTileAdded();
    148         mStateManager.setBindService(true);
    149 
    150         verifyBind(1);
    151         verify(mMockTileService).onTileAdded();
    152     }
    153 
    154     @Test
    155     public void testListeningBeforeBind() throws Exception {
    156         mStateManager.onTileAdded();
    157         mStateManager.onStartListening();
    158         mStateManager.setBindService(true);
    159 
    160         verifyBind(1);
    161         verify(mMockTileService).onTileAdded();
    162         verify(mMockTileService).onStartListening();
    163     }
    164 
    165     @Test
    166     public void testClickBeforeBind() throws Exception {
    167         mStateManager.onTileAdded();
    168         mStateManager.onStartListening();
    169         mStateManager.onClick(null);
    170         mStateManager.setBindService(true);
    171 
    172         verifyBind(1);
    173         verify(mMockTileService).onTileAdded();
    174         verify(mMockTileService).onStartListening();
    175         verify(mMockTileService).onClick(null);
    176     }
    177 
    178     @Test
    179     public void testListeningNotListeningBeforeBind() throws Exception {
    180         mStateManager.onTileAdded();
    181         mStateManager.onStartListening();
    182         mStateManager.onStopListening();
    183         mStateManager.setBindService(true);
    184 
    185         verifyBind(1);
    186         mStateManager.setBindService(false);
    187         assertFalse(mContext.isBound(mTileServiceComponentName));
    188         verify(mMockTileService, never()).onStartListening();
    189     }
    190 
    191     @Test
    192     public void testNoClickOfNotListeningAnymore() throws Exception {
    193         mStateManager.onTileAdded();
    194         mStateManager.onStartListening();
    195         mStateManager.onClick(null);
    196         mStateManager.onStopListening();
    197         mStateManager.setBindService(true);
    198 
    199         verifyBind(1);
    200         mStateManager.setBindService(false);
    201         assertFalse(mContext.isBound(mTileServiceComponentName));
    202         verify(mMockTileService, never()).onClick(null);
    203     }
    204 
    205     @Test
    206     public void testComponentEnabling() throws Exception {
    207         mStateManager.onTileAdded();
    208         mStateManager.onStartListening();
    209         setPackageEnabled(false);
    210         mStateManager.setBindService(true);
    211         // Package not available, not yet created.
    212         verifyBind(0);
    213 
    214         // Package is re-enabled.
    215         setPackageEnabled(true);
    216         mStateManager.onReceive(
    217                 mContext,
    218                 new Intent(
    219                         Intent.ACTION_PACKAGE_CHANGED,
    220                         Uri.fromParts(
    221                                 "package", mTileServiceComponentName.getPackageName(), null)));
    222         verifyBind(1);
    223     }
    224 
    225     @Test
    226     public void testKillProcess() throws Exception {
    227         mStateManager.onStartListening();
    228         mStateManager.setBindService(true);
    229         mStateManager.setBindRetryDelay(0);
    230         mStateManager.onServiceDisconnected(mTileServiceComponentName);
    231 
    232         // Guarantees mHandler has processed all messages.
    233         assertTrue(mHandler.runWithScissors(()->{}, TEST_FAIL_TIMEOUT));
    234 
    235         // Two calls: one for the first bind, one for the restart.
    236         verifyBind(2);
    237         verify(mMockTileService, times(2)).onStartListening();
    238     }
    239 }
    240