Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2014 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 android.media.tv.cts;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Context;
     21 import android.content.pm.PackageManager;
     22 import android.media.tv.TvContentRating;
     23 import android.media.tv.TvInputInfo;
     24 import android.media.tv.TvInputManager;
     25 import android.media.tv.TvInputService;
     26 import android.os.Handler;
     27 import android.test.ActivityInstrumentationTestCase2;
     28 
     29 import com.android.compatibility.common.util.PollingCheck;
     30 
     31 import java.io.IOException;
     32 import java.util.ArrayList;
     33 import java.util.List;
     34 
     35 import org.xmlpull.v1.XmlPullParserException;
     36 
     37 /**
     38  * Test for {@link android.media.tv.TvInputManager}.
     39  */
     40 public class TvInputManagerTest extends ActivityInstrumentationTestCase2<TvViewStubActivity> {
     41     /** The maximum time to wait for an operation. */
     42     private static final long TIME_OUT_MS = 15000L;
     43 
     44     private static final String[] VALID_TV_INPUT_SERVICES = {
     45         StubTunerTvInputService.class.getName()
     46     };
     47     private static final String[] INVALID_TV_INPUT_SERVICES = {
     48         NoMetadataTvInputService.class.getName(), NoPermissionTvInputService.class.getName()
     49     };
     50     private static final TvContentRating DUMMY_RATING = TvContentRating.createRating(
     51             "com.android.tv", "US_TV", "US_TV_PG", "US_TV_D", "US_TV_L");
     52 
     53     private String mStubId;
     54     private TvInputManager mManager;
     55     private LoggingCallback mCallback = new LoggingCallback();
     56 
     57     private static TvInputInfo getInfoForClassName(List<TvInputInfo> list, String name) {
     58         for (TvInputInfo info : list) {
     59             if (info.getServiceInfo().name.equals(name)) {
     60                 return info;
     61             }
     62         }
     63         return null;
     64     }
     65 
     66     public TvInputManagerTest() {
     67         super(TvViewStubActivity.class);
     68     }
     69 
     70     @Override
     71     public void setUp() throws Exception {
     72         if (!Utils.hasTvInputFramework(getActivity())) {
     73             return;
     74         }
     75         mManager = (TvInputManager) getActivity().getSystemService(Context.TV_INPUT_SERVICE);
     76         mStubId = getInfoForClassName(
     77                 mManager.getTvInputList(), StubTvInputService2.class.getName()).getId();
     78     }
     79 
     80     public void testGetInputState() throws Exception {
     81         if (!Utils.hasTvInputFramework(getActivity())) {
     82             return;
     83         }
     84         assertEquals(mManager.getInputState(mStubId), TvInputManager.INPUT_STATE_CONNECTED);
     85     }
     86 
     87     public void testGetTvInputInfo() throws Exception {
     88         if (!Utils.hasTvInputFramework(getActivity())) {
     89             return;
     90         }
     91         TvInputInfo expected = mManager.getTvInputInfo(mStubId);
     92         TvInputInfo actual = getInfoForClassName(mManager.getTvInputList(),
     93                 StubTvInputService2.class.getName());
     94         assertTrue("expected=" + expected + " actual=" + actual,
     95                 TvInputInfoTest.compareTvInputInfos(getActivity(), expected, actual));
     96     }
     97 
     98     public void testGetTvInputList() throws Exception {
     99         if (!Utils.hasTvInputFramework(getActivity())) {
    100             return;
    101         }
    102         List<TvInputInfo> list = mManager.getTvInputList();
    103         for (String name : VALID_TV_INPUT_SERVICES) {
    104             assertNotNull("getTvInputList() doesn't contain valid input: " + name,
    105                     getInfoForClassName(list, name));
    106         }
    107         for (String name : INVALID_TV_INPUT_SERVICES) {
    108             assertNull("getTvInputList() contains invalind input: " + name,
    109                     getInfoForClassName(list, name));
    110         }
    111     }
    112 
    113     public void testIsParentalControlsEnabled() {
    114         if (!Utils.hasTvInputFramework(getActivity())) {
    115             return;
    116         }
    117         try {
    118             mManager.isParentalControlsEnabled();
    119         } catch (Exception e) {
    120             fail();
    121         }
    122     }
    123 
    124     public void testIsRatingBlocked() {
    125         if (!Utils.hasTvInputFramework(getActivity())) {
    126             return;
    127         }
    128         try {
    129             mManager.isRatingBlocked(DUMMY_RATING);
    130         } catch (Exception e) {
    131             fail();
    132         }
    133     }
    134 
    135     public void testRegisterUnregisterCallback() {
    136         if (!Utils.hasTvInputFramework(getActivity())) {
    137             return;
    138         }
    139         getActivity().runOnUiThread(new Runnable() {
    140             @Override
    141             public void run() {
    142                 try {
    143                     mManager.registerCallback(mCallback, new Handler());
    144                     mManager.unregisterCallback(mCallback);
    145                 } catch (Exception e) {
    146                     fail();
    147                 }
    148             }
    149         });
    150         getInstrumentation().waitForIdleSync();
    151     }
    152 
    153     public void testInputAddedAndRemoved() {
    154         if (!Utils.hasTvInputFramework(getActivity())) {
    155             return;
    156         }
    157         getActivity().runOnUiThread(new Runnable() {
    158             @Override
    159             public void run() {
    160                 mManager.registerCallback(mCallback, new Handler());
    161             }
    162         });
    163         getInstrumentation().waitForIdleSync();
    164 
    165         // Test if onInputRemoved() is called.
    166         mCallback.resetLogs();
    167         PackageManager pm = getActivity().getPackageManager();
    168         ComponentName component = new ComponentName(getActivity(), StubTvInputService2.class);
    169         assertTrue(PackageManager.COMPONENT_ENABLED_STATE_DISABLED != pm.getComponentEnabledSetting(
    170                 component));
    171         pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
    172                 PackageManager.DONT_KILL_APP);
    173         new PollingCheck(TIME_OUT_MS) {
    174             @Override
    175             protected boolean check() {
    176                 return mCallback.isInputRemoved(mStubId);
    177             }
    178         }.run();
    179 
    180         // Test if onInputAdded() is called.
    181         mCallback.resetLogs();
    182         assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, pm.getComponentEnabledSetting(
    183                 component));
    184         pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
    185                 PackageManager.DONT_KILL_APP);
    186         new PollingCheck(TIME_OUT_MS) {
    187             @Override
    188             protected boolean check() {
    189                 return mCallback.isInputAdded(mStubId);
    190             }
    191         }.run();
    192 
    193         getActivity().runOnUiThread(new Runnable() {
    194             @Override
    195             public void run() {
    196                 mManager.unregisterCallback(mCallback);
    197             }
    198         });
    199         getInstrumentation().waitForIdleSync();
    200     }
    201 
    202     public void testTvInputInfoUpdated() throws IOException, XmlPullParserException {
    203         if (!Utils.hasTvInputFramework(getActivity())) {
    204             return;
    205         }
    206         getActivity().runOnUiThread(new Runnable() {
    207             @Override
    208             public void run() {
    209                 mManager.registerCallback(mCallback, new Handler());
    210             }
    211         });
    212         getInstrumentation().waitForIdleSync();
    213 
    214         mCallback.resetLogs();
    215         TvInputInfo defaultInfo = new TvInputInfo.Builder(getActivity(),
    216                 new ComponentName(getActivity(), StubTunerTvInputService.class)).build();
    217         TvInputInfo updatedInfo = new TvInputInfo.Builder(getActivity(),
    218                 new ComponentName(getActivity(), StubTunerTvInputService.class))
    219                         .setTunerCount(10).setCanRecord(true).build();
    220 
    221         mManager.updateTvInputInfo(updatedInfo);
    222         new PollingCheck(TIME_OUT_MS) {
    223             @Override
    224             protected boolean check() {
    225                 TvInputInfo info = mCallback.getLastUpdatedTvInputInfo();
    226                 return info !=  null && info.getTunerCount() == 10 && info.canRecord();
    227             }
    228         }.run();
    229 
    230         mManager.updateTvInputInfo(defaultInfo);
    231         new PollingCheck(TIME_OUT_MS) {
    232             @Override
    233             protected boolean check() {
    234                 TvInputInfo info = mCallback.getLastUpdatedTvInputInfo();
    235                 return info !=  null && info.getTunerCount() == 1 && !info.canRecord();
    236             }
    237         }.run();
    238 
    239         getActivity().runOnUiThread(new Runnable() {
    240             @Override
    241             public void run() {
    242                 mManager.unregisterCallback(mCallback);
    243             }
    244         });
    245         getInstrumentation().waitForIdleSync();
    246     }
    247 
    248     private static class LoggingCallback extends TvInputManager.TvInputCallback {
    249         private final List<String> mAddedInputs = new ArrayList<>();
    250         private final List<String> mRemovedInputs = new ArrayList<>();
    251         private TvInputInfo mLastUpdatedTvInputInfo;
    252 
    253         @Override
    254         public synchronized void onInputAdded(String inputId) {
    255             mAddedInputs.add(inputId);
    256         }
    257 
    258         @Override
    259         public synchronized void onInputRemoved(String inputId) {
    260             mRemovedInputs.add(inputId);
    261         }
    262 
    263         @Override
    264         public synchronized void onTvInputInfoUpdated(TvInputInfo info) {
    265             mLastUpdatedTvInputInfo = info;
    266         }
    267 
    268         public synchronized void resetLogs() {
    269             mAddedInputs.clear();
    270             mRemovedInputs.clear();
    271             mLastUpdatedTvInputInfo = null;
    272         }
    273 
    274         public synchronized boolean isInputAdded(String inputId) {
    275             return mRemovedInputs.isEmpty() && mAddedInputs.size() == 1 && mAddedInputs.contains(
    276                     inputId);
    277         }
    278 
    279         public synchronized boolean isInputRemoved(String inputId) {
    280             return mAddedInputs.isEmpty() && mRemovedInputs.size() == 1 && mRemovedInputs.contains(
    281                     inputId);
    282         }
    283 
    284         public synchronized TvInputInfo getLastUpdatedTvInputInfo() {
    285             return mLastUpdatedTvInputInfo;
    286         }
    287     }
    288 
    289     public static class StubTvInputService2 extends StubTvInputService {
    290         @Override
    291         public Session onCreateSession(String inputId) {
    292             return null;
    293         }
    294     }
    295 }
    296