Home | History | Annotate | Download | only in notifications
      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 
     17 package com.android.cts.verifier.notifications;
     18 
     19 import com.android.cts.verifier.R;
     20 
     21 import android.app.ActivityManager;
     22 import android.app.AutomaticZenRule;
     23 import android.app.NotificationManager;
     24 import android.content.ComponentName;
     25 import android.content.Context;
     26 import android.content.Intent;
     27 import android.net.Uri;
     28 import android.provider.Settings;
     29 import android.text.TextUtils;
     30 import android.util.Log;
     31 import android.view.View;
     32 import android.view.ViewGroup;
     33 
     34 import java.util.ArrayList;
     35 import java.util.List;
     36 import java.util.Map;
     37 import java.util.Objects;
     38 
     39 public class ConditionProviderVerifierActivity extends InteractiveVerifierActivity
     40         implements Runnable {
     41     protected static final String CP_PACKAGE = "com.android.cts.verifier";
     42     protected static final String CP_PATH = CP_PACKAGE +
     43             "/com.android.cts.verifier.notifications.MockConditionProvider";
     44 
     45     @Override
     46     protected int getTitleResource() {
     47         return R.string.cp_test;
     48     }
     49 
     50     @Override
     51     protected int getInstructionsResource() {
     52         return R.string.cp_info;
     53     }
     54 
     55     // Test Setup
     56 
     57     @Override
     58     protected List<InteractiveTestCase> createTestItems() {
     59         List<InteractiveTestCase> tests = new ArrayList<>(9);
     60         ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
     61         if (am.isLowRamDevice()) {
     62             tests.add(new CannotBeEnabledTest());
     63             tests.add(new ServiceStoppedTest());
     64         } else {
     65             tests.add(new IsEnabledTest());
     66             tests.add(new ServiceStartedTest());
     67             tests.add(new CreateAutomaticZenRuleTest());
     68             tests.add(new UpdateAutomaticZenRuleTest());
     69             tests.add(new GetAutomaticZenRuleTest());
     70             tests.add(new GetAutomaticZenRulesTest());
     71             tests.add(new SubscribeAutomaticZenRuleTest());
     72             tests.add(new DeleteAutomaticZenRuleTest());
     73             tests.add(new UnsubscribeAutomaticZenRuleTest());
     74             tests.add(new RequestUnbindTest());
     75             tests.add(new RequestBindTest());
     76             tests.add(new IsDisabledTest());
     77             tests.add(new ServiceStoppedTest());
     78         }
     79         return tests;
     80     }
     81 
     82     protected class IsEnabledTest extends InteractiveTestCase {
     83         @Override
     84         protected View inflate(ViewGroup parent) {
     85             return createSettingsItem(parent, R.string.cp_enable_service);
     86         }
     87 
     88         @Override
     89         boolean autoStart() {
     90             return true;
     91         }
     92 
     93         @Override
     94         protected void test() {
     95             Intent settings = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
     96             if (settings.resolveActivity(mPackageManager) == null) {
     97                 logFail("no settings activity");
     98                 status = FAIL;
     99             } else {
    100                 if (mNm.isNotificationPolicyAccessGranted()) {
    101                     status = PASS;
    102                 } else {
    103                     status = WAIT_FOR_USER;
    104                 }
    105                 next();
    106             }
    107         }
    108 
    109         protected void tearDown() {
    110             // wait for the service to start
    111             delay();
    112         }
    113 
    114         @Override
    115         protected Intent getIntent() {
    116             return new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
    117         }
    118     }
    119 
    120     protected class CannotBeEnabledTest extends InteractiveTestCase {
    121         @Override
    122         protected View inflate(ViewGroup parent) {
    123             return createNlsSettingsItem(parent, R.string.cp_cannot_enable_service);
    124         }
    125 
    126         @Override
    127         boolean autoStart() {
    128             return true;
    129         }
    130 
    131         @Override
    132         protected void test() {
    133             mNm.cancelAll();
    134             Intent settings = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
    135             if (settings.resolveActivity(mPackageManager) == null) {
    136                 logFail("no settings activity");
    137                 status = FAIL;
    138             } else {
    139                 if (mNm.isNotificationPolicyAccessGranted()) {
    140                     status = FAIL;
    141                 } else {
    142                     status = PASS;
    143                 }
    144                 next();
    145             }
    146         }
    147 
    148         protected void tearDown() {
    149             // wait for the service to start
    150             delay();
    151         }
    152 
    153         @Override
    154         protected Intent getIntent() {
    155             return new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
    156         }
    157     }
    158 
    159     protected class ServiceStartedTest extends InteractiveTestCase {
    160         int mRetries = 5;
    161         @Override
    162         protected View inflate(ViewGroup parent) {
    163             return createAutoItem(parent, R.string.cp_service_started);
    164         }
    165 
    166         @Override
    167         protected void test() {
    168             if (MockConditionProvider.getInstance().isConnected()
    169                     && MockConditionProvider.getInstance().isBound()) {
    170                 status = PASS;
    171                 next();
    172             } else {
    173                 if (--mRetries > 0) {
    174                     status = RETEST;
    175                     next();
    176                 } else {
    177                     logFail();
    178                     status = FAIL;
    179                 }
    180             }
    181         }
    182     }
    183 
    184     private class RequestUnbindTest extends InteractiveTestCase {
    185         int mRetries = 5;
    186 
    187         @Override
    188         protected View inflate(ViewGroup parent) {
    189             return createAutoItem(parent, R.string.nls_snooze);
    190 
    191         }
    192 
    193         @Override
    194         protected void setUp() {
    195             status = READY;
    196         }
    197 
    198         @Override
    199         protected void test() {
    200             if (status == READY) {
    201                 MockConditionProvider.getInstance().requestUnbind();
    202                 status = RETEST;
    203             } else {
    204                 if (MockConditionProvider.getInstance() == null ||
    205                         !MockConditionProvider.getInstance().isConnected()) {
    206                     status = PASS;
    207                 } else {
    208                     if (--mRetries > 0) {
    209                         status = RETEST;
    210                     } else {
    211                         logFail();
    212                         status = FAIL;
    213                     }
    214                 }
    215                 next();
    216             }
    217         }
    218     }
    219 
    220     private class RequestBindTest extends InteractiveTestCase {
    221         int mRetries = 5;
    222 
    223         @Override
    224         protected View inflate(ViewGroup parent) {
    225             return createAutoItem(parent, R.string.nls_unsnooze);
    226 
    227         }
    228 
    229         @Override
    230         protected void test() {
    231             if (status == READY) {
    232                 MockConditionProvider.requestRebind(MockConditionProvider.COMPONENT_NAME);
    233                 status = RETEST;
    234             } else {
    235                 if (MockConditionProvider.getInstance().isConnected()
    236                         && MockConditionProvider.getInstance().isBound()) {
    237                     status = PASS;
    238                     next();
    239                 } else {
    240                     if (--mRetries > 0) {
    241                         status = RETEST;
    242                         next();
    243                     } else {
    244                         logFail();
    245                         status = FAIL;
    246                     }
    247                 }
    248             }
    249         }
    250     }
    251 
    252 
    253     private class CreateAutomaticZenRuleTest extends InteractiveTestCase {
    254         private String id = null;
    255 
    256         @Override
    257         protected View inflate(ViewGroup parent) {
    258             return createAutoItem(parent, R.string.cp_create_rule);
    259         }
    260 
    261         @Override
    262         protected void test() {
    263             AutomaticZenRule ruleToCreate =
    264                     createRule("Rule", "value", NotificationManager.INTERRUPTION_FILTER_ALARMS);
    265             id = mNm.addAutomaticZenRule(ruleToCreate);
    266 
    267             if (!TextUtils.isEmpty(id)) {
    268                 status = PASS;
    269             } else {
    270                 logFail();
    271                 status = FAIL;
    272             }
    273             next();
    274         }
    275 
    276         @Override
    277         protected void tearDown() {
    278             if (id != null) {
    279                 mNm.removeAutomaticZenRule(id);
    280             }
    281             MockConditionProvider.getInstance().resetData();
    282         }
    283     }
    284 
    285     private class UpdateAutomaticZenRuleTest extends InteractiveTestCase {
    286         private String id = null;
    287 
    288         @Override
    289         protected View inflate(ViewGroup parent) {
    290             return createAutoItem(parent, R.string.cp_update_rule);
    291         }
    292 
    293         @Override
    294         protected void setUp() {
    295             id = mNm.addAutomaticZenRule(createRule("BeforeUpdate", "beforeValue",
    296                     NotificationManager.INTERRUPTION_FILTER_ALARMS));
    297             status = READY;
    298             delay();
    299         }
    300 
    301         @Override
    302         protected void test() {
    303             AutomaticZenRule updated = mNm.getAutomaticZenRule(id);
    304             updated.setName("AfterUpdate");
    305             updated.setConditionId(MockConditionProvider.toConditionId("afterValue"));
    306             updated.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
    307 
    308             try {
    309                 boolean success = mNm.updateAutomaticZenRule(id, updated);
    310                 if (success && updated.equals(mNm.getAutomaticZenRule(id))) {
    311                     status = PASS;
    312                 } else {
    313                     logFail();
    314                     status = FAIL;
    315                 }
    316             } catch (Exception e) {
    317                 logFail("update failed", e);
    318                 status = FAIL;
    319             }
    320             next();
    321         }
    322 
    323         @Override
    324         protected void tearDown() {
    325             if (id != null) {
    326                 mNm.removeAutomaticZenRule(id);
    327             }
    328             MockConditionProvider.getInstance().resetData();
    329         }
    330     }
    331 
    332     private class SubscribeAutomaticZenRuleTest extends InteractiveTestCase {
    333         private String id = null;
    334         private AutomaticZenRule ruleToCreate;
    335         private int mRetries = 3;
    336 
    337         @Override
    338         protected View inflate(ViewGroup parent) {
    339             return createAutoItem(parent, R.string.cp_subscribe_rule);
    340         }
    341 
    342         @Override
    343         protected void setUp() {
    344             ruleToCreate = createRule("RuleSubscribe", "Subscribevalue",
    345                     NotificationManager.INTERRUPTION_FILTER_ALARMS);
    346             id = mNm.addAutomaticZenRule(ruleToCreate);
    347             status = READY;
    348             delay();
    349         }
    350 
    351         @Override
    352         protected void test() {
    353             boolean foundMatch = false;
    354             List<Uri> subscriptions = MockConditionProvider.getInstance().getSubscriptions();
    355             for (Uri actual : subscriptions) {
    356                 if (ruleToCreate.getConditionId().equals(actual)) {
    357                     status = PASS;
    358                     foundMatch = true;
    359                     break;
    360                 }
    361             }
    362             if (foundMatch) {
    363                 status = PASS;
    364                 next();
    365             } else if (--mRetries > 0) {
    366                 setFailed();
    367             } else {
    368                 status = RETEST;
    369                 next();
    370             }
    371         }
    372 
    373         @Override
    374         protected void tearDown() {
    375             if (id != null) {
    376                 mNm.removeAutomaticZenRule(id);
    377             }
    378             MockConditionProvider.getInstance().resetData();
    379         }
    380     }
    381 
    382     private class GetAutomaticZenRuleTest extends InteractiveTestCase {
    383         private String id = null;
    384         private AutomaticZenRule ruleToCreate;
    385 
    386         @Override
    387         protected View inflate(ViewGroup parent) {
    388             return createAutoItem(parent, R.string.cp_get_rule);
    389         }
    390 
    391         @Override
    392         protected void setUp() {
    393             ruleToCreate = createRule("RuleGet", "valueGet",
    394                     NotificationManager.INTERRUPTION_FILTER_ALARMS);
    395             id = mNm.addAutomaticZenRule(ruleToCreate);
    396             status = READY;
    397             delay();
    398         }
    399 
    400         @Override
    401         protected void test() {
    402             AutomaticZenRule queriedRule = mNm.getAutomaticZenRule(id);
    403             if (queriedRule != null
    404                     && ruleToCreate.getName().equals(queriedRule.getName())
    405                     && ruleToCreate.getOwner().equals(queriedRule.getOwner())
    406                     && ruleToCreate.getConditionId().equals(queriedRule.getConditionId())
    407                     && ruleToCreate.isEnabled() == queriedRule.isEnabled()) {
    408                 status = PASS;
    409             } else {
    410                 logFail();
    411                 status = FAIL;
    412             }
    413             next();
    414         }
    415 
    416         @Override
    417         protected void tearDown() {
    418             if (id != null) {
    419                 mNm.removeAutomaticZenRule(id);
    420             }
    421             MockConditionProvider.getInstance().resetData();
    422         }
    423     }
    424 
    425     private class GetAutomaticZenRulesTest extends InteractiveTestCase {
    426         private List<String> ids = new ArrayList<>();
    427         private AutomaticZenRule rule1;
    428         private AutomaticZenRule rule2;
    429 
    430         @Override
    431         protected View inflate(ViewGroup parent) {
    432             return createAutoItem(parent, R.string.cp_get_rules);
    433         }
    434 
    435         @Override
    436         protected void setUp() {
    437             rule1 = createRule("Rule1", "value1", NotificationManager.INTERRUPTION_FILTER_ALARMS);
    438             rule2 = createRule("Rule2", "value2", NotificationManager.INTERRUPTION_FILTER_NONE);
    439             ids.add(mNm.addAutomaticZenRule(rule1));
    440             ids.add(mNm.addAutomaticZenRule(rule2));
    441             status = READY;
    442             delay();
    443         }
    444 
    445         @Override
    446         protected void test() {
    447             Map<String, AutomaticZenRule> rules = mNm.getAutomaticZenRules();
    448 
    449             if (rules == null || rules.size() != 2) {
    450                 logFail();
    451                 status = FAIL;
    452                 next();
    453                 return;
    454             }
    455 
    456             for (AutomaticZenRule createdRule : rules.values()) {
    457                 if (!compareRules(createdRule, rule1) && !compareRules(createdRule, rule2)) {
    458                     logFail();
    459                     status = FAIL;
    460                     break;
    461                 }
    462             }
    463             status = PASS;
    464             next();
    465         }
    466 
    467         @Override
    468         protected void tearDown() {
    469             for (String id : ids) {
    470                 mNm.removeAutomaticZenRule(id);
    471             }
    472             MockConditionProvider.getInstance().resetData();
    473         }
    474     }
    475 
    476     private class DeleteAutomaticZenRuleTest extends InteractiveTestCase {
    477         private String id = null;
    478 
    479         @Override
    480         protected View inflate(ViewGroup parent) {
    481             return createAutoItem(parent, R.string.cp_delete_rule);
    482         }
    483 
    484         @Override
    485         protected void test() {
    486             AutomaticZenRule ruleToCreate = createRule("RuleDelete", "Deletevalue",
    487                     NotificationManager.INTERRUPTION_FILTER_ALARMS);
    488             id = mNm.addAutomaticZenRule(ruleToCreate);
    489 
    490             if (id != null) {
    491                 if (mNm.removeAutomaticZenRule(id)) {
    492                     if (mNm.getAutomaticZenRule(id) == null) {
    493                         status = PASS;
    494                     } else {
    495                         logFail();
    496                         status = FAIL;
    497                     }
    498                 } else {
    499                     logFail();
    500                     status = FAIL;
    501                 }
    502             } else {
    503                 logFail("Couldn't test rule deletion; creation failed.");
    504                 status = FAIL;
    505             }
    506             next();
    507         }
    508 
    509         @Override
    510         protected void tearDown() {
    511             MockConditionProvider.getInstance().resetData();
    512             delay();
    513         }
    514     }
    515 
    516     private class UnsubscribeAutomaticZenRuleTest extends InteractiveTestCase {
    517         private String id = null;
    518         private AutomaticZenRule ruleToCreate;
    519         private int mSubscribeRetries = 3;
    520         private int mUnsubscribeRetries = 3;
    521         private boolean mSubscribing = true;
    522 
    523         @Override
    524         protected View inflate(ViewGroup parent) {
    525             return createAutoItem(parent, R.string.cp_unsubscribe_rule);
    526         }
    527 
    528         @Override
    529         protected void setUp() {
    530             ruleToCreate = createRule("RuleUnsubscribe", "valueUnsubscribe",
    531                     NotificationManager.INTERRUPTION_FILTER_PRIORITY);
    532             id = mNm.addAutomaticZenRule(ruleToCreate);
    533             status = READY;
    534             delay();
    535         }
    536 
    537         @Override
    538         protected void test() {
    539             if (mSubscribing) {
    540                 // trying to subscribe
    541                 boolean foundMatch = false;
    542                 List<Uri> subscriptions = MockConditionProvider.getInstance().getSubscriptions();
    543                 for (Uri actual : subscriptions) {
    544                     if (ruleToCreate.getConditionId().equals(actual)) {
    545                         status = PASS;
    546                         foundMatch = true;
    547                         break;
    548                     }
    549                 }
    550                 if (foundMatch) {
    551                     // Now that it's subscribed, remove the rule and verify that it
    552                     // unsubscribes.
    553                     Log.d(MockConditionProvider.TAG, "Found subscription, removing");
    554                     mNm.removeAutomaticZenRule(id);
    555 
    556                     mSubscribing = false;
    557                     status = RETEST;
    558                     next();
    559                 } else if (--mSubscribeRetries > 0) {
    560                     setFailed();
    561                 } else {
    562                     status = RETEST;
    563                     next();
    564                 }
    565             } else {
    566                 // trying to unsubscribe
    567                 List<Uri> continuingSubscriptions
    568                         = MockConditionProvider.getInstance().getSubscriptions();
    569                 boolean stillFoundMatch = false;
    570                 for (Uri actual : continuingSubscriptions) {
    571                     if (ruleToCreate.getConditionId().equals(actual)) {
    572                         stillFoundMatch = true;
    573                         break;
    574                     }
    575                 }
    576                 if (!stillFoundMatch) {
    577                     status = PASS;
    578                     next();
    579                 } else if (stillFoundMatch && --mUnsubscribeRetries > 0) {
    580                     Log.d(MockConditionProvider.TAG, "Still found subscription, retrying");
    581                     status = RETEST;
    582                     next();
    583                 } else {
    584                     setFailed();
    585                 }
    586             }
    587         }
    588 
    589         @Override
    590         protected void tearDown() {
    591             mNm.removeAutomaticZenRule(id);
    592             MockConditionProvider.getInstance().resetData();
    593         }
    594     }
    595 
    596     private class IsDisabledTest extends InteractiveTestCase {
    597         @Override
    598         protected View inflate(ViewGroup parent) {
    599             return createSettingsItem(parent, R.string.cp_disable_service);
    600         }
    601 
    602         @Override
    603         boolean autoStart() {
    604             return true;
    605         }
    606 
    607         @Override
    608         protected void test() {
    609             if (!mNm.isNotificationPolicyAccessGranted()) {
    610                 status = PASS;
    611             } else {
    612                 status = WAIT_FOR_USER;
    613             }
    614             next();
    615         }
    616 
    617         @Override
    618         protected Intent getIntent() {
    619             return new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
    620         }
    621     }
    622 
    623     private class ServiceStoppedTest extends InteractiveTestCase {
    624         int mRetries = 5;
    625 
    626         @Override
    627         protected View inflate(ViewGroup parent) {
    628             return createAutoItem(parent, R.string.cp_service_stopped);
    629         }
    630 
    631         @Override
    632         protected void test() {
    633             if (MockConditionProvider.getInstance() == null ||
    634                     !MockConditionProvider.getInstance().isConnected()) {
    635                 status = PASS;
    636             } else {
    637                 if (--mRetries > 0) {
    638                     status = RETEST;
    639                 } else {
    640                     logFail();
    641                     status = FAIL;
    642                 }
    643             }
    644             next();
    645         }
    646     }
    647 
    648     private AutomaticZenRule createRule(String name, String queryValue, int status) {
    649         return new AutomaticZenRule(name,
    650                 ComponentName.unflattenFromString(CP_PATH),
    651                 MockConditionProvider.toConditionId(queryValue),
    652                 status,
    653                 true);
    654     }
    655 
    656     private boolean compareRules(AutomaticZenRule rule1, AutomaticZenRule rule2) {
    657         return rule1.isEnabled() == rule2.isEnabled()
    658                 && Objects.equals(rule1.getName(), rule2.getName())
    659                 && rule1.getInterruptionFilter() == rule2.getInterruptionFilter()
    660                 && Objects.equals(rule1.getConditionId(), rule2.getConditionId())
    661                 && Objects.equals(rule1.getOwner(), rule2.getOwner());
    662     }
    663 
    664     protected View createSettingsItem(ViewGroup parent, int messageId) {
    665         return createUserItem(parent, R.string.cp_start_settings, messageId);
    666     }
    667 }
    668