Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2016 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.server.pm;
     17 
     18 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.array;
     19 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertContains;
     20 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
     21 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertSuccess;
     22 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
     23 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
     24 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.readAll;
     25 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resultContains;
     26 
     27 import android.content.ComponentName;
     28 import android.os.Bundle;
     29 import android.os.ParcelFileDescriptor;
     30 import android.os.Process;
     31 import android.os.RemoteException;
     32 import android.os.ResultReceiver;
     33 import android.test.suitebuilder.annotation.SmallTest;
     34 
     35 import com.android.frameworks.servicestests.R;
     36 import com.android.server.pm.ShortcutService.ConfigConstants;
     37 
     38 import java.io.File;
     39 import java.io.IOException;
     40 import java.util.List;
     41 import java.util.concurrent.atomic.AtomicInteger;
     42 
     43 /**
     44  * Unit test for "cmd shortcut" and "dumpsys shortcut".
     45  *
     46  * Launcher related commands are tested in
     47  */
     48 @SmallTest
     49 public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
     50     private List<String> callShellCommand(String... args) throws IOException, RemoteException {
     51 
     52         // For reset to work, the current time needs to be incrementing.
     53         mInjectedCurrentTimeMillis++;
     54 
     55         final AtomicInteger resultCode = new AtomicInteger(Integer.MIN_VALUE);
     56 
     57         final ResultReceiver rr = new ResultReceiver(mHandler) {
     58             @Override
     59             public void send(int resultCode_, Bundle resultData) {
     60                 resultCode.set(resultCode_);
     61             }
     62         };
     63         final File out = File.createTempFile("shellout-", ".tmp",
     64                 getTestContext().getCacheDir());
     65         try {
     66             try (final ParcelFileDescriptor fd = ParcelFileDescriptor.open(out,
     67                     ParcelFileDescriptor.MODE_READ_WRITE)) {
     68                 mService.onShellCommand(
     69                     /* fdin*/ null,
     70                     /* fdout*/ fd.getFileDescriptor(),
     71                     /* fderr*/ fd.getFileDescriptor(),
     72                         args, null, rr);
     73             }
     74             return readAll(out);
     75         } finally {
     76             out.delete();
     77         }
     78     }
     79 
     80     public void testNonShell() throws Exception {
     81         mService.mMaxUpdatesPerInterval = 99;
     82 
     83         mInjectedCallingUid = 12345;
     84         assertExpectException(SecurityException.class, "must be shell",
     85                 () -> callShellCommand("reset-config"));
     86 
     87         mInjectedCallingUid = Process.SYSTEM_UID;
     88         assertExpectException(SecurityException.class, "must be shell",
     89                 () -> callShellCommand("reset-config"));
     90 
     91         assertEquals(99, mService.mMaxUpdatesPerInterval);
     92     }
     93 
     94     public void testRoot() throws Exception {
     95         mService.mMaxUpdatesPerInterval = 99;
     96 
     97         mInjectedCallingUid = Process.ROOT_UID;
     98         assertSuccess(callShellCommand("reset-config"));
     99 
    100         assertEquals(3, mService.mMaxUpdatesPerInterval);
    101     }
    102 
    103     public void testRestConfig() throws Exception {
    104         mService.mMaxUpdatesPerInterval = 99;
    105 
    106         mInjectedCallingUid = Process.SHELL_UID;
    107         assertSuccess(callShellCommand("reset-config"));
    108 
    109         assertEquals(3, mService.mMaxUpdatesPerInterval);
    110     }
    111 
    112     public void testOverrideConfig() throws Exception {
    113         mService.mMaxUpdatesPerInterval = 99;
    114 
    115         mInjectedCallingUid = Process.SHELL_UID;
    116         assertSuccess(callShellCommand("override-config",
    117                 ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=1"));
    118 
    119         assertEquals(1, mService.mMaxUpdatesPerInterval);
    120     }
    121 
    122     public void testResetThrottling() throws Exception {
    123         prepareCrossProfileDataSet();
    124 
    125         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    126             assertTrue(mManager.getRemainingCallCount() < 3);
    127         });
    128         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    129             assertTrue(mManager.getRemainingCallCount() < 3);
    130         });
    131 
    132         mInjectedCallingUid = Process.SHELL_UID;
    133         assertSuccess(callShellCommand("reset-throttling"));
    134 
    135         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    136             assertEquals(3, mManager.getRemainingCallCount());
    137         });
    138         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    139             assertTrue(mManager.getRemainingCallCount() < 3);
    140         });
    141     }
    142 
    143     public void testResetThrottling_user_not_running() throws Exception {
    144         prepareCrossProfileDataSet();
    145 
    146         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    147             assertTrue(mManager.getRemainingCallCount() < 3);
    148         });
    149         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    150             assertTrue(mManager.getRemainingCallCount() < 3);
    151         });
    152 
    153         mInjectedCallingUid = Process.SHELL_UID;
    154 
    155         mRunningUsers.put(USER_10, false);
    156 
    157         assertTrue(resultContains(
    158                 callShellCommand("reset-throttling", "--user", "10"),
    159                 "User 10 is not running or locked"));
    160 
    161         mRunningUsers.put(USER_10, true);
    162 
    163         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    164             assertTrue(mManager.getRemainingCallCount() < 3);
    165         });
    166         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    167             assertTrue(mManager.getRemainingCallCount() < 3);
    168         });
    169     }
    170 
    171     public void testResetThrottling_user_running() throws Exception {
    172         prepareCrossProfileDataSet();
    173 
    174         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    175             assertTrue(mManager.getRemainingCallCount() < 3);
    176         });
    177         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    178             assertTrue(mManager.getRemainingCallCount() < 3);
    179         });
    180 
    181         mRunningUsers.put(USER_10, true);
    182         mUnlockedUsers.put(USER_10, true);
    183 
    184         mInjectedCallingUid = Process.SHELL_UID;
    185         assertSuccess(callShellCommand("reset-throttling", "--user", "10"));
    186 
    187         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    188             assertTrue(mManager.getRemainingCallCount() < 3);
    189         });
    190         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    191             assertEquals(3, mManager.getRemainingCallCount());
    192         });
    193     }
    194 
    195     public void testResetAllThrottling() throws Exception {
    196         prepareCrossProfileDataSet();
    197 
    198         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    199             assertTrue(mManager.getRemainingCallCount() < 3);
    200         });
    201         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    202             assertTrue(mManager.getRemainingCallCount() < 3);
    203         });
    204 
    205         mInjectedCallingUid = Process.SHELL_UID;
    206         assertSuccess(callShellCommand("reset-all-throttling"));
    207 
    208         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
    209             assertEquals(3, mManager.getRemainingCallCount());
    210         });
    211         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    212             assertEquals(3, mManager.getRemainingCallCount());
    213         });
    214     }
    215 
    216     public void testLauncherCommands() throws Exception {
    217         prepareGetHomeActivitiesAsUser(
    218                 /* preferred */ null,
    219                 list(getSystemLauncher(), getFallbackLauncher()),
    220                 USER_0);
    221 
    222         prepareGetHomeActivitiesAsUser(
    223                 /* preferred */ cn(CALLING_PACKAGE_2, "name"),
    224                 list(getSystemLauncher(), getFallbackLauncher(),
    225                         ri(CALLING_PACKAGE_1, "name", false, 0),
    226                         ri(CALLING_PACKAGE_2, "name", false, 0)
    227                 ),
    228                 USER_10);
    229 
    230         assertTrue(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_0));
    231 
    232         // First, test "get".
    233 
    234         mRunningUsers.put(USER_10, true);
    235         mUnlockedUsers.put(USER_10, true);
    236         mInjectedCallingUid = Process.SHELL_UID;
    237         assertContains(
    238                 assertSuccess(callShellCommand("get-default-launcher")),
    239                 "Launcher: ComponentInfo{com.android.systemlauncher/systemlauncher_name}");
    240 
    241         assertContains(
    242                 assertSuccess(callShellCommand("get-default-launcher", "--user", "10")),
    243                 "Launcher: ComponentInfo{com.android.test.2/name}");
    244 
    245         // Next, test "clear".
    246         assertSuccess(callShellCommand("clear-default-launcher", "--user", "10"));
    247 
    248         // User-10's launcher should be cleared.
    249         assertEquals(null, mService.getUserShortcutsLocked(USER_10).getLastKnownLauncher());
    250         assertEquals(null, mService.getUserShortcutsLocked(USER_10).getCachedLauncher());
    251 
    252         // but user'0's shouldn't.
    253         assertEquals(cn(PACKAGE_SYSTEM_LAUNCHER, PACKAGE_SYSTEM_LAUNCHER_NAME),
    254                 mService.getUserShortcutsLocked(USER_0).getCachedLauncher());
    255 
    256         // Change user-0's launcher.
    257         prepareGetHomeActivitiesAsUser(
    258                 /* preferred */ cn(CALLING_PACKAGE_1, "name"),
    259                 list(
    260                         ri(CALLING_PACKAGE_1, "name", false, 0)
    261                 ),
    262                 USER_0);
    263         assertContains(
    264                 assertSuccess(callShellCommand("get-default-launcher")),
    265                 "Launcher: ComponentInfo{com.android.test.1/name}");
    266     }
    267 
    268     public void testUnloadUser() throws Exception {
    269         prepareCrossProfileDataSet();
    270 
    271         assertNotNull(mService.getShortcutsForTest().get(USER_10));
    272 
    273         mRunningUsers.put(USER_10, true);
    274         mUnlockedUsers.put(USER_10, true);
    275 
    276         mInjectedCallingUid = Process.SHELL_UID;
    277         assertSuccess(callShellCommand("unload-user", "--user", "10"));
    278 
    279         assertNull(mService.getShortcutsForTest().get(USER_10));
    280     }
    281 
    282     public void testClearShortcuts() throws Exception {
    283 
    284         mRunningUsers.put(USER_10, true);
    285 
    286         // Add two manifests and two dynamics.
    287         addManifestShortcutResource(
    288                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
    289                 R.xml.shortcut_2);
    290         updatePackageVersion(CALLING_PACKAGE_1, 1);
    291         mService.mPackageMonitor.onReceive(getTestContext(),
    292                 genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
    293 
    294         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    295             assertTrue(mManager.addDynamicShortcuts(list(
    296                     makeShortcut("s1"), makeShortcut("s2"))));
    297         });
    298         runWithCaller(LAUNCHER_1, USER_10, () -> {
    299             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_10);
    300         });
    301 
    302         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    303             assertWith(getCallerShortcuts())
    304                     .haveIds("ms1", "ms2", "s1", "s2")
    305                     .areAllEnabled()
    306 
    307                     .selectPinned()
    308                     .haveIds("ms2", "s2");
    309         });
    310 
    311         // First, call for a different package.
    312 
    313         mRunningUsers.put(USER_10, true);
    314         mUnlockedUsers.put(USER_10, true);
    315 
    316         mInjectedCallingUid = Process.SHELL_UID;
    317         assertSuccess(callShellCommand("clear-shortcuts", "--user", "10", CALLING_PACKAGE_2));
    318 
    319         // Shouldn't be cleared yet.
    320         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    321             assertWith(getCallerShortcuts())
    322                     .haveIds("ms1", "ms2", "s1", "s2")
    323                     .areAllEnabled()
    324 
    325                     .selectPinned()
    326                     .haveIds("ms2", "s2");
    327         });
    328 
    329         mInjectedCallingUid = Process.SHELL_UID;
    330         assertSuccess(callShellCommand("clear-shortcuts", "--user", "10", CALLING_PACKAGE_1));
    331 
    332         // Only manifest shortcuts will remain, and are no longer pinned.
    333         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
    334             assertWith(getCallerShortcuts())
    335                     .haveIds("ms1", "ms2")
    336                     .areAllEnabled()
    337                     .areAllNotPinned();
    338         });
    339     }
    340 
    341     public void testDumpsysArgs() {
    342         checkDumpsysArgs(null, true, false, false);
    343         checkDumpsysArgs(array("-u"), true, true, false);
    344         checkDumpsysArgs(array("--uid"), true, true, false);
    345 
    346         checkDumpsysArgs(array("-f"), true, false, true);
    347         checkDumpsysArgs(array("--files"), true, false, true);
    348 
    349         checkDumpsysArgs(array("-a"), true, true, true);
    350         checkDumpsysArgs(array("--all"), true, true, true);
    351 
    352         checkDumpsysArgs(array("-a", "-n"), false, true, true);
    353         checkDumpsysArgs(array("-a", "--no-main"), false, true, true);
    354     }
    355 
    356     private void checkDumpsysArgs(String[] args, boolean expectMain, boolean expectUid,
    357             boolean expectDumpFiles) {
    358         String dump = dumpsys(args);
    359 
    360         assertEquals(expectMain, dump.contains("Icon format: PNG"));
    361         assertEquals(expectUid, dump.contains("SHORTCUT MANAGER UID STATES"));
    362         assertEquals(expectDumpFiles, dump.contains("SHORTCUT MANAGER FILES"));
    363     }
    364 
    365 }
    366