Home | History | Annotate | Download | only in publisher4
      1 /*
      2  * Copyright (C) 2017 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 android.content.pm.cts.shortcut.backup.publisher4;
     17 
     18 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
     19 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
     20 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
     21 
     22 import android.app.PendingIntent;
     23 import android.content.BroadcastReceiver;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.IntentFilter;
     27 import android.content.pm.ShortcutInfo;
     28 import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
     29 import android.os.PersistableBundle;
     30 import android.text.TextUtils;
     31 
     32 import java.security.SecureRandom;
     33 import java.util.concurrent.CountDownLatch;
     34 import java.util.concurrent.TimeUnit;
     35 
     36 public class ShortcutManagerPostBackupTest extends ShortcutManagerDeviceTestBase {
     37     public void testRestoredOnOldVersion() {
     38         assertWith(getManager().getDynamicShortcuts())
     39                 .isEmpty();
     40 
     41         assertWith(getManager().getPinnedShortcuts())
     42                 .haveIds("ms1", "ms2")
     43                 .areAllEnabled();
     44 
     45         assertWith(getManager().getManifestShortcuts())
     46                 .haveIds("ms1", "ms2")
     47                 .areAllPinned()
     48                 .areAllEnabled();
     49 
     50         // At this point, s1 and s2 don't look to exist to the publisher, so it can publish a
     51         // dynamic shortcut and that should work.
     52         // But updateShortcuts() don't.
     53 
     54         final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
     55                 .setShortLabel("shortlabel1_new_one")
     56                 .setActivity(getActivity("MainActivity"))
     57                 .setIntents(new Intent[]{new Intent("main")})
     58                 .build();
     59 
     60         assertTrue(getManager().addDynamicShortcuts(list(s1)));
     61 
     62         final ShortcutInfo s2 = new ShortcutInfo.Builder(getContext(), "s2")
     63                 .setShortLabel("shortlabel2_updated")
     64                 .build();
     65         assertTrue(getManager().updateShortcuts(list(s2)));
     66 
     67         assertWith(getManager().getDynamicShortcuts())
     68                 .haveIds("s1") // s2 not in the list.
     69                 .areAllEnabled();
     70 
     71         assertWith(getManager().getPinnedShortcuts())
     72                 .haveIds("ms1", "ms2", "s1") // s2 not in the list.
     73                 .areAllEnabled();
     74 
     75     }
     76 
     77     public void testRestoredOnNewVersion() {
     78         assertWith(getManager().getDynamicShortcuts())
     79                 .haveIds("s1")
     80                 .areAllEnabled()
     81                 .areAllPinned();
     82 
     83         assertWith(getManager().getManifestShortcuts())
     84                 .haveIds("ms1", "ms2")
     85                 .areAllPinned()
     86                 .areAllEnabled();
     87 
     88         assertWith(getManager().getPinnedShortcuts())
     89                 .haveIds("ms1", "ms2", "s1", "s2")
     90                 .areAllEnabled();
     91 
     92         // This time, update should work.
     93         final ShortcutInfo s2 = new ShortcutInfo.Builder(getContext(), "s2")
     94                 .setShortLabel("shortlabel2_updated")
     95                 .build();
     96         assertTrue(getManager().updateShortcuts(list(s2)));
     97 
     98         assertWith(getManager().getPinnedShortcuts())
     99                 .selectByIds("s2")
    100                 .forAllShortcuts(si -> {
    101                     assertEquals("shortlabel2_updated", si.getShortLabel());
    102                 });
    103     }
    104 
    105     public void testBackupDisabled() {
    106         assertWith(getManager().getDynamicShortcuts())
    107                 .isEmpty();
    108 
    109         assertWith(getManager().getPinnedShortcuts())
    110                 .haveIds("ms1", "ms2")
    111                 .areAllEnabled();
    112 
    113         assertWith(getManager().getManifestShortcuts())
    114                 .haveIds("ms1", "ms2")
    115                 .areAllPinned()
    116                 .areAllEnabled();
    117 
    118         // Backup was disabled, so either s1 nor s2 look to be restored to the app.
    119         // So when the app publishes s1, it'll be published as new.
    120         // But it'll still be pinned.
    121         final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
    122                 .setShortLabel("shortlabel1_new_one")
    123                 .setActivity(getActivity("MainActivity"))
    124                 .setIntents(new Intent[]{new Intent("main")})
    125                 .build();
    126 
    127         assertTrue(getManager().addDynamicShortcuts(list(s1)));
    128 
    129         assertWith(getManager().getDynamicShortcuts())
    130                 .haveIds("s1") // s2 not in the list.
    131                 .areAllPinned()
    132                 .areAllEnabled()
    133                 .forAllShortcuts(si -> {
    134                     // The app re-published the shortcut, not updated, so the fields that existed
    135                     // in the original shortcut is gone now.
    136                     assertNull(si.getExtras());
    137                 });
    138     }
    139 
    140     public void testRestoreWrongKey() {
    141         // Restored pinned shortcuts are from a package with a different signature, so the dynamic
    142         // pinned shortcuts should be disabled-invisible.
    143 
    144         assertWith(getManager().getDynamicShortcuts())
    145                 .isEmpty();
    146 
    147         assertWith(getManager().getPinnedShortcuts())
    148                 .haveIds("ms1", "ms2");
    149 
    150         assertWith(getManager().getManifestShortcuts())
    151                 .haveIds("ms1", "ms2")
    152                 .areAllPinned()
    153                 .areAllEnabled();
    154 
    155         final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
    156                 .setShortLabel("shortlabel1_new_one")
    157                 .setActivity(getActivity("MainActivity"))
    158                 .setIntents(new Intent[]{new Intent("main")})
    159                 .build();
    160 
    161         assertTrue(getManager().addDynamicShortcuts(list(s1)));
    162 
    163         final ShortcutInfo s2 = new ShortcutInfo.Builder(getContext(), "s2")
    164                 .setShortLabel("shortlabel2_updated")
    165                 .build();
    166         assertTrue(getManager().updateShortcuts(list(s2)));
    167 
    168         assertWith(getManager().getDynamicShortcuts())
    169                 .haveIds("s1") // s2 not in the list.
    170                 .areAllEnabled();
    171     }
    172 
    173     /**
    174      * Restored on an older version that have no manifest shortcuts.
    175      *
    176      * In this case, the publisher wouldn't see the manifest shortcuts, and they're overwritable.
    177      */
    178     public void testRestoreNoManifestOnOldVersion() {
    179         assertWith(getManager().getManifestShortcuts())
    180                 .isEmpty();
    181 
    182         assertWith(getManager().getDynamicShortcuts())
    183                 .isEmpty();
    184 
    185         assertWith(getManager().getPinnedShortcuts())
    186                 .isEmpty();
    187 
    188         // ms1 was manifest/immutable, but can be overwritten.
    189         final ShortcutInfo ms1 = new ShortcutInfo.Builder(getContext(), "ms1")
    190                 .setShortLabel("ms1_new_one")
    191                 .setActivity(getActivity("MainActivity"))
    192                 .setIntents(new Intent[]{new Intent("main")})
    193                 .build();
    194 
    195         assertTrue(getManager().setDynamicShortcuts(list(ms1)));
    196 
    197         assertWith(getManager().getDynamicShortcuts())
    198                 .haveIds("ms1");
    199         assertWith(getManager().getPinnedShortcuts())
    200                 .haveIds("ms1");
    201 
    202         // Adding s1 should also work.
    203         final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
    204                 .setShortLabel("s1_new_one")
    205                 .setActivity(getActivity("MainActivity"))
    206                 .setIntents(new Intent[]{new Intent("main")})
    207                 .build();
    208 
    209         assertTrue(getManager().addDynamicShortcuts(list(s1)));
    210 
    211         assertWith(getManager().getDynamicShortcuts())
    212                 .haveIds("s1", "ms1");
    213         assertWith(getManager().getPinnedShortcuts())
    214                 .haveIds("s1", "ms1");
    215 
    216         // Update on ms2 should be no-op.
    217         final ShortcutInfo ms2 = new ShortcutInfo.Builder(getContext(), "ms2")
    218                 .setShortLabel("ms2-updated")
    219                 .build();
    220         assertTrue(getManager().updateShortcuts(list(ms2)));
    221 
    222         assertWith(getManager().getManifestShortcuts())
    223                 .isEmpty();
    224         assertWith(getManager().getDynamicShortcuts())
    225                 .haveIds("s1", "ms1")
    226                 .areAllEnabled()
    227                 .areAllPinned()
    228                 .areAllMutable()
    229 
    230                 .selectByIds("s1")
    231                 .forAllShortcuts(si -> {
    232                     assertEquals("s1_new_one", si.getShortLabel());
    233                 })
    234 
    235                 .revertToOriginalList()
    236                 .selectByIds("ms1")
    237                 .forAllShortcuts(si -> {
    238                     assertEquals("ms1_new_one", si.getShortLabel());
    239                 });
    240     }
    241 
    242     /**
    243      * Restored on the same (or newer) version that have no manifest shortcuts.
    244      *
    245      * In this case, the publisher will see the manifest shortcuts (as immutable pinned),
    246      * and they *cannot* be overwritten.
    247      */
    248     public void testRestoreNoManifestOnNewVersion() {
    249         assertWith(getManager().getManifestShortcuts())
    250                 .isEmpty();
    251 
    252         assertWith(getManager().getDynamicShortcuts())
    253                 .isEmpty();
    254 
    255         assertWith(getManager().getPinnedShortcuts())
    256                 .haveIds("ms1", "ms2", "s1", "s2")
    257                 .selectByIds("ms1", "ms2")
    258                 .areAllDisabled()
    259 
    260                 .revertToOriginalList()
    261                 .selectByIds("s1", "s2")
    262                 .areAllEnabled();
    263     }
    264 
    265     private void assertNoShortcuts() {
    266         assertWith(getManager().getDynamicShortcuts()).isEmpty();
    267         assertWith(getManager().getPinnedShortcuts()).isEmpty();
    268         assertWith(getManager().getManifestShortcuts()).isEmpty();
    269     }
    270 
    271     public void testInvisibleIgnored() throws Exception {
    272         assertNoShortcuts();
    273 
    274         // Make sure "disable" won't change the disabled reason. Also make sure "enable" won't
    275         // enable them.
    276         getManager().disableShortcuts(list("s1", "s2", "ms1"));
    277         assertNoShortcuts();
    278 
    279         getManager().enableShortcuts(list("ms1", "s2"));
    280         assertNoShortcuts();
    281 
    282         getManager().enableShortcuts(list("ms1"));
    283         assertNoShortcuts();
    284 
    285         getManager().removeDynamicShortcuts(list("s1", "ms1"));
    286         assertNoShortcuts();
    287 
    288         getManager().removeAllDynamicShortcuts();
    289         assertNoShortcuts();
    290 
    291 
    292         // Force launcher 4 to be the default launcher so it'll receive the pin request.
    293         setDefaultLauncher(getInstrumentation(),
    294                 "android.content.pm.cts.shortcut.backup.launcher4/.MainActivity");
    295 
    296         // Update, set and add have been tested already, so let's test "pin".
    297 
    298         final CountDownLatch latch = new CountDownLatch(1);
    299 
    300         PersistableBundle pb = new PersistableBundle();
    301         pb.putBoolean("acceptit", true);
    302 
    303         final ShortcutInfo ms2 = new ShortcutInfo.Builder(getContext(), "ms2")
    304                 .setShortLabel("ms2_new_one")
    305                 .setActivity(getActivity("MainActivity"))
    306                 .setIntents(new Intent[]{new Intent("main2")})
    307                 .setExtras(pb)
    308                 .build();
    309 
    310         final String myIntentAction = "cts-shortcut-intent_" + new SecureRandom().nextInt();
    311         final IntentFilter myFilter = new IntentFilter(myIntentAction);
    312 
    313         final BroadcastReceiver onResult = new BroadcastReceiver() {
    314             @Override
    315             public void onReceive(Context context, Intent intent) {
    316                 latch.countDown();
    317             }
    318         };
    319         getContext().registerReceiver(onResult, myFilter);
    320         assertTrue(getManager().requestPinShortcut(ms2,
    321                 PendingIntent.getBroadcast(getContext(), 0, new Intent(myIntentAction),
    322                         PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender()));
    323 
    324         assertTrue("Didn't receive requestPinShortcut() callback.",
    325                 latch.await(30, TimeUnit.SECONDS));
    326 
    327         assertWith(getManager().getPinnedShortcuts())
    328                 .haveIds("ms2")
    329                 .areAllNotDynamic()
    330                 .areAllNotManifest()
    331                 .areAllMutable()
    332                 .areAllPinned()
    333                 .forAllShortcuts(si -> {
    334                     // requestPinShortcut() acts as an update in this case, so even though
    335                     // the original shortcut hada  long label, this one does not.
    336                     assertTrue(TextUtils.isEmpty(si.getLongLabel()));
    337                 });
    338     }
    339 }
    340