summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPeter Visontay <pvisontay@google.com>2010-11-19 13:14:13 +0000
committerPeter Visontay <pvisontay@google.com>2011-01-28 11:03:50 +0000
commit62a6b1f913bdfa1f7f53fad055cd62c3cfb90100 (patch)
tree55020b6e74848efaa3d815e4a98d0a8f02f5a857 /tests
parent6bb3c8a364e4f8c291f8e2a1c1cbd2ab2042d8ba (diff)
downloadApplicationsProvider-62a6b1f913bdfa1f7f53fad055cd62c3cfb90100.tar.gz
Added new URI for launch count updates to ApplicationsProvider.
Tested with automated tests + manually: 1. Installed ApplicationsProvider (with a clean database containing 0 as each app's current launch count). 2. Typed "g" into QSB. App suggestions: Gallery, Gmail (ranked alphabetically). 3. Clicked on the "Google Search" app to launch it and by doing so increase its launch count. 4. Cleared the QSB shortcuts (QSB created one for Google Search when it was launched). 5. Reinstalled ApplicationsProvider so the in-memory values would be lost. 6. Typed "g" into QSB. app suggestions: Google Search, Gallery (ranked by launch count). Bug: 1847330 Change-Id: I4125b34a1923fe5866c52bf77218974ed14a38bc
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.mk18
-rw-r--r--tests/AndroidManifest.xml28
-rw-r--r--tests/runtests5
-rw-r--r--tests/src/com/android/providers/applications/ApplicationsProviderForTesting.java41
-rw-r--r--tests/src/com/android/providers/applications/ApplicationsProviderTest.java204
-rw-r--r--tests/src/com/android/providers/applications/MockPackageManager.java70
6 files changed, 366 insertions, 0 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..7d1fe34
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_INSTRUMENTATION_FOR := ApplicationsProvider
+
+# framework is required to access android.provider.Applications
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := ApplicationsProviderTests
+LOCAL_CERTIFICATE := shared
+
+include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
new file mode 100644
index 0000000..c614afc
--- /dev/null
+++ b/tests/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2010 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.providers.applications.tests">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.providers.applications"
+ android:label="Tests for the ApplicationsProvider">
+ </instrumentation>
+</manifest>
diff --git a/tests/runtests b/tests/runtests
new file mode 100644
index 0000000..184a278
--- /dev/null
+++ b/tests/runtests
@@ -0,0 +1,5 @@
+mmm packages/providers/ApplicationsProvider || return
+adb install -r ${OUT}/system/app/ApplicationsProvider.apk || return
+adb install -r ${OUT}/data/app/ApplicationsProviderTests.apk || return
+adb shell am instrument -w -e class com.android.providers.applications.ApplicationsProviderTest com.android.providers.applications.tests/android.test.InstrumentationTestRunner || return
+
diff --git a/tests/src/com/android/providers/applications/ApplicationsProviderForTesting.java b/tests/src/com/android/providers/applications/ApplicationsProviderForTesting.java
new file mode 100644
index 0000000..0ecb6fb
--- /dev/null
+++ b/tests/src/com/android/providers/applications/ApplicationsProviderForTesting.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 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.providers.applications;
+
+import android.content.pm.PackageManager;
+
+/**
+ * An extension of {@link ApplicationsProvider} that makes its testing easier.
+ */
+public class ApplicationsProviderForTesting extends ApplicationsProvider {
+
+ private PackageManager mMockPackageManager;
+
+ @Override
+ protected PackageManager getPackageManager() {
+ return mMockPackageManager;
+ }
+
+ protected void setMockPackageManager(PackageManager mockPackageManager) {
+ this.mMockPackageManager = mockPackageManager;
+ }
+
+ @Override
+ protected void enforcePermissionForLaunchCountIncrease() {
+ // Tests are allowed to do this.
+ }
+}
diff --git a/tests/src/com/android/providers/applications/ApplicationsProviderTest.java b/tests/src/com/android/providers/applications/ApplicationsProviderTest.java
new file mode 100644
index 0000000..6eb47c6
--- /dev/null
+++ b/tests/src/com/android/providers/applications/ApplicationsProviderTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010 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.providers.applications;
+
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.Applications;
+import android.test.ProviderTestCase2;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Instrumentation test for the ApplicationsProvider.
+ *
+ * The tests use an IsolatedContext, and are not affected by the real list of
+ * applications on the device. The ApplicationsProvider's persistent database
+ * is also created in an isolated context so it doesn't interfere with the
+ * database of the actual ApplicationsProvider installed on the device.
+ */
+public class ApplicationsProviderTest extends ProviderTestCase2<ApplicationsProviderForTesting> {
+
+ private ApplicationsProviderForTesting mProvider;
+
+ public ApplicationsProviderTest() {
+ super(ApplicationsProviderForTesting.class, Applications.AUTHORITY);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mProvider = getProvider();
+ initProvider(mProvider);
+ }
+
+ /**
+ * Ensures that the ApplicationsProvider is in a ready-to-test state.
+ */
+ private void initProvider(ApplicationsProviderForTesting provider) throws Exception {
+ // Decouple the provider from Android's real list of applications.
+ MockPackageManager mockPackageManager = new MockPackageManager();
+ addDefaultTestPackages(mockPackageManager);
+ provider.setMockPackageManager(mockPackageManager);
+
+ // We need to wait for the applications database to be updated (it's
+ // updated with a slight delay by a separate thread) before we can use
+ // the ApplicationsProvider.
+ Runnable markerRunnable = new Runnable() {
+ @Override
+ public void run() {
+ }
+ };
+ FutureTask<Void> onApplicationsListUpdated = new FutureTask<Void>(markerRunnable, null);
+
+ provider.setOnApplicationsListUpdated(onApplicationsListUpdated);
+ onApplicationsListUpdated.get();
+ }
+
+ /**
+ * Register a few default applications with the ApplicationsProvider that
+ * tests can query.
+ */
+ private void addDefaultTestPackages(MockPackageManager mockPackageManager) {
+ mockPackageManager.addPackage(
+ "Email", new ComponentName("com.android.email", "com.android.email.MainView"));
+ mockPackageManager.addPackage(
+ "Ebay", new ComponentName("com.android.ebay", "com.android.ebay.Shopping"));
+ mockPackageManager.addPackage(
+ "Fakeapp", new ComponentName("com.android.fakeapp", "com.android.fakeapp.FakeView"));
+
+ // Apps that can be used to test ordering.
+ mockPackageManager.addPackage("AlphabeticA", new ComponentName("a", "a.AView"));
+ mockPackageManager.addPackage("AlphabeticB", new ComponentName("b", "b.BView"));
+ mockPackageManager.addPackage("AlphabeticC", new ComponentName("c", "c.CView"));
+ mockPackageManager.addPackage("AlphabeticD", new ComponentName("d", "d.DView"));
+ }
+
+ public void testSearch_singleResult() {
+ testSearch("ema", "Email");
+ }
+
+ public void testSearch_multipleResults() {
+ testSearch("e", "Ebay", "Email");
+ }
+
+ public void testSearch_noResults() {
+ testSearch("nosuchapp");
+ }
+
+ public void testSearch_orderingIsAlphabeticByDefault() {
+ testSearch("alphabetic", "AlphabeticA", "AlphabeticB", "AlphabeticC", "AlphabeticD");
+ }
+
+ public void testSearch_emptySearchQueryReturnsEverything() {
+ testSearch("",
+ "AlphabeticA", "AlphabeticB", "AlphabeticC", "AlphabeticD",
+ "Ebay", "Email", "Fakeapp");
+ }
+
+ public void testSearch_appsAreRankedByLaunchCount() throws Exception {
+ // Original ranking: A, B, C, D (alphabetic; all launch counts are 0
+ // by default).
+ increaseLaunchCount(new ComponentName("b", "b.BView"));
+ increaseLaunchCount(new ComponentName("d", "d.DView"));
+ increaseLaunchCount(new ComponentName("d", "d.DView"));
+
+ // New ranking: D, B, A, C (first by launch count, then
+ // - if the launch counts of two apps are equal - alphabetically)
+ testSearch("alphabetic", "AlphabeticD", "AlphabeticB", "AlphabeticA", "AlphabeticC");
+ }
+
+ /**
+ * Tests that the launch count values are persisted even if the
+ * ApplicationsProvider is restarted.
+ */
+ public void testSearch_launchCountInformationIsPersistent() throws Exception {
+ // Original ranking: A, B, C, D (alphabetic; all launch counts are 0
+ // by default).
+ increaseLaunchCount(new ComponentName("b", "b.BView"));
+ increaseLaunchCount(new ComponentName("d", "d.DView"));
+ increaseLaunchCount(new ComponentName("d", "d.DView"));
+
+ // New ranking: D, B, A, C (first by launch count, then
+ // - if the launch counts of two apps are equal - alphabetically)
+ testSearch("alphabetic", "AlphabeticD", "AlphabeticB", "AlphabeticA", "AlphabeticC");
+
+ // Now we'll create a new ApplicationsProvider instance (the provider
+ // may be killed by Android at any time) and verify that it has access
+ // to the same launch count information as the original provider instance.
+ // The new instance will use the same IsolatedContext as the previous one.
+ ApplicationsProviderForTesting newProviderInstance = createNewProvider(mProvider.getContext());
+ assertNotSame(newProviderInstance, mProvider);
+
+ // Override the previous provider with the new instance in the
+ // ContentResolver.
+ getMockContentResolver().addProvider(Applications.AUTHORITY, newProviderInstance);
+
+ initProvider(newProviderInstance);
+
+ // Verify that the launch-count-dependent ordering is still correct.
+ testSearch("alphabetic", "AlphabeticD", "AlphabeticB", "AlphabeticA", "AlphabeticC");
+ }
+
+ private void testSearch(String searchQuery, String... expectedResultsInOrder) {
+ Cursor cursor = Applications.search(getMockContentResolver(), searchQuery);
+
+ assertNotNull(cursor);
+ assertFalse(cursor.isClosed());
+
+ verifySearchResults(cursor, expectedResultsInOrder);
+
+ cursor.close();
+ }
+
+ private void verifySearchResults(Cursor cursor, String... expectedResultsInOrder) {
+ int expectedResultCount = expectedResultsInOrder.length;
+ assertEquals("Wrong number of app search results.",
+ expectedResultCount, cursor.getCount());
+
+ if (expectedResultCount > 0) {
+ cursor.moveToFirst();
+ int nameIndex = cursor.getColumnIndex(ApplicationsProvider.NAME);
+ // Verify that the actual results match the expected ones.
+ for (int i = 0; i < cursor.getCount(); i++) {
+ assertEquals("Wrong search result at position " + i,
+ expectedResultsInOrder[i], cursor.getString(nameIndex));
+ cursor.moveToNext();
+ }
+ }
+ }
+
+ /**
+ * Makes the ApplicationsProvider increase the launch count of this
+ * application stored in its database.
+ */
+ private void increaseLaunchCount(ComponentName componentName) {
+ Applications.increaseLaunchCount(getMockContentResolver(), componentName);
+ }
+
+ private ApplicationsProviderForTesting createNewProvider(Context context) throws Exception {
+ ApplicationsProviderForTesting newProviderInstance =
+ ApplicationsProviderForTesting.class.newInstance();
+ newProviderInstance.attachInfo(context, null);
+ return newProviderInstance;
+ }
+}
diff --git a/tests/src/com/android/providers/applications/MockPackageManager.java b/tests/src/com/android/providers/applications/MockPackageManager.java
new file mode 100644
index 0000000..3d272c4
--- /dev/null
+++ b/tests/src/com/android/providers/applications/MockPackageManager.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package com.android.providers.applications;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MockPackageManager extends android.test.mock.MockPackageManager {
+
+ private List<ResolveInfo> mPackages = new ArrayList<ResolveInfo>();
+
+ /**
+ * Returns all packages registered with the mock package manager.
+ * ApplicationsProvider uses this method to query the list of applications.
+ */
+ @Override
+ public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+ return mPackages;
+ }
+
+ /**
+ * Adds a new package to the mock package manager.
+ *
+ * Example:
+ * addPackage("Email", new ComponentName("com.android.email", "com.android.email.MainView"));
+ *
+ * @param title the user-friendly title of the application (this is what
+ * users will search for)
+ */
+ public void addPackage(final String title, ComponentName componentName) {
+ // Set the application's title.
+ ResolveInfo packageInfo = new ResolveInfo() {
+ @Override
+ public CharSequence loadLabel(PackageManager pm) {
+ return title;
+ }
+ };
+
+ // Set the application's ComponentName.
+ packageInfo.activityInfo = new ActivityInfo();
+ packageInfo.activityInfo.name = componentName.getClassName();
+ packageInfo.activityInfo.applicationInfo = new ApplicationInfo();
+ packageInfo.activityInfo.applicationInfo.packageName = componentName.getPackageName();
+
+ mPackages.add(packageInfo);
+ }
+}