blob: bf1ed98983dfb014890bf03e8d373a46c0c5ac13 [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 android.os.Handler;
import android.os.Looper;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.LargeTest;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
* Run with:
adb install \
-r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
adb shell am instrument -e class com.android.server.pm.ShortcutPendingTasksTest \
-w com.android.frameworks.servicestests
*/
@LargeTest
public class ShortcutPendingTasksTest extends BaseShortcutManagerTest {
public void testAll() {
final AtomicReference<Throwable> thrown = new AtomicReference<>();
final AtomicBoolean threadCheckerResult = new AtomicBoolean(true);
final Handler handler = new Handler(Looper.getMainLooper());
final ShortcutPendingTasks tasks = new ShortcutPendingTasks(
handler::post,
threadCheckerResult::get,
thrown::set);
// No pending tasks, shouldn't block.
assertTrue(tasks.waitOnAllTasks());
final AtomicInteger counter = new AtomicInteger();
// Run one task.
tasks.addTask(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException ignore) {
}
counter.incrementAndGet();
});
assertTrue(tasks.waitOnAllTasks());
assertNull(thrown.get());
assertEquals(1, counter.get());
// Run 3 tasks.
// We use this ID to make sure only one task can run at the same time.
final AtomicInteger currentTaskId = new AtomicInteger();
tasks.addTask(() -> {
currentTaskId.set(1);
try {
Thread.sleep(500);
} catch (InterruptedException ignore) {
}
counter.incrementAndGet();
assertEquals(1, currentTaskId.get());
});
tasks.addTask(() -> {
currentTaskId.set(2);
try {
Thread.sleep(500);
} catch (InterruptedException ignore) {
}
counter.incrementAndGet();
assertEquals(2, currentTaskId.get());
});
tasks.addTask(() -> {
currentTaskId.set(3);
try {
Thread.sleep(500);
} catch (InterruptedException ignore) {
}
counter.incrementAndGet();
assertEquals(3, currentTaskId.get());
});
assertTrue(tasks.waitOnAllTasks());
assertNull(thrown.get());
assertEquals(4, counter.get());
// No tasks running, shouldn't block.
assertTrue(tasks.waitOnAllTasks());
assertNull(thrown.get());
assertEquals(4, counter.get());
// Now the thread checker returns false, so waitOnAllTasks() returns false.
threadCheckerResult.set(false);
assertFalse(tasks.waitOnAllTasks());
threadCheckerResult.set(true);
// Make sure the exception handler is called.
tasks.addTask(() -> {
throw new RuntimeException("XXX");
});
assertTrue(tasks.waitOnAllTasks());
assertNotNull(thrown.get());
MoreAsserts.assertContainsRegex("XXX", thrown.get().getMessage());
}
}