blob: eb4db7a0f4af556dc3f73cbe3b91f812f26d0a5a [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.pm;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
import android.content.ComponentName;
import android.content.pm.ShortcutInfo;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.frameworks.servicestests.R;
import com.android.server.pm.ShortcutService.ConfigConstants;
/**
* Tests related to shortcut rank auto-adjustment.
*/
@SmallTest
public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
private static final String CALLING_PACKAGE = CALLING_PACKAGE_1;
private static final ComponentName A1 = new ComponentName(CALLING_PACKAGE,
ShortcutActivity.class.getName());
private static final ComponentName A2 = new ComponentName(CALLING_PACKAGE,
ShortcutActivity2.class.getName());
private static final ComponentName A3 = new ComponentName(CALLING_PACKAGE,
ShortcutActivity3.class.getName());
private ShortcutInfo shortcut(String id, ComponentName activity, int rank) {
return makeShortcutWithActivityAndRank(id, activity, rank);
}
private ShortcutInfo shortcut(String id, ComponentName activity) {
return makeShortcutWithActivityAndRank(id, activity, ShortcutInfo.RANK_NOT_SET);
}
@Override
protected void setUp() throws Exception {
super.setUp();
// We don't need throttling during this test class, and also relax the max cap.
mService.updateConfigurationLocked(
ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
+ ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
);
setCaller(CALLING_PACKAGE, USER_0);
}
private void publishManifestShortcuts(ComponentName activity, int resId) {
addManifestShortcutResource(activity, resId);
updatePackageVersion(CALLING_PACKAGE, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
genPackageAddIntent(CALLING_PACKAGE, USER_0));
}
public void testSetDynamicShortcuts_noManifestShortcuts() {
mManager.setDynamicShortcuts(list(
shortcut("s1", A1)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s1");
assertTrue(mManager.setDynamicShortcuts(list(
shortcut("s5", A1),
shortcut("s4", A1),
shortcut("s3", A1)
)));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s4", "s3");
// RANK_NOT_SET is always the last.
assertTrue(mManager.setDynamicShortcuts(list(
shortcut("s5", A1),
shortcut("s4", A1, 5),
shortcut("s3", A1, 3),
shortcut("s2", A1)
)));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s3", "s4", "s5", "s2");
// Same rank, preserve the argument order.
assertTrue(mManager.setDynamicShortcuts(list(
shortcut("s5", A1, 5),
shortcut("s4", A1, 0),
shortcut("s3", A1, 5)
)));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s4", "s5", "s3");
// Multiple activities.
assertTrue(mManager.setDynamicShortcuts(list(
shortcut("s5", A1),
shortcut("s4", A2),
shortcut("s3", A3)
)));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
.haveRanksInOrder("s3");
assertTrue(mManager.setDynamicShortcuts(list(
shortcut("s5", A1, 5),
shortcut("s4", A1),
shortcut("s3", A1, 5),
shortcut("x5", A2, 5),
shortcut("x4", A2),
shortcut("x3", A2, 1)
)));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x5", "x4");
// Clear. Make sure it wouldn't lead to invalid internals state.
// (ShortcutService.verifyStates() will do so internally.)
assertTrue(mManager.setDynamicShortcuts(list()));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1).isEmpty();
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2).isEmpty();
}
private void runTestWithManifestShortcuts(Runnable r) {
publishManifestShortcuts(A1, R.xml.shortcut_5_alt);
publishManifestShortcuts(A2, R.xml.shortcut_1);
assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
.haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
.haveRanksInOrder("ms1");
// Existence of manifest shortcuts shouldn't affect dynamic shortcut ranks,
// so running another test here should pass.
r.run();
// And dynamic shortcut tests shouldn't affect manifest shortcuts, so repeat the
// same check.
assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
.haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
.haveRanksInOrder("ms1");
}
public void testSetDynamicShortcuts_withManifestShortcuts() {
runTestWithManifestShortcuts(() -> testSetDynamicShortcuts_noManifestShortcuts());
}
public void testAddDynamicShortcuts_noManifestShortcuts() {
mManager.addDynamicShortcuts(list(
shortcut("s1", A1)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s1");
//------------------------------------------------------
long lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.addDynamicShortcuts(list(
shortcut("s5", A1, 0),
shortcut("s4", A1),
shortcut("s2", A1, 3),
shortcut("x1", A2),
shortcut("x3", A2, 2),
shortcut("x2", A2, 2),
shortcut("s3", A1, 0)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s1", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s5", "s3", "s1", "s2", "s4", "x3", "x2", "x1");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.addDynamicShortcuts(list(
shortcut("s1", A1, 1)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s1", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s1", "s3");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.addDynamicShortcuts(list(
shortcut("s1", A1, 1),
// This is add, not update, so the following means s5 will have NO_RANK,
// which puts it at the end.
shortcut("s5", A1),
shortcut("s3", A1, 0),
// s10 also has NO_RANK, so it'll be put at the end, even after "s5" as we preserve
// the argument order.
shortcut("s10", A1),
// Note we're changing the activity for x2.
shortcut("x2", A1, 0),
shortcut("x10", A2)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s3", "x2", "s1", "s2", "s4", "s5", "s10");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x1", "x10");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s3", "x2", "s1", "s5", "s10", "x1", "x10");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
// Change the activities again.
mManager.addDynamicShortcuts(list(
shortcut("s1", A2),
shortcut("s2", A2, 999)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s3", "x2", "s4", "s5", "s10");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x1", "x10", "s2", "s1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s1", "s2", "s4", "s5", "s10");
}
public void testAddDynamicShortcuts_withManifestShortcuts() {
runTestWithManifestShortcuts(() -> testAddDynamicShortcuts_noManifestShortcuts());
}
public void testUpdateShortcuts_noManifestShortcuts() {
mManager.addDynamicShortcuts(list(
shortcut("s5", A1, 0),
shortcut("s4", A1),
shortcut("s2", A1, 3),
shortcut("x1", A2),
shortcut("x3", A2, 2),
shortcut("x2", A2, 2),
shortcut("s3", A1, 0)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
//------------------------------------------------------
long lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.updateShortcuts(list());
// Same order.
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.isEmpty();
runWithCaller(LAUNCHER_1, USER_0, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
});
// Still same order.
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.updateShortcuts(list(
shortcut("s4", A1, 1),
// Rank not changing, should keep the same positions.
// c.f. in case of addDynamicShortcuts, this means "put them at the end".
shortcut("s3", A1),
shortcut("x2", A2)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s4", "s3", "s2");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s4", "s3", "s2", "x2");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.updateShortcuts(list(
shortcut("s4", A1, 0),
// Change the activity without specifying a rank -> keep the same rank.
shortcut("s5", A2),
// Change the activity without specifying a rank -> assign a new rank.
shortcut("x2", A1, 2),
// "xx" doesn't exist, so it'll be ignored.
shortcut("xx", A1, 0)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s4", "x2", "s3", "s2");
// Interesting case: both x3 and s5 originally had rank=0, and in this case s5 has moved
// to A2 without changing the rank. So they're tie for the new rank, as well as
// the "rank changed" bit. Also in this case, "s5" won't have an implicit order, since
// its rank isn't changing. So we sort them by ID, thus s5 comes before x3.
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("s5", "x3", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s4", "x2", "s5", "x3");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.updateShortcuts(list(
shortcut("s3", A3)));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s4", "x2", "s2");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("s5", "x3", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
.haveRanksInOrder("s3");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s3", "s2");
}
public void testUpdateShortcuts_withManifestShortcuts() {
runTestWithManifestShortcuts(() -> testUpdateShortcuts_noManifestShortcuts());
}
public void testDeleteDynamicShortcuts_noManifestShortcuts() {
mManager.addDynamicShortcuts(list(
shortcut("s5", A1, 0),
shortcut("s4", A1),
shortcut("s2", A1, 3),
shortcut("x1", A2),
shortcut("x3", A2, 2),
shortcut("x2", A2, 2),
shortcut("s3", A1, 0)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
//------------------------------------------------------
long lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.removeDynamicShortcuts(list());
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.isEmpty();
runWithCaller(LAUNCHER_1, USER_0, () -> {
mLauncherApps.pinShortcuts(
CALLING_PACKAGE, list("s2", "s4", "x1", "x2"), HANDLE_USER_0);
});
// Still same order.
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.removeDynamicShortcuts(list("s3", "x1", "xxxx"));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s2", "s4");
}
public void testDeleteDynamicShortcuts_withManifestShortcuts() {
runTestWithManifestShortcuts(() -> testDeleteDynamicShortcuts_noManifestShortcuts());
}
public void testDisableShortcuts_noManifestShortcuts() {
mManager.addDynamicShortcuts(list(
shortcut("s5", A1, 0),
shortcut("s4", A1),
shortcut("s2", A1, 3),
shortcut("x1", A2),
shortcut("x3", A2, 2),
shortcut("x2", A2, 2),
shortcut("s3", A1, 0)
));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
//------------------------------------------------------
long lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.disableShortcuts(list());
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s3", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2", "x1");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.isEmpty();
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.disableShortcuts(list("s3", "x1", "xxxx"));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s2", "s4");
runWithCaller(LAUNCHER_1, USER_0, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
});
// Still same order.
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s2", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x3", "x2");
//------------------------------------------------------
lastApiTime = ++mInjectedCurrentTimeMillis;
mManager.disableShortcuts(list("s2", "x3"));
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
.haveRanksInOrder("s5", "s4");
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
.haveRanksInOrder("x2");
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s4", "x2");
}
public void testDisableShortcuts_withManifestShortcuts() {
runTestWithManifestShortcuts(() -> testDisableShortcuts_noManifestShortcuts());
}
}