summaryrefslogtreecommitdiffstats
path: root/core/tests/coretests/src/android/app
diff options
context:
space:
mode:
Diffstat (limited to 'core/tests/coretests/src/android/app')
-rw-r--r--core/tests/coretests/src/android/app/SearchManagerTest.java195
-rw-r--r--core/tests/coretests/src/android/app/SearchablesTest.java477
-rw-r--r--core/tests/coretests/src/android/app/SuggestionProvider.java110
-rw-r--r--core/tests/coretests/src/android/app/activity/AbortReceiver.java49
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityManagerTest.java135
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityTests.java40
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityTestsBase.java212
-rw-r--r--core/tests/coretests/src/android/app/activity/BroadcastTest.java536
-rw-r--r--core/tests/coretests/src/android/app/activity/ClearTop.java51
-rw-r--r--core/tests/coretests/src/android/app/activity/IntentSenderTest.java86
-rw-r--r--core/tests/coretests/src/android/app/activity/LaunchTest.java75
-rw-r--r--core/tests/coretests/src/android/app/activity/LaunchpadActivity.java588
-rw-r--r--core/tests/coretests/src/android/app/activity/LaunchpadTabActivity.java43
-rw-r--r--core/tests/coretests/src/android/app/activity/LifecycleTest.java109
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalActivity.java33
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java42
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalDeniedService.java22
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalDialog.java33
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalGrantedReceiver.java42
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalGrantedService.java22
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalProvider.java163
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalReceiver.java77
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalScreen.java33
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalService.java122
-rw-r--r--core/tests/coretests/src/android/app/activity/MetaDataTest.java166
-rw-r--r--core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java42
-rw-r--r--core/tests/coretests/src/android/app/activity/RemoteGrantedReceiver.java42
-rw-r--r--core/tests/coretests/src/android/app/activity/RemoteReceiver.java50
-rw-r--r--core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java59
-rw-r--r--core/tests/coretests/src/android/app/activity/ResultReceiver.java43
-rw-r--r--core/tests/coretests/src/android/app/activity/SearchableActivity.java30
-rw-r--r--core/tests/coretests/src/android/app/activity/ServiceTest.java469
-rw-r--r--core/tests/coretests/src/android/app/activity/SetTimeZonePermissionsTest.java70
-rw-r--r--core/tests/coretests/src/android/app/activity/SubActivityScreen.java168
-rw-r--r--core/tests/coretests/src/android/app/activity/SubActivityTest.java92
-rw-r--r--core/tests/coretests/src/android/app/activity/TestedActivity.java77
-rw-r--r--core/tests/coretests/src/android/app/activity/TestedScreen.java128
37 files changed, 4731 insertions, 0 deletions
diff --git a/core/tests/coretests/src/android/app/SearchManagerTest.java b/core/tests/coretests/src/android/app/SearchManagerTest.java
new file mode 100644
index 0000000..21ed4c5
--- /dev/null
+++ b/core/tests/coretests/src/android/app/SearchManagerTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2006 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 android.app;
+
+import android.app.activity.LocalActivity;
+
+import android.app.Activity;
+import android.app.ISearchManager;
+import android.app.SearchManager;
+import android.app.SearchableInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.ServiceManager;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+
+/**
+ * To launch this test from the command line:
+ *
+ * adb shell am instrument -w \
+ * -e class com.android.unit_tests.SearchManagerTest \
+ * com.android.unit_tests/android.test.InstrumentationTestRunner
+ */
+public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalActivity> {
+
+ private ComponentName SEARCHABLE_ACTIVITY =
+ new ComponentName("com.android.frameworks.coretests",
+ "android.app.activity.SearchableActivity");
+
+ /*
+ * Bug list of test ideas.
+ *
+ * testSearchManagerInterfaceAvailable()
+ * Exercise the interface obtained
+ *
+ * testSearchManagerAvailable()
+ * Exercise the interface obtained
+ *
+ * testSearchManagerInvocations()
+ * FIX - make it work again
+ * stress test with a very long string
+ *
+ * SearchManager tests
+ * confirm proper identification of "default" activity based on policy, not hardcoded contacts
+ *
+ * SearchBar tests
+ * Maybe have to do with framework / unittest runner - need instrumented activity?
+ * How can we unit test the suggestions content providers?
+ * Should I write unit tests for any of them?
+ * Test scenarios:
+ * type-BACK (cancel)
+ * type-GO (send)
+ * type-navigate-click (suggestion)
+ * type-action
+ * type-navigate-action (suggestion)
+ */
+
+ /**
+ * Local copy of activity context
+ */
+ Context mContext;
+
+ public SearchManagerTest() {
+ super("com.android.frameworks.coretests", LocalActivity.class);
+ }
+
+ /**
+ * Setup any common data for the upcoming tests.
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ Activity testActivity = getActivity();
+ mContext = testActivity;
+ }
+
+ private ISearchManager getSearchManagerService() {
+ return ISearchManager.Stub.asInterface(
+ ServiceManager.getService(Context.SEARCH_SERVICE));
+ }
+
+ /**
+ * The goal of this test is to confirm that we can obtain
+ * a search manager interface.
+ */
+ @MediumTest
+ public void testSearchManagerInterfaceAvailable() {
+ assertNotNull(getSearchManagerService());
+ }
+
+ /**
+ * The goal of this test is to confirm that we can obtain
+ * a search manager at any time, and that for any given context,
+ * it is a singleton.
+ */
+ @LargeTest
+ public void testSearchManagerAvailable() {
+ SearchManager searchManager1 = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager1);
+ SearchManager searchManager2 = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager2);
+ assertSame(searchManager1, searchManager2 );
+ }
+
+ @MediumTest
+ public void testSearchables() {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ SearchableInfo si;
+
+ si = searchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, false);
+ assertNotNull(si);
+ assertFalse(searchManager.isDefaultSearchable(si));
+ si = searchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, true);
+ assertNotNull(si);
+ assertTrue(searchManager.isDefaultSearchable(si));
+ si = searchManager.getSearchableInfo(null, true);
+ assertNotNull(si);
+ assertTrue(searchManager.isDefaultSearchable(si));
+ }
+
+ /**
+ * Tests that startSearch() can be called multiple times without stopSearch()
+ * in between.
+ */
+ @MediumTest
+ public void testStartSearchIdempotent() throws Exception {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager);
+
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.stopSearch();
+ }
+
+ /**
+ * Tests that stopSearch() can be called when the search UI is not visible and can be
+ * called multiple times without startSearch() in between.
+ */
+ @MediumTest
+ public void testStopSearchIdempotent() throws Exception {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager);
+ searchManager.stopSearch();
+
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.stopSearch();
+ searchManager.stopSearch();
+ }
+
+ /**
+ * The goal of this test is to confirm that we can start and then
+ * stop a simple search.
+ */
+ @MediumTest
+ public void testSearchManagerInvocations() throws Exception {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager);
+
+ // These tests should simply run to completion w/o exceptions
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.stopSearch();
+
+ searchManager.startSearch("", false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.stopSearch();
+
+ searchManager.startSearch("test search string", false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.stopSearch();
+
+ searchManager.startSearch("test search string", true, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.stopSearch();
+ }
+
+}
diff --git a/core/tests/coretests/src/android/app/SearchablesTest.java b/core/tests/coretests/src/android/app/SearchablesTest.java
new file mode 100644
index 0000000..9b4520e
--- /dev/null
+++ b/core/tests/coretests/src/android/app/SearchablesTest.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2009 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 android.app;
+
+import android.app.SearchManager;
+import android.app.SearchableInfo;
+import android.app.SearchableInfo.ActionKeyInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.os.RemoteException;
+import android.server.search.Searchables;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.test.mock.MockContext;
+import android.test.mock.MockPackageManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.KeyEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * To launch this test from the command line:
+ *
+ * adb shell am instrument -w \
+ * -e class com.android.unit_tests.SearchablesTest \
+ * com.android.unit_tests/android.test.InstrumentationTestRunner
+ */
+@SmallTest
+public class SearchablesTest extends AndroidTestCase {
+
+ /*
+ * SearchableInfo tests
+ * Mock the context so I can provide very specific input data
+ * Confirm OK with "zero" searchables
+ * Confirm "good" metadata read properly
+ * Confirm "bad" metadata skipped properly
+ * Confirm ordering of searchables
+ * Confirm "good" actionkeys
+ * confirm "bad" actionkeys are rejected
+ * confirm XML ordering enforced (will fail today - bug in SearchableInfo)
+ * findActionKey works
+ * getIcon works
+ */
+
+ /**
+ * The goal of this test is to confirm proper operation of the
+ * SearchableInfo helper class.
+ *
+ * TODO: The metadata source needs to be mocked out because adding
+ * searchability metadata via this test is causing it to leak into the
+ * real system. So for now I'm just going to test for existence of the
+ * GlobalSearch app (which is searchable).
+ */
+ public void testSearchableGlobalSearch() {
+ // test basic array & hashmap
+ Searchables searchables = new Searchables(mContext);
+ searchables.buildSearchableList();
+
+ // test linkage from another activity
+ // TODO inject this via mocking into the package manager.
+ // TODO for now, just check for searchable GlobalSearch app (this isn't really a unit test)
+ ComponentName thisActivity = new ComponentName(
+ "com.android.globalsearch",
+ "com.android.globalsearch.GlobalSearch");
+
+ SearchableInfo si = searchables.getSearchableInfo(thisActivity);
+ assertNotNull(si);
+ assertEquals(thisActivity, si.getSearchActivity());
+
+ Context appContext = si.getActivityContext(mContext);
+ assertNotNull(appContext);
+ MoreAsserts.assertNotEqual(appContext, mContext);
+ assertEquals("Quick Search Box", appContext.getString(si.getHintId()));
+ assertEquals("Quick Search Box", appContext.getString(si.getLabelId()));
+ }
+
+ /**
+ * Test that non-searchable activities return no searchable info (this would typically
+ * trigger the use of the default searchable e.g. contacts)
+ */
+ public void testNonSearchable() {
+ // test basic array & hashmap
+ Searchables searchables = new Searchables(mContext);
+ searchables.buildSearchableList();
+
+ // confirm that we return null for non-searchy activities
+ ComponentName nonActivity = new ComponentName(
+ "com.android.frameworks.coretests",
+ "com.android.frameworks.coretests.activity.NO_SEARCH_ACTIVITY");
+ SearchableInfo si = searchables.getSearchableInfo(nonActivity);
+ assertNull(si);
+ }
+
+ /**
+ * Test that there is a default searchable (aka global search provider).
+ */
+ public void testDefaultSearchable() {
+ Searchables searchables = new Searchables(mContext);
+ searchables.buildSearchableList();
+ SearchableInfo si = searchables.getDefaultSearchable();
+ checkSearchable(si);
+ assertTrue(searchables.isDefaultSearchable(si));
+ }
+
+ /**
+ * This is an attempt to run the searchable info list with a mocked context. Here are some
+ * things I'd like to test.
+ *
+ * Confirm OK with "zero" searchables
+ * Confirm "good" metadata read properly
+ * Confirm "bad" metadata skipped properly
+ * Confirm ordering of searchables
+ * Confirm "good" actionkeys
+ * confirm "bad" actionkeys are rejected
+ * confirm XML ordering enforced (will fail today - bug in SearchableInfo)
+ * findActionKey works
+ * getIcon works
+
+ */
+ public void testSearchablesListReal() {
+ MyMockPackageManager mockPM = new MyMockPackageManager(mContext.getPackageManager());
+ MyMockContext mockContext = new MyMockContext(mContext, mockPM);
+
+ // build item list with real-world source data
+ mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_PASSTHROUGH);
+ Searchables searchables = new Searchables(mockContext);
+ searchables.buildSearchableList();
+ // tests with "real" searchables (deprecate, this should be a unit test)
+ ArrayList<SearchableInfo> searchablesList = searchables.getSearchablesList();
+ int count = searchablesList.size();
+ assertTrue(count >= 1); // this isn't really a unit test
+ checkSearchables(searchablesList);
+ ArrayList<SearchableInfo> global = searchables.getSearchablesInGlobalSearchList();
+ checkSearchables(global);
+ }
+
+ /**
+ * This round of tests confirms good operations with "zero" searchables found
+ */
+ public void testSearchablesListEmpty() {
+ MyMockPackageManager mockPM = new MyMockPackageManager(mContext.getPackageManager());
+ MyMockContext mockContext = new MyMockContext(mContext, mockPM);
+
+ mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_MOCK_ZERO);
+ Searchables searchables = new Searchables(mockContext);
+ searchables.buildSearchableList();
+ ArrayList<SearchableInfo> searchablesList = searchables.getSearchablesList();
+ assertNotNull(searchablesList);
+ MoreAsserts.assertEmpty(searchablesList);
+ ArrayList<SearchableInfo> global = searchables.getSearchablesInGlobalSearchList();
+ MoreAsserts.assertEmpty(global);
+ }
+
+ /**
+ * Generic health checker for an array of searchables.
+ *
+ * This is designed to pass for any semi-legal searchable, without knowing much about
+ * the format of the underlying data. It's fairly easy for a non-compliant application
+ * to provide meta-data that will pass here (e.g. a non-existent suggestions authority).
+ *
+ * @param searchables The list of searchables to examine.
+ */
+ private void checkSearchables(ArrayList<SearchableInfo> searchablesList) {
+ assertNotNull(searchablesList);
+ int count = searchablesList.size();
+ for (int ii = 0; ii < count; ii++) {
+ SearchableInfo si = searchablesList.get(ii);
+ checkSearchable(si);
+ }
+ }
+
+ private void checkSearchable(SearchableInfo si) {
+ assertNotNull(si);
+ assertTrue(si.getLabelId() != 0); // This must be a useable string
+ assertNotEmpty(si.getSearchActivity().getClassName());
+ assertNotEmpty(si.getSearchActivity().getPackageName());
+ if (si.getSuggestAuthority() != null) {
+ // The suggestion fields are largely optional, so we'll just confirm basic health
+ assertNotEmpty(si.getSuggestAuthority());
+ assertNullOrNotEmpty(si.getSuggestPath());
+ assertNullOrNotEmpty(si.getSuggestSelection());
+ assertNullOrNotEmpty(si.getSuggestIntentAction());
+ assertNullOrNotEmpty(si.getSuggestIntentData());
+ }
+ /* Add a way to get the entire action key list, then explicitly test its elements */
+ /* For now, test the most common action key (CALL) */
+ ActionKeyInfo ai = si.findActionKey(KeyEvent.KEYCODE_CALL);
+ if (ai != null) {
+ assertEquals(ai.getKeyCode(), KeyEvent.KEYCODE_CALL);
+ // one of these three fields must be non-null & non-empty
+ boolean m1 = (ai.getQueryActionMsg() != null) && (ai.getQueryActionMsg().length() > 0);
+ boolean m2 = (ai.getSuggestActionMsg() != null) && (ai.getSuggestActionMsg().length() > 0);
+ boolean m3 = (ai.getSuggestActionMsgColumn() != null) &&
+ (ai.getSuggestActionMsgColumn().length() > 0);
+ assertTrue(m1 || m2 || m3);
+ }
+
+ /*
+ * Find ways to test these:
+ *
+ * private int mSearchMode
+ * private Drawable mIcon
+ */
+
+ /*
+ * Explicitly not tested here:
+ *
+ * Can be null, so not much to see:
+ * public String mSearchHint
+ * private String mZeroQueryBanner
+ *
+ * To be deprecated/removed, so don't bother:
+ * public boolean mFilterMode
+ * public boolean mQuickStart
+ * private boolean mIconResized
+ * private int mIconResizeWidth
+ * private int mIconResizeHeight
+ *
+ * All of these are "internal" working variables, not part of any contract
+ * private ActivityInfo mActivityInfo
+ * private Rect mTempRect
+ * private String mSuggestProviderPackage
+ * private String mCacheActivityContext
+ */
+ }
+
+ /**
+ * Combo assert for "string not null and not empty"
+ */
+ private void assertNotEmpty(final String s) {
+ assertNotNull(s);
+ MoreAsserts.assertNotEqual(s, "");
+ }
+
+ /**
+ * Combo assert for "string null or (not null and not empty)"
+ */
+ private void assertNullOrNotEmpty(final String s) {
+ if (s != null) {
+ MoreAsserts.assertNotEqual(s, "");
+ }
+ }
+
+ /**
+ * This is a mock for context. Used to perform a true unit test on SearchableInfo.
+ *
+ */
+ private class MyMockContext extends MockContext {
+
+ protected Context mRealContext;
+ protected PackageManager mPackageManager;
+
+ /**
+ * Constructor.
+ *
+ * @param realContext Please pass in a real context for some pass-throughs to function.
+ */
+ MyMockContext(Context realContext, PackageManager packageManager) {
+ mRealContext = realContext;
+ mPackageManager = packageManager;
+ }
+
+ /**
+ * Resources. Pass through for now.
+ */
+ @Override
+ public Resources getResources() {
+ return mRealContext.getResources();
+ }
+
+ /**
+ * Package manager. Pass through for now.
+ */
+ @Override
+ public PackageManager getPackageManager() {
+ return mPackageManager;
+ }
+
+ /**
+ * Package manager. Pass through for now.
+ */
+ @Override
+ public Context createPackageContext(String packageName, int flags)
+ throws PackageManager.NameNotFoundException {
+ return mRealContext.createPackageContext(packageName, flags);
+ }
+
+ /**
+ * Message broadcast. Pass through for now.
+ */
+ @Override
+ public void sendBroadcast(Intent intent) {
+ mRealContext.sendBroadcast(intent);
+ }
+ }
+
+/**
+ * This is a mock for package manager. Used to perform a true unit test on SearchableInfo.
+ *
+ */
+ private class MyMockPackageManager extends MockPackageManager {
+
+ public final static int SEARCHABLES_PASSTHROUGH = 0;
+ public final static int SEARCHABLES_MOCK_ZERO = 1;
+ public final static int SEARCHABLES_MOCK_ONEGOOD = 2;
+ public final static int SEARCHABLES_MOCK_ONEGOOD_ONEBAD = 3;
+
+ protected PackageManager mRealPackageManager;
+ protected int mSearchablesMode;
+
+ public MyMockPackageManager(PackageManager realPM) {
+ mRealPackageManager = realPM;
+ mSearchablesMode = SEARCHABLES_PASSTHROUGH;
+ }
+
+ /**
+ * Set the mode for various tests.
+ */
+ public void setSearchablesMode(int newMode) {
+ switch (newMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ case SEARCHABLES_MOCK_ZERO:
+ mSearchablesMode = newMode;
+ break;
+
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Find activities that support a given intent.
+ *
+ * Retrieve all activities that can be performed for the given intent.
+ *
+ * @param intent The desired intent as per resolveActivity().
+ * @param flags Additional option flags. The most important is
+ * MATCH_DEFAULT_ONLY, to limit the resolution to only
+ * those activities that support the CATEGORY_DEFAULT.
+ *
+ * @return A List<ResolveInfo> containing one entry for each matching
+ * Activity. These are ordered from best to worst match -- that
+ * is, the first item in the list is what is returned by
+ * resolveActivity(). If there are no matching activities, an empty
+ * list is returned.
+ */
+ @Override
+ public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+ assertNotNull(intent);
+ assertTrue(intent.getAction().equals(Intent.ACTION_SEARCH)
+ || intent.getAction().equals(Intent.ACTION_WEB_SEARCH));
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.queryIntentActivities(intent, flags);
+ case SEARCHABLES_MOCK_ZERO:
+ return null;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public ResolveInfo resolveActivity(Intent intent, int flags) {
+ assertNotNull(intent);
+ assertTrue(intent.getAction().equals(Intent.ACTION_WEB_SEARCH)
+ || intent.getAction().equals(SearchManager.INTENT_ACTION_GLOBAL_SEARCH));
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.resolveActivity(intent, flags);
+ case SEARCHABLES_MOCK_ZERO:
+ return null;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Retrieve an XML file from a package. This is a low-level API used to
+ * retrieve XML meta data.
+ *
+ * @param packageName The name of the package that this xml is coming from.
+ * Can not be null.
+ * @param resid The resource identifier of the desired xml. Can not be 0.
+ * @param appInfo Overall information about <var>packageName</var>. This
+ * may be null, in which case the application information will be retrieved
+ * for you if needed; if you already have this information around, it can
+ * be much more efficient to supply it here.
+ *
+ * @return Returns an XmlPullParser allowing you to parse out the XML
+ * data. Returns null if the xml resource could not be found for any
+ * reason.
+ */
+ @Override
+ public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
+ assertNotNull(packageName);
+ MoreAsserts.assertNotEqual(packageName, "");
+ MoreAsserts.assertNotEqual(resid, 0);
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.getXml(packageName, resid, appInfo);
+ case SEARCHABLES_MOCK_ZERO:
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Find a single content provider by its base path name.
+ *
+ * @param name The name of the provider to find.
+ * @param flags Additional option flags. Currently should always be 0.
+ *
+ * @return ContentProviderInfo Information about the provider, if found,
+ * else null.
+ */
+ @Override
+ public ProviderInfo resolveContentProvider(String name, int flags) {
+ assertNotNull(name);
+ MoreAsserts.assertNotEqual(name, "");
+ assertEquals(flags, 0);
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.resolveContentProvider(name, flags);
+ case SEARCHABLES_MOCK_ZERO:
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Get the activity information for a particular activity.
+ *
+ * @param name The name of the activity to find.
+ * @param flags Additional option flags.
+ *
+ * @return ActivityInfo Information about the activity, if found, else null.
+ */
+ @Override
+ public ActivityInfo getActivityInfo(ComponentName name, int flags)
+ throws NameNotFoundException {
+ assertNotNull(name);
+ MoreAsserts.assertNotEqual(name, "");
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.getActivityInfo(name, flags);
+ case SEARCHABLES_MOCK_ZERO:
+ throw new NameNotFoundException();
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/SuggestionProvider.java b/core/tests/coretests/src/android/app/SuggestionProvider.java
new file mode 100644
index 0000000..9fb7dcf
--- /dev/null
+++ b/core/tests/coretests/src/android/app/SuggestionProvider.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 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 android.app;
+
+import android.app.SearchManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+
+/** Simple test provider that runs in the local process.
+ *
+ * Used by {@link SearchManagerTest}.
+ */
+public class SuggestionProvider extends ContentProvider {
+ private static final String TAG = "SuggestionProvider";
+
+ private static final int SEARCH_SUGGESTIONS = 1;
+
+ private static final UriMatcher sURLMatcher = new UriMatcher(
+ UriMatcher.NO_MATCH);
+
+ static {
+ sURLMatcher.addURI("*", SearchManager.SUGGEST_URI_PATH_QUERY,
+ SEARCH_SUGGESTIONS);
+ sURLMatcher.addURI("*", SearchManager.SUGGEST_URI_PATH_QUERY + "/*",
+ SEARCH_SUGGESTIONS);
+ }
+
+ private static final String[] COLUMNS = new String[] {
+ "_id",
+ SearchManager.SUGGEST_COLUMN_TEXT_1,
+ SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+ SearchManager.SUGGEST_COLUMN_QUERY
+ };
+
+ public SuggestionProvider() {
+ }
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri url, String[] projectionIn, String selection,
+ String[] selectionArgs, String sort) {
+ int match = sURLMatcher.match(url);
+ switch (match) {
+ case SEARCH_SUGGESTIONS:
+ String query = url.getLastPathSegment();
+ MatrixCursor cursor = new MatrixCursor(COLUMNS);
+ String[] suffixes = { "", "a", " foo", "XXXXXXXXXXXXXXXXX" };
+ for (String suffix : suffixes) {
+ addRow(cursor, query + suffix);
+ }
+ return cursor;
+ default:
+ throw new IllegalArgumentException("Unknown URL: " + url);
+ }
+ }
+
+ private void addRow(MatrixCursor cursor, String string) {
+ long id = cursor.getCount();
+ cursor.newRow().add(id).add(string).add(Intent.ACTION_SEARCH).add(string);
+ }
+
+ @Override
+ public String getType(Uri url) {
+ int match = sURLMatcher.match(url);
+ switch (match) {
+ case SEARCH_SUGGESTIONS:
+ return SearchManager.SUGGEST_MIME_TYPE;
+ default:
+ throw new IllegalArgumentException("Unknown URL: " + url);
+ }
+ }
+
+ @Override
+ public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
+ throw new UnsupportedOperationException("update not supported");
+ }
+
+ @Override
+ public Uri insert(Uri url, ContentValues initialValues) {
+ throw new UnsupportedOperationException("insert not supported");
+ }
+
+ @Override
+ public int delete(Uri url, String where, String[] whereArgs) {
+ throw new UnsupportedOperationException("delete not supported");
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/AbortReceiver.java b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
new file mode 100644
index 0000000..fef1775
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 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 android.app.activity;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.util.Log;
+
+public class AbortReceiver extends BroadcastReceiver
+{
+ public AbortReceiver()
+ {
+ }
+
+ public void onReceive(Context context, Intent intent)
+ {
+ //Log.i("AbortReceiver", "onReceiveIntent!");
+ try {
+ IBinder caller = intent.getIBinderExtra("caller");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(LaunchpadActivity.LAUNCH);
+ data.writeString(LaunchpadActivity.RECEIVER_ABORT);
+ caller.transact(LaunchpadActivity.GOT_RECEIVE_TRANSACTION, data, null, 0);
+ data.recycle();
+ } catch (RemoteException ex) {
+ }
+
+ // abort the broadcast!!!
+ abortBroadcast();
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java b/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java
new file mode 100644
index 0000000..61d73bc
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008 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 android.app.activity;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Configuration;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class ActivityManagerTest extends AndroidTestCase {
+
+ protected Context mContext;
+ protected ActivityManager mActivityManager;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getContext();
+ mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ }
+
+ // TODO should write a test for getRecentTasks()
+ // TODO should write a test for getRunningTasks()
+ // TODO should write a test for getMemoryInfo()
+
+ // TODO: Find a way to re-enable this. It fails if any other app has failed during startup.
+ // This is probably an OK assumption given the desired system status when we run unit tests,
+ // but it's not necessarily the right assumption for a unit test.
+ @Suppress
+ public void disabledTestErrorTasksEmpty() throws Exception {
+
+ List<ActivityManager.ProcessErrorStateInfo> errList;
+
+ errList = mActivityManager.getProcessesInErrorState();
+
+ // test: confirm list is empty
+ assertNull(errList);
+ }
+
+ // TODO: Force an activity into an error state - then see if we can catch it here?
+ @SmallTest
+ public void testErrorTasksWithError() throws Exception {
+
+ List<ActivityManager.ProcessErrorStateInfo> errList;
+
+ // TODO force another process into an error condition. How?
+
+ // test: confirm error list length is at least 1 under varying query lengths
+// checkErrorListMax(1,-1);
+
+ errList = mActivityManager.getProcessesInErrorState();
+
+ // test: the list itself is healthy
+ checkErrorListSanity(errList);
+
+ // test: confirm our application shows up in the list
+ }
+
+ // TODO: Force an activity into an ANR state - then see if we can catch it here?
+ @SmallTest
+ public void testErrorTasksWithANR() throws Exception {
+
+ List<ActivityManager.ProcessErrorStateInfo> errList;
+
+ // TODO: force an application into an ANR state
+
+ errList = mActivityManager.getProcessesInErrorState();
+
+ // test: the list itself is healthy
+ checkErrorListSanity(errList);
+
+ // test: confirm our ANR'ing application shows up in the list
+ }
+
+ @SmallTest
+ public void testGetDeviceConfigurationInfo() throws Exception {
+ ConfigurationInfo config = mActivityManager.getDeviceConfigurationInfo();
+ assertNotNull(config);
+ // Validate values against configuration retrieved from resources
+ Configuration vconfig = mContext.getResources().getConfiguration();
+ assertNotNull(vconfig);
+ assertEquals(config.reqKeyboardType, vconfig.keyboard);
+ assertEquals(config.reqTouchScreen, vconfig.touchscreen);
+ assertEquals(config.reqNavigation, vconfig.navigation);
+ if (vconfig.navigation == Configuration.NAVIGATION_NONAV) {
+ assertNotNull(config.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV);
+ }
+ if (vconfig.keyboard != Configuration.KEYBOARD_UNDEFINED) {
+ assertNotNull(config.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD);
+ }
+ }
+
+ // If any entries in appear in the list, sanity check them against all running applications
+ private void checkErrorListSanity(List<ActivityManager.ProcessErrorStateInfo> errList) {
+ if (errList == null) return;
+
+ Iterator<ActivityManager.ProcessErrorStateInfo> iter = errList.iterator();
+ while (iter.hasNext()) {
+ ActivityManager.ProcessErrorStateInfo info = iter.next();
+ assertNotNull(info);
+ // sanity checks
+ assertTrue((info.condition == ActivityManager.ProcessErrorStateInfo.CRASHED) ||
+ (info.condition == ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING));
+ // TODO look at each of these and consider a stronger test
+ // TODO can we cross-check at the process name via some other API?
+ // TODO is there a better test for strings, e.g. "assertIsLegalString")
+ assertNotNull(info.processName);
+ // reasonableness test for info.pid ?
+ assertNotNull(info.longMsg);
+ assertNotNull(info.shortMsg);
+ // is there any reasonable test for the crashData? Probably not.
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/ActivityTests.java b/core/tests/coretests/src/android/app/activity/ActivityTests.java
new file mode 100644
index 0000000..c57fe98
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/ActivityTests.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import junit.framework.TestSuite;
+
+public class ActivityTests {
+ public static final boolean DEBUG_LIFECYCLE = false;
+
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite(ActivityTests.class.getName());
+
+ suite.addTestSuite(BroadcastTest.class);
+ suite.addTestSuite(IntentSenderTest.class);
+ suite.addTestSuite(ActivityManagerTest.class);
+ suite.addTestSuite(LaunchTest.class);
+ suite.addTestSuite(LifecycleTest.class);
+ suite.addTestSuite(ServiceTest.class);
+ suite.addTestSuite(MetaDataTest.class);
+ // Remove temporarily until bug 1171309 is fixed.
+ //suite.addTestSuite(SubActivityTest.class);
+ suite.addTestSuite(SetTimeZonePermissionsTest.class);
+
+ return suite;
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/ActivityTestsBase.java b/core/tests/coretests/src/android/app/activity/ActivityTestsBase.java
new file mode 100644
index 0000000..232abe2
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/ActivityTestsBase.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.test.AndroidTestCase;
+import android.test.PerformanceTestCase;
+
+public class ActivityTestsBase extends AndroidTestCase
+ implements PerformanceTestCase, LaunchpadActivity.CallingTest {
+ public static final String PERMISSION_GRANTED =
+ "com.android.frameworks.coretests.permission.TEST_GRANTED";
+ public static final String PERMISSION_DENIED =
+ "com.android.frameworks.coretests.permission.TEST_DENIED";
+
+ protected Intent mIntent;
+
+ private PerformanceTestCase.Intermediates mIntermediates;
+ private String mExpecting;
+
+ // Synchronization of activity result.
+ private boolean mFinished;
+ private int mResultCode = 0;
+ private Intent mData;
+ private RuntimeException mResultStack = null;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mIntent = new Intent(mContext, LaunchpadActivity.class);
+ mIntermediates = null;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mIntermediates = null;
+ super.tearDown();
+ }
+
+ public boolean isPerformanceOnly() {
+ return false;
+ }
+
+ public void setInternalIterations(int count) {
+ }
+
+ public void startTiming(boolean realTime) {
+ if (mIntermediates != null) {
+ mIntermediates.startTiming(realTime);
+ }
+ }
+
+ public void addIntermediate(String name) {
+ if (mIntermediates != null) {
+ mIntermediates.addIntermediate(name);
+ }
+ }
+
+ public void addIntermediate(String name, long timeInNS) {
+ if (mIntermediates != null) {
+ mIntermediates.addIntermediate(name, timeInNS);
+ }
+ }
+
+ public void finishTiming(boolean realTime) {
+ if (mIntermediates != null) {
+ mIntermediates.finishTiming(realTime);
+ }
+ }
+
+ public void activityFinished(int resultCode, Intent data, RuntimeException where) {
+ finishWithResult(resultCode, data, where);
+ }
+
+ public Intent editIntent() {
+ return mIntent;
+ }
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public int startPerformance(Intermediates intermediates) {
+ mIntermediates = intermediates;
+ return 1;
+ }
+
+ public void finishGood() {
+ finishWithResult(Activity.RESULT_OK, null);
+ }
+
+ public void finishBad(String error) {
+ finishWithResult(Activity.RESULT_CANCELED, (new Intent()).setAction(error));
+ }
+
+ public void finishWithResult(int resultCode, Intent data) {
+ RuntimeException where = new RuntimeException("Original error was here");
+ where.fillInStackTrace();
+ finishWithResult(resultCode, data, where);
+ }
+
+ public void finishWithResult(int resultCode, Intent data, RuntimeException where) {
+ synchronized (this) {
+ //System.out.println("*** Activity finished!!");
+ mResultCode = resultCode;
+ mData = data;
+ mResultStack = where;
+ mFinished = true;
+ notifyAll();
+ }
+ }
+
+ public int runLaunchpad(String action) {
+ LaunchpadActivity.setCallingTest(this);
+
+ synchronized (this) {
+ mIntent.setAction(action);
+ mFinished = false;
+ //System.out.println("*** Starting: " + mIntent);
+ mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(mIntent);
+ }
+
+ return waitForResultOrThrow(60 * 1000);
+ }
+
+ public int waitForResultOrThrow(int timeoutMs) {
+ return waitForResultOrThrow(timeoutMs, null);
+ }
+
+ public int waitForResultOrThrow(int timeoutMs, String expected) {
+ int res = waitForResult(timeoutMs, expected);
+
+ if (res == Activity.RESULT_CANCELED) {
+ if (mResultStack != null) {
+ throw new RuntimeException(
+ mData != null ? mData.toString() : "Unable to launch",
+ mResultStack);
+ } else {
+ throw new RuntimeException(
+ mData != null ? mData.toString() : "Unable to launch");
+ }
+ }
+ return res;
+ }
+
+ public int waitForResult(int timeoutMs, String expected) {
+ mExpecting = expected;
+
+ long endTime = System.currentTimeMillis() + timeoutMs;
+
+ boolean timeout = false;
+ synchronized (this) {
+ while (!mFinished) {
+ long delay = endTime - System.currentTimeMillis();
+ if (delay < 0) {
+ timeout = true;
+ break;
+ }
+
+ try {
+ wait(delay);
+ } catch (java.lang.InterruptedException e) {
+ // do nothing
+ }
+ }
+ }
+
+ mFinished = false;
+
+ if (timeout) {
+ mResultCode = Activity.RESULT_CANCELED;
+ onTimeout();
+ }
+ return mResultCode;
+ }
+
+ public int getResultCode() {
+ return mResultCode;
+ }
+
+ public Intent getResultData() {
+ return mData;
+ }
+
+ public RuntimeException getResultStack() {
+ return mResultStack;
+ }
+
+ public void onTimeout() {
+ String msg = mExpecting == null
+ ? "Timeout" : ("Timeout while expecting " + mExpecting);
+ finishWithResult(Activity.RESULT_CANCELED, (new Intent()).setAction(msg));
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/BroadcastTest.java b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
new file mode 100644
index 0000000..4b1f9fd
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.test.FlakyTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+
+import java.util.Arrays;
+
+public class BroadcastTest extends ActivityTestsBase {
+ public static final int BROADCAST_TIMEOUT = 5 * 1000;
+
+ public static final String BROADCAST_REGISTERED =
+ "com.android.frameworks.coretests.activity.BROADCAST_REGISTERED";
+ public static final String BROADCAST_LOCAL =
+ "com.android.frameworks.coretests.activity.BROADCAST_LOCAL";
+ public static final String BROADCAST_LOCAL_GRANTED =
+ "com.android.frameworks.coretests.activity.BROADCAST_LOCAL_GRANTED";
+ public static final String BROADCAST_LOCAL_DENIED =
+ "com.android.frameworks.coretests.activity.BROADCAST_LOCAL_DENIED";
+ public static final String BROADCAST_REMOTE =
+ "com.android.frameworks.coretests.activity.BROADCAST_REMOTE";
+ public static final String BROADCAST_REMOTE_GRANTED =
+ "com.android.frameworks.coretests.activity.BROADCAST_REMOTE_GRANTED";
+ public static final String BROADCAST_REMOTE_DENIED =
+ "com.android.frameworks.coretests.activity.BROADCAST_REMOTE_DENIED";
+ public static final String BROADCAST_ALL =
+ "com.android.frameworks.coretests.activity.BROADCAST_ALL";
+ public static final String BROADCAST_MULTI =
+ "com.android.frameworks.coretests.activity.BROADCAST_MULTI";
+ public static final String BROADCAST_ABORT =
+ "com.android.frameworks.coretests.activity.BROADCAST_ABORT";
+
+ public static final String BROADCAST_STICKY1 =
+ "com.android.frameworks.coretests.activity.BROADCAST_STICKY1";
+ public static final String BROADCAST_STICKY2 =
+ "com.android.frameworks.coretests.activity.BROADCAST_STICKY2";
+
+ public static final String BROADCAST_FAIL_REGISTER =
+ "com.android.frameworks.coretests.activity.BROADCAST_FAIL_REGISTER";
+ public static final String BROADCAST_FAIL_BIND =
+ "com.android.frameworks.coretests.activity.BROADCAST_FAIL_BIND";
+
+ public static final String RECEIVER_REG = "receiver-reg";
+ public static final String RECEIVER_LOCAL = "receiver-local";
+ public static final String RECEIVER_REMOTE = "receiver-remote";
+ public static final String RECEIVER_ABORT = "receiver-abort";
+ public static final String RECEIVER_RESULTS = "receiver-results";
+
+ public static final String DATA_1 = "one";
+ public static final String DATA_2 = "two";
+
+ public static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
+ public static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
+
+ private String[] mExpectedReceivers = null;
+ private int mNextReceiver;
+
+ private String[] mExpectedData = null;
+ private boolean[] mReceivedData = null;
+
+ boolean mReceiverRegistered = false;
+
+ public void setExpectedReceivers(String[] receivers) {
+ mExpectedReceivers = receivers;
+ mNextReceiver = 0;
+ }
+
+ public void setExpectedData(String[] data) {
+ mExpectedData = data;
+ mReceivedData = new boolean[data.length];
+ }
+
+ public void onTimeout() {
+ String msg = "Timeout";
+ if (mExpectedReceivers != null && mNextReceiver < mExpectedReceivers.length) {
+ msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver];
+ }
+ finishBad(msg);
+ }
+
+ public Intent makeBroadcastIntent(String action) {
+ Intent intent = new Intent(action, null);
+ intent.putExtra("caller", mCallTarget);
+ return intent;
+ }
+
+ public void finishWithResult(int resultCode, Intent data) {
+ unregisterMyReceiver();
+ super.finishWithResult(resultCode, data);
+ }
+
+ public final void gotReceive(String name, Intent intent) {
+ synchronized (this) {
+
+ //System.out.println("Got receive: " + name);
+ //System.out.println(mNextReceiver + " in " + mExpectedReceivers);
+ //new RuntimeException("stack").printStackTrace();
+
+ addIntermediate(name);
+
+ if (mExpectedData != null) {
+ int n = mExpectedData.length;
+ int i;
+ boolean prev = false;
+ for (i = 0; i < n; i++) {
+ if (mExpectedData[i].equals(intent.getStringExtra("test"))) {
+ if (mReceivedData[i]) {
+ prev = true;
+ continue;
+ }
+ mReceivedData[i] = true;
+ break;
+ }
+ }
+ if (i >= n) {
+ if (prev) {
+ finishBad("Receive got data too many times: "
+ + intent.getStringExtra("test"));
+ } else {
+ finishBad("Receive got unexpected data: "
+ + intent.getStringExtra("test"));
+ }
+ new RuntimeException("stack").printStackTrace();
+ return;
+ }
+ }
+
+ if (mNextReceiver >= mExpectedReceivers.length) {
+ finishBad("Got too many onReceiveIntent() calls!");
+// System.out.println("Too many intents received: now at "
+// + mNextReceiver + ", expect list: "
+// + Arrays.toString(mExpectedReceivers));
+ fail("Got too many onReceiveIntent() calls!");
+ } else if (!mExpectedReceivers[mNextReceiver].equals(name)) {
+ finishBad("Receive out of order: got " + name
+ + " but expected "
+ + mExpectedReceivers[mNextReceiver]);
+ fail("Receive out of order: got " + name
+ + " but expected "
+ + mExpectedReceivers[mNextReceiver]);
+ } else {
+ mNextReceiver++;
+ if (mNextReceiver == mExpectedReceivers.length) {
+ finishTest();
+ }
+ }
+ }
+ }
+
+ public void registerMyReceiver(IntentFilter filter, String permission) {
+ mReceiverRegistered = true;
+ //System.out.println("Registering: " + mReceiver);
+ getContext().registerReceiver(mReceiver, filter, permission, null);
+ }
+
+ public void unregisterMyReceiver() {
+ if (mReceiverRegistered) {
+ unregisterMyReceiverNoCheck();
+ }
+ }
+
+ public void unregisterMyReceiverNoCheck() {
+ mReceiverRegistered = false;
+ //System.out.println("Unregistering: " + mReceiver);
+ getContext().unregisterReceiver(mReceiver);
+ }
+
+ public void onRegisteredReceiver(Intent intent) {
+ gotReceive(RECEIVER_REG, intent);
+ }
+
+ private Binder mCallTarget = new Binder() {
+ public boolean onTransact(int code, Parcel data, Parcel reply,
+ int flags) {
+ data.setDataPosition(0);
+ data.enforceInterface(LaunchpadActivity.LAUNCH);
+ if (code == GOT_RECEIVE_TRANSACTION) {
+ String name = data.readString();
+ gotReceive(name, null);
+ return true;
+ } else if (code == ERROR_TRANSACTION) {
+ finishBad(data.readString());
+ return true;
+ }
+ return false;
+ }
+ };
+
+ private void finishTest() {
+ if (mReceiverRegistered) {
+ addIntermediate("before-unregister");
+ unregisterMyReceiver();
+ }
+ finishTiming(true);
+ finishGood();
+ }
+
+ private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ //System.out.println("Receive in: " + this + ": " + intent);
+ onRegisteredReceiver(intent);
+ }
+ };
+
+ // Mark flaky until http://b/issue?id=1191607 is resolved.
+ @FlakyTest(tolerance=2)
+ public void testRegistered() throws Exception {
+ runLaunchpad(LaunchpadActivity.BROADCAST_REGISTERED);
+ }
+
+ public void testLocal() throws Exception {
+ runLaunchpad(LaunchpadActivity.BROADCAST_LOCAL);
+ }
+
+ public void testRemote() throws Exception {
+ runLaunchpad(LaunchpadActivity.BROADCAST_REMOTE);
+ }
+
+ public void testAbort() throws Exception {
+ runLaunchpad(LaunchpadActivity.BROADCAST_ABORT);
+ }
+
+ @FlakyTest(tolerance=2)
+ public void testAll() throws Exception {
+ runLaunchpad(LaunchpadActivity.BROADCAST_ALL);
+ }
+
+ @FlakyTest(tolerance=2)
+ public void testMulti() throws Exception {
+ runLaunchpad(LaunchpadActivity.BROADCAST_MULTI);
+ }
+
+ private class TestBroadcastReceiver extends BroadcastReceiver {
+ public boolean mHaveResult = false;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ synchronized (BroadcastTest.this) {
+ mHaveResult = true;
+ BroadcastTest.this.notifyAll();
+ }
+ }
+ }
+
+ public void testResult() throws Exception {
+ TestBroadcastReceiver broadcastReceiver = new TestBroadcastReceiver();
+
+ synchronized (this) {
+ Bundle map = new Bundle();
+ map.putString("foo", "you");
+ map.putString("remove", "me");
+ getContext().sendOrderedBroadcast(
+ new Intent("com.android.frameworks.coretests.activity.BROADCAST_RESULT"),
+ null, broadcastReceiver, null, 1, "foo", map);
+ while (!broadcastReceiver.mHaveResult) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ //System.out.println("Code: " + mResultCode + ", data: " + mResultData);
+ //System.out.println("Extras: " + mResultExtras);
+
+ assertEquals("Incorrect code: " + broadcastReceiver.getResultCode(),
+ 3, broadcastReceiver.getResultCode());
+
+ assertEquals("bar", broadcastReceiver.getResultData());
+
+ Bundle resultExtras = broadcastReceiver.getResultExtras(false);
+ assertEquals("them", resultExtras.getString("bar"));
+ assertEquals("you", resultExtras.getString("foo"));
+ assertNull(resultExtras.getString("remove"));
+ }
+ }
+
+ public void testSetSticky() throws Exception {
+ Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
+ intent.putExtra("test", LaunchpadActivity.DATA_1);
+ ActivityManagerNative.getDefault().unbroadcastIntent(null, intent);
+
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ addIntermediate("finished-broadcast");
+
+ IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
+ Intent sticky = getContext().registerReceiver(null, filter);
+ assertNotNull("Sticky not found", sticky);
+ assertEquals(LaunchpadActivity.DATA_1, sticky.getStringExtra("test"));
+ }
+
+ public void testClearSticky() throws Exception {
+ Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
+ intent.putExtra("test", LaunchpadActivity.DATA_1);
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+
+ ActivityManagerNative.getDefault().unbroadcastIntent(
+ null, new Intent(LaunchpadActivity.BROADCAST_STICKY1, null));
+ addIntermediate("finished-unbroadcast");
+
+ IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
+ Intent sticky = getContext().registerReceiver(null, filter);
+ assertNull("Sticky not found", sticky);
+ }
+
+ public void testReplaceSticky() throws Exception {
+ Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
+ intent.putExtra("test", LaunchpadActivity.DATA_1);
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ intent.putExtra("test", LaunchpadActivity.DATA_2);
+
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ addIntermediate("finished-broadcast");
+
+ IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
+ Intent sticky = getContext().registerReceiver(null, filter);
+ assertNotNull("Sticky not found", sticky);
+ assertEquals(LaunchpadActivity.DATA_2, sticky.getStringExtra("test"));
+ }
+
+ // Marking flaky until http://b/issue?id=1191337 is resolved
+ @FlakyTest(tolerance=2)
+ public void testReceiveSticky() throws Exception {
+ Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
+ intent.putExtra("test", LaunchpadActivity.DATA_1);
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+
+ runLaunchpad(LaunchpadActivity.BROADCAST_STICKY1);
+ }
+
+ // Marking flaky until http://b/issue?id=1191337 is resolved
+ @FlakyTest(tolerance=2)
+ public void testReceive2Sticky() throws Exception {
+ Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
+ intent.putExtra("test", LaunchpadActivity.DATA_1);
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ intent = new Intent(LaunchpadActivity.BROADCAST_STICKY2, null);
+ intent.putExtra("test", LaunchpadActivity.DATA_2);
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+
+ runLaunchpad(LaunchpadActivity.BROADCAST_STICKY2);
+ }
+
+ public void testRegisteredReceivePermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_REG});
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_GRANTED);
+ addIntermediate("after-register");
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testRegisteredReceivePermissionDenied() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_DENIED);
+ addIntermediate("after-register");
+
+ BroadcastReceiver finish = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ getContext().sendOrderedBroadcast(
+ makeBroadcastIntent(BROADCAST_REGISTERED),
+ null, finish, null, Activity.RESULT_CANCELED, null, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testRegisteredBroadcastPermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_REG});
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
+ addIntermediate("after-register");
+ getContext().sendBroadcast(
+ makeBroadcastIntent(BROADCAST_REGISTERED),
+ PERMISSION_GRANTED);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testRegisteredBroadcastPermissionDenied() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
+ addIntermediate("after-register");
+
+ BroadcastReceiver finish = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ getContext().sendOrderedBroadcast(
+ makeBroadcastIntent(BROADCAST_REGISTERED),
+ PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
+ null, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testLocalReceivePermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_LOCAL});
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL_GRANTED));
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testLocalReceivePermissionDenied() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+
+ BroadcastReceiver finish = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ getContext().sendOrderedBroadcast(
+ makeBroadcastIntent(BROADCAST_LOCAL_DENIED),
+ null, finish, null, Activity.RESULT_CANCELED,
+ null, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testLocalBroadcastPermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_LOCAL});
+ getContext().sendBroadcast(
+ makeBroadcastIntent(BROADCAST_LOCAL),
+ PERMISSION_GRANTED);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testLocalBroadcastPermissionDenied() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+
+ BroadcastReceiver finish = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ getContext().sendOrderedBroadcast(
+ makeBroadcastIntent(BROADCAST_LOCAL),
+ PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
+ null, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testRemoteReceivePermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_REMOTE});
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE_GRANTED));
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testRemoteReceivePermissionDenied() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+
+ BroadcastReceiver finish = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ getContext().sendOrderedBroadcast(
+ makeBroadcastIntent(BROADCAST_REMOTE_DENIED),
+ null, finish, null, Activity.RESULT_CANCELED,
+ null, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testRemoteBroadcastPermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_REMOTE});
+ getContext().sendBroadcast(
+ makeBroadcastIntent(BROADCAST_REMOTE),
+ PERMISSION_GRANTED);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testRemoteBroadcastPermissionDenied() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+
+ BroadcastReceiver finish = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ getContext().sendOrderedBroadcast(
+ makeBroadcastIntent(BROADCAST_REMOTE),
+ PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
+ null, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testReceiverCanNotRegister() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_LOCAL});
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_REGISTER));
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testReceiverCanNotBind() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_LOCAL});
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_BIND));
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ }
+
+ public void testLocalUnregisterTwice() throws Exception {
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
+ unregisterMyReceiverNoCheck();
+ try {
+ unregisterMyReceiverNoCheck();
+ fail("No exception thrown on second unregister");
+ } catch (IllegalArgumentException e) {
+ Log.i("foo", "Unregister exception", e);
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/ClearTop.java b/core/tests/coretests/src/android/app/activity/ClearTop.java
new file mode 100644
index 0000000..a5ee2ce
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/ClearTop.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+public class ClearTop extends Activity {
+ public static final String WAIT_CLEAR_TASK = "waitClearTask";
+
+ public ClearTop() {
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ //Log.i("foo", "Creating: " + this);
+ Intent intent = new Intent(getIntent()).setAction(LocalScreen.CLEAR_TASK)
+ .setClass(this, LocalScreen.class);
+ startActivity(intent);
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ //Log.i("foo", "New intent in " + this + ": " + intent);
+ if (LocalScreen.CLEAR_TASK.equals(intent.getAction())) {
+ setResult(RESULT_OK);
+ } else {
+ setResult(RESULT_CANCELED, new Intent().setAction(
+ "New intent received " + intent + ", expecting action "
+ + TestedScreen.CLEAR_TASK));
+ }
+ finish();
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/IntentSenderTest.java b/core/tests/coretests/src/android/app/activity/IntentSenderTest.java
new file mode 100644
index 0000000..3c30915
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/IntentSenderTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.test.suitebuilder.annotation.Suppress;
+import android.os.Bundle;
+import android.test.suitebuilder.annotation.Suppress;
+
+public class IntentSenderTest extends BroadcastTest {
+
+ public void testRegisteredReceivePermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_REG});
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_GRANTED);
+ addIntermediate("after-register");
+ PendingIntent is = PendingIntent.getBroadcast(getContext(), 0,
+ makeBroadcastIntent(BROADCAST_REGISTERED), 0);
+ is.send();
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ is.cancel();
+ }
+
+ public void testRegisteredReceivePermissionDenied() throws Exception {
+ final Intent intent = makeBroadcastIntent(BROADCAST_REGISTERED);
+
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_DENIED);
+ addIntermediate("after-register");
+
+ PendingIntent.OnFinished finish = new PendingIntent.OnFinished() {
+ public void onSendFinished(PendingIntent pi, Intent intent,
+ int resultCode, String resultData, Bundle resultExtras) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ PendingIntent is = PendingIntent.getBroadcast(getContext(), 0, intent, 0);
+ is.send(Activity.RESULT_CANCELED, finish, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ is.cancel();
+ }
+
+ public void testLocalReceivePermissionGranted() throws Exception {
+ setExpectedReceivers(new String[]{RECEIVER_LOCAL});
+ PendingIntent is = PendingIntent.getBroadcast(getContext(), 0,
+ makeBroadcastIntent(BROADCAST_LOCAL_GRANTED), 0);
+ is.send();
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ is.cancel();
+ }
+
+ public void testLocalReceivePermissionDenied() throws Exception {
+ final Intent intent = makeBroadcastIntent(BROADCAST_LOCAL_DENIED);
+
+ setExpectedReceivers(new String[]{RECEIVER_RESULTS});
+
+ PendingIntent.OnFinished finish = new PendingIntent.OnFinished() {
+ public void onSendFinished(PendingIntent pi, Intent intent,
+ int resultCode, String resultData, Bundle resultExtras) {
+ gotReceive(RECEIVER_RESULTS, intent);
+ }
+ };
+
+ PendingIntent is = PendingIntent.getBroadcast(getContext(), 0, intent, 0);
+ is.send(Activity.RESULT_CANCELED, finish, null);
+ waitForResultOrThrow(BROADCAST_TIMEOUT);
+ is.cancel();
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/LaunchTest.java b/core/tests/coretests/src/android/app/activity/LaunchTest.java
new file mode 100644
index 0000000..5893fd0
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LaunchTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.ComponentName;
+import android.test.suitebuilder.annotation.LargeTest;
+
+public class LaunchTest extends ActivityTestsBase {
+
+ @LargeTest
+ public void testColdActivity() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), TestedActivity.class));
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ @LargeTest
+ public void testLocalActivity() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), LocalActivity.class));
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ @LargeTest
+ public void testColdScreen() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), TestedScreen.class));
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ @LargeTest
+ public void testLocalScreen() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), LocalScreen.class));
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ @LargeTest
+ public void testForwardResult() throws Exception {
+ runLaunchpad(LaunchpadActivity.FORWARD_RESULT);
+ }
+
+ // The following is disabled until we can catch and recover from
+ // application errors.
+ public void xxtestBadParcelable() throws Exception {
+ // All we really care about for this test is that the system
+ // doesn't crash.
+ runLaunchpad(LaunchpadActivity.BAD_PARCELABLE);
+ }
+
+ @LargeTest
+ public void testClearTopInCreate() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), ClearTop.class));
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ @LargeTest
+ public void testClearTopWhileResumed() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), ClearTop.class));
+ mIntent.putExtra(ClearTop.WAIT_CLEAR_TASK, true);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+}
+
+
diff --git a/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java b/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java
new file mode 100644
index 0000000..7662456
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.test.PerformanceTestCase;
+import android.util.Log;
+
+class MyBadParcelable implements Parcelable {
+ public MyBadParcelable() {
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString("I am bad");
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<MyBadParcelable> CREATOR
+ = new Parcelable.Creator<MyBadParcelable>() {
+ public MyBadParcelable createFromParcel(Parcel in) {
+ return new MyBadParcelable(in);
+ }
+
+ public MyBadParcelable[] newArray(int size) {
+ return new MyBadParcelable[size];
+ }
+ };
+
+ public MyBadParcelable(Parcel in) {
+ String nm = in.readString();
+ }
+}
+
+public class LaunchpadActivity extends Activity {
+ public interface CallingTest extends PerformanceTestCase.Intermediates {
+ public void startTiming(boolean realTime);
+ public void addIntermediate(String name);
+ public void addIntermediate(String name, long timeInNS);
+ public void finishTiming(boolean realTime);
+ public void activityFinished(int resultCode, Intent data,
+ RuntimeException where);
+ }
+
+ // Also used as the Binder interface descriptor string in these tests
+ public static final String LAUNCH = "com.android.frameworks.coretests.activity.LAUNCH";
+
+ public static final String FORWARD_RESULT =
+ "com.android.frameworks.coretests.activity.FORWARD_RESULT";
+ public static final String RETURNED_RESULT =
+ "com.android.frameworks.coretests.activity.RETURNED_RESULT";
+
+ public static final String BAD_PARCELABLE =
+ "comcom.android.frameworks.coretests.activity.BAD_PARCELABLE";
+
+ public static final int LAUNCHED_RESULT = 1;
+ public static final int FORWARDED_RESULT = 2;
+
+ public static final String LIFECYCLE_BASIC =
+ "com.android.frameworks.coretests.activity.LIFECYCLE_BASIC";
+ public static final String LIFECYCLE_SCREEN =
+ "com.android.frameworks.coretests.activity.LIFECYCLE_SCREEN";
+ public static final String LIFECYCLE_DIALOG =
+ "com.android.frameworks.coretests.activity.LIFECYCLE_DIALOG";
+ public static final String LIFECYCLE_FINISH_CREATE =
+ "com.android.frameworks.coretests.activity.LIFECYCLE_FINISH_CREATE";
+ public static final String LIFECYCLE_FINISH_START =
+ "com.android.frameworks.coretests.activity.LIFECYCLE_FINISH_START";
+
+ public static final String BROADCAST_REGISTERED =
+ "com.android.frameworks.coretests.activity.BROADCAST_REGISTERED";
+ public static final String BROADCAST_LOCAL =
+ "com.android.frameworks.coretests.activity.BROADCAST_LOCAL";
+ public static final String BROADCAST_REMOTE =
+ "com.android.frameworks.coretests.activity.BROADCAST_REMOTE";
+ public static final String BROADCAST_ALL =
+ "com.android.frameworks.coretests.activity.BROADCAST_ALL";
+ public static final String BROADCAST_REPEAT =
+ "com.android.frameworks.coretests.activity.BROADCAST_REPEAT";
+ public static final String BROADCAST_MULTI =
+ "com.android.frameworks.coretests.activity.BROADCAST_MULTI";
+ public static final String BROADCAST_ABORT =
+ "com.android.frameworks.coretests.activity.BROADCAST_ABORT";
+
+ public static final String BROADCAST_STICKY1 =
+ "com.android.frameworks.coretests.activity.BROADCAST_STICKY1";
+ public static final String BROADCAST_STICKY2 =
+ "com.android.frameworks.coretests.activity.BROADCAST_STICKY2";
+
+ public static final String RECEIVER_REG = "receiver-reg";
+ public static final String RECEIVER_LOCAL = "receiver-local";
+ public static final String RECEIVER_REMOTE = "receiver-remote";
+ public static final String RECEIVER_ABORT = "receiver-abort";
+
+ public static final String DATA_1 = "one";
+ public static final String DATA_2 = "two";
+
+ public static final String ON_START = "onStart";
+ public static final String ON_RESTART = "onRestart";
+ public static final String ON_RESUME = "onResume";
+ public static final String ON_FREEZE = "onSaveInstanceState";
+ public static final String ON_PAUSE = "onPause";
+ public static final String ON_STOP = "onStop";
+ public static final String ON_DESTROY = "onDestroy";
+
+ public static final String DO_FINISH = "finish";
+ public static final String DO_LOCAL_SCREEN = "local-screen";
+ public static final String DO_LOCAL_DIALOG = "local-dialog";
+
+ private boolean mBadParcelable = false;
+
+ private boolean mStarted = false;
+ private long mStartTime;
+
+ private int mResultCode = RESULT_CANCELED;
+ private Intent mData = (new Intent()).setAction("No result received");
+ private RuntimeException mResultStack = null;
+
+ private String[] mExpectedLifecycle = null;
+ private int mNextLifecycle;
+
+ private String[] mExpectedReceivers = null;
+ private int mNextReceiver;
+
+ private String[] mExpectedData = null;
+ private boolean[] mReceivedData = null;
+
+ boolean mReceiverRegistered = false;
+
+ private static CallingTest sCallingTest = null;
+
+ public static void setCallingTest(CallingTest ct) {
+ sCallingTest = ct;
+ }
+
+ public LaunchpadActivity() {
+ mStartTime = System.currentTimeMillis();
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ String action = getIntent().getAction();
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "CREATE lauchpad "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ if (LIFECYCLE_BASIC.equals(action)) {
+ setExpectedLifecycle(new String[]{ON_START, ON_RESUME,
+ DO_FINISH, ON_PAUSE, ON_STOP, ON_DESTROY});
+ } else if (LIFECYCLE_SCREEN.equals(action)) {
+ setExpectedLifecycle(new String[]{ON_START, ON_RESUME,
+ DO_LOCAL_SCREEN, ON_FREEZE, ON_PAUSE, ON_STOP,
+ ON_RESTART, ON_START, ON_RESUME,
+ DO_FINISH, ON_PAUSE, ON_STOP, ON_DESTROY});
+ } else if (LIFECYCLE_DIALOG.equals(action)) {
+ setExpectedLifecycle(new String[]{ON_START, ON_RESUME,
+ DO_LOCAL_DIALOG, ON_FREEZE, ON_PAUSE, ON_RESUME,
+ DO_FINISH, ON_PAUSE, ON_STOP, ON_DESTROY});
+ } else if (LIFECYCLE_FINISH_CREATE.equals(action)) {
+ // This one behaves a little differently when running in a group.
+ if (getParent() == null) {
+ setExpectedLifecycle(new String[]{ON_DESTROY});
+ } else {
+ setExpectedLifecycle(new String[]{ON_START, ON_STOP, ON_DESTROY});
+ }
+ finish();
+ } else if (LIFECYCLE_FINISH_START.equals(action)) {
+ setExpectedLifecycle(new String[]{ON_START, DO_FINISH,
+ ON_STOP, ON_DESTROY});
+ }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "START lauchpad "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ checkLifecycle(ON_START);
+ }
+
+ @Override
+ protected void onRestart() {
+ super.onStart();
+ checkLifecycle(ON_RESTART);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "RESUME lauchpad "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ checkLifecycle(ON_RESUME);
+
+ if (!mStarted) {
+ mStarted = true;
+
+ mHandler.postDelayed(mTimeout, 5 * 1000);
+
+ String action = getIntent().getAction();
+
+ sCallingTest.startTiming(true);
+
+ if (LAUNCH.equals(action)) {
+ Intent intent = getIntent();
+ intent.setFlags(0);
+ intent.setComponent((ComponentName)
+ intent.getParcelableExtra("component"));
+ //System.out.println("*** Launchpad is starting: comp=" + intent.component);
+ startActivityForResult(intent, LAUNCHED_RESULT);
+ } else if (FORWARD_RESULT.equals(action)) {
+ Intent intent = getIntent();
+ intent.setFlags(0);
+ intent.setClass(this, LocalScreen.class);
+ startActivityForResult(intent, FORWARDED_RESULT);
+ } else if (BAD_PARCELABLE.equals(action)) {
+ mBadParcelable = true;
+ Intent intent = getIntent();
+ intent.setFlags(0);
+ intent.setClass(this, LocalScreen.class);
+ startActivityForResult(intent, LAUNCHED_RESULT);
+ } else if (BROADCAST_REGISTERED.equals(action)) {
+ setExpectedReceivers(new String[]{RECEIVER_REG});
+ registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED));
+ sCallingTest.addIntermediate("after-register");
+ sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
+ } else if (BROADCAST_LOCAL.equals(action)) {
+ setExpectedReceivers(new String[]{RECEIVER_LOCAL});
+ sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL));
+ } else if (BROADCAST_REMOTE.equals(action)) {
+ setExpectedReceivers(new String[]{RECEIVER_REMOTE});
+ sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE));
+ } else if (BROADCAST_ALL.equals(action)) {
+ setExpectedReceivers(new String[]{
+ RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL});
+ registerMyReceiver(new IntentFilter(BROADCAST_ALL));
+ sCallingTest.addIntermediate("after-register");
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ } else if (BROADCAST_MULTI.equals(action)) {
+ setExpectedReceivers(new String[]{
+ RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
+ RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
+ RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
+ RECEIVER_LOCAL, RECEIVER_REMOTE,
+ RECEIVER_LOCAL, RECEIVER_REMOTE,
+ RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
+ RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
+ RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
+ RECEIVER_REMOTE, RECEIVER_LOCAL,
+ RECEIVER_REMOTE, RECEIVER_LOCAL});
+ registerMyReceiver(new IntentFilter(BROADCAST_ALL));
+ sCallingTest.addIntermediate("after-register");
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT), null);
+ } else if (BROADCAST_ABORT.equals(action)) {
+ setExpectedReceivers(new String[]{
+ RECEIVER_REMOTE, RECEIVER_ABORT});
+ registerMyReceiver(new IntentFilter(BROADCAST_ABORT));
+ sCallingTest.addIntermediate("after-register");
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT), null);
+ } else if (BROADCAST_STICKY1.equals(action)) {
+ setExpectedReceivers(new String[]{RECEIVER_REG});
+ setExpectedData(new String[]{DATA_1});
+ registerMyReceiver(new IntentFilter(BROADCAST_STICKY1));
+ sCallingTest.addIntermediate("after-register");
+ } else if (BROADCAST_STICKY2.equals(action)) {
+ setExpectedReceivers(new String[]{RECEIVER_REG, RECEIVER_REG});
+ setExpectedData(new String[]{DATA_1, DATA_2});
+ IntentFilter filter = new IntentFilter(BROADCAST_STICKY1);
+ filter.addAction(BROADCAST_STICKY2);
+ registerMyReceiver(filter);
+ sCallingTest.addIntermediate("after-register");
+ }
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle icicle) {
+ super.onSaveInstanceState(icicle);
+ checkLifecycle(ON_FREEZE);
+ if (mBadParcelable) {
+ icicle.putParcelable("baddy", new MyBadParcelable());
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "PAUSE lauchpad "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ checkLifecycle(ON_PAUSE);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "STOP lauchpad "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ checkLifecycle(ON_STOP);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode,
+ Intent data) {
+ switch (requestCode) {
+ case LAUNCHED_RESULT:
+ sCallingTest.finishTiming(true);
+ finishWithResult(resultCode, data);
+ break;
+ case FORWARDED_RESULT:
+ sCallingTest.finishTiming(true);
+ if (RETURNED_RESULT.equals(data.getAction())) {
+ finishWithResult(resultCode, data);
+ } else {
+ finishWithResult(RESULT_CANCELED, (new Intent()).setAction(
+ "Bad data returned: " + data));
+ }
+ break;
+ default:
+ sCallingTest.finishTiming(true);
+ finishWithResult(RESULT_CANCELED, (new Intent()).setAction(
+ "Unexpected request code: " + requestCode));
+ break;
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "DESTROY lauchpad "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ checkLifecycle(ON_DESTROY);
+ sCallingTest.activityFinished(mResultCode, mData, mResultStack);
+ }
+
+ private void setExpectedLifecycle(String[] lifecycle) {
+ mExpectedLifecycle = lifecycle;
+ mNextLifecycle = 0;
+ }
+
+ private void checkLifecycle(String where) {
+ if (mExpectedLifecycle == null) return;
+
+ if (mNextLifecycle >= mExpectedLifecycle.length) {
+ finishBad("Activity lifecycle incorrect: received " + where
+ + " but don't expect any more calls");
+ mExpectedLifecycle = null;
+ return;
+ }
+ if (!mExpectedLifecycle[mNextLifecycle].equals(where)) {
+ finishBad("Activity lifecycle incorrect: received " + where
+ + " but expected " + mExpectedLifecycle[mNextLifecycle]
+ + " at " + mNextLifecycle);
+ mExpectedLifecycle = null;
+ return;
+ }
+
+ mNextLifecycle++;
+
+ if (mNextLifecycle >= mExpectedLifecycle.length) {
+ setTestResult(RESULT_OK, null);
+ return;
+ }
+
+ String next = mExpectedLifecycle[mNextLifecycle];
+ if (where.equals(ON_DESTROY)) {
+ finishBad("Activity lifecycle incorrect: received " + where
+ + " but expected more actions (next is " + next + ")");
+ mExpectedLifecycle = null;
+ return;
+ } else if (next.equals(DO_FINISH)) {
+ mNextLifecycle++;
+ if (mNextLifecycle >= mExpectedLifecycle.length) {
+ setTestResult(RESULT_OK, null);
+ }
+ if (!isFinishing()) {
+ finish();
+ }
+ } else if (next.equals(DO_LOCAL_SCREEN)) {
+ mNextLifecycle++;
+ Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
+ intent.setClass(this, LocalScreen.class);
+ startActivity(intent);
+ } else if (next.equals(DO_LOCAL_DIALOG)) {
+ mNextLifecycle++;
+ Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
+ intent.setClass(this, LocalDialog.class);
+ startActivity(intent);
+ }
+ }
+
+ private void setExpectedReceivers(String[] receivers) {
+ mExpectedReceivers = receivers;
+ mNextReceiver = 0;
+ }
+
+ private void setExpectedData(String[] data) {
+ mExpectedData = data;
+ mReceivedData = new boolean[data.length];
+ }
+
+ private Intent makeBroadcastIntent(String action) {
+ Intent intent = new Intent(action, null);
+ intent.putExtra("caller", mCallTarget);
+ return intent;
+ }
+
+ private void finishGood() {
+ finishWithResult(RESULT_OK, null);
+ }
+
+ private void finishBad(String error) {
+ finishWithResult(RESULT_CANCELED, (new Intent()).setAction(error));
+ }
+
+ private void finishWithResult(int resultCode, Intent data) {
+ setTestResult(resultCode, data);
+ finish();
+ }
+
+ private void setTestResult(int resultCode, Intent data) {
+ mHandler.removeCallbacks(mTimeout);
+ unregisterMyReceiver();
+ mResultCode = resultCode;
+ mData = data;
+ mResultStack = new RuntimeException("Original error was here");
+ mResultStack.fillInStackTrace();
+ }
+
+ private void registerMyReceiver(IntentFilter filter) {
+ mReceiverRegistered = true;
+ //System.out.println("Registering: " + mReceiver);
+ registerReceiver(mReceiver, filter);
+ }
+
+ private void unregisterMyReceiver() {
+ if (mReceiverRegistered) {
+ mReceiverRegistered = false;
+ //System.out.println("Unregistering: " + mReceiver);
+ unregisterReceiver(mReceiver);
+ }
+ }
+
+ private Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ }
+ };
+
+ static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
+ static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
+
+ private Binder mCallTarget = new Binder() {
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
+ data.setDataPosition(0);
+ data.enforceInterface(LaunchpadActivity.LAUNCH);
+ if (code == GOT_RECEIVE_TRANSACTION) {
+ String name = data.readString();
+ gotReceive(name, null);
+ return true;
+ } else if (code == ERROR_TRANSACTION) {
+ finishBad(data.readString());
+ return true;
+ }
+ return false;
+ }
+ };
+
+ private final void gotReceive(String name, Intent intent) {
+ synchronized (this) {
+
+ //System.out.println("Got receive: " + name);
+ //System.out.println(mNextReceiver + " in " + mExpectedReceivers);
+ //new RuntimeException("stack").printStackTrace();
+
+ sCallingTest.addIntermediate(mNextReceiver + "-" + name);
+
+ if (mExpectedData != null) {
+ int n = mExpectedData.length;
+ int i;
+ boolean prev = false;
+ for (i = 0; i < n; i++) {
+ if (mExpectedData[i].equals(intent.getStringExtra("test"))) {
+ if (mReceivedData[i]) {
+ prev = true;
+ continue;
+ }
+ mReceivedData[i] = true;
+ break;
+ }
+ }
+ if (i >= n) {
+ if (prev) {
+ finishBad("Receive got data too many times: "
+ + intent.getStringExtra("test"));
+ } else {
+ finishBad("Receive got unexpected data: "
+ + intent.getStringExtra("test"));
+ }
+ return;
+ }
+ }
+
+ if (mNextReceiver >= mExpectedReceivers.length) {
+ finishBad("Got too many onReceiveIntent() calls!");
+// System.out.println("Too many intents received: now at "
+// + mNextReceiver + ", expect list: "
+// + Arrays.toString(mExpectedReceivers));
+ } else if (!mExpectedReceivers[mNextReceiver].equals(name)) {
+ finishBad("Receive out of order: got " + name + " but expected "
+ + mExpectedReceivers[mNextReceiver] + " at "
+ + mNextReceiver);
+ } else {
+ mNextReceiver++;
+ if (mNextReceiver == mExpectedReceivers.length) {
+ mHandler.post(mUnregister);
+ }
+ }
+
+ }
+ }
+
+ private Runnable mUnregister = new Runnable() {
+ public void run() {
+ if (mReceiverRegistered) {
+ sCallingTest.addIntermediate("before-unregister");
+ unregisterMyReceiver();
+ }
+ sCallingTest.finishTiming(true);
+ finishGood();
+ }
+ };
+
+ private Runnable mTimeout = new Runnable() {
+ public void run() {
+ Log.i("foo", "**** TIMEOUT");
+ String msg = "Timeout";
+ if (mExpectedReceivers != null
+ && mNextReceiver < mExpectedReceivers.length) {
+ msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver];
+ }
+ finishBad(msg);
+ }
+ };
+
+ private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ //System.out.println("Receive in: " + this + ": " + intent);
+ gotReceive(RECEIVER_REG, intent);
+ }
+ };
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LaunchpadTabActivity.java b/core/tests/coretests/src/android/app/activity/LaunchpadTabActivity.java
new file mode 100644
index 0000000..79b860f
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LaunchpadTabActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.TabActivity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.TabHost;
+
+public class LaunchpadTabActivity extends TabActivity {
+ public LaunchpadTabActivity() {
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Intent tabIntent = new Intent(getIntent());
+ tabIntent.setComponent((ComponentName)tabIntent.getParcelableExtra("tab"));
+
+ TabHost th = getTabHost();
+ TabHost.TabSpec ts = th.newTabSpec("1");
+ ts.setIndicator("One");
+ ts.setContent(tabIntent);
+ th.addTab(ts);
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LifecycleTest.java b/core/tests/coretests/src/android/app/activity/LifecycleTest.java
new file mode 100644
index 0000000..768a9a4
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LifecycleTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.test.FlakyTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
+
+public class LifecycleTest extends ActivityTestsBase {
+ private Intent mTopIntent;
+ private Intent mTabIntent;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTopIntent = mIntent;
+ mTabIntent = new Intent(mContext, LaunchpadTabActivity.class);
+ mTabIntent.putExtra("tab", new ComponentName(mContext,
+ LaunchpadActivity.class));
+ }
+
+ @LargeTest
+ public void testBasic() throws Exception {
+ mIntent = mTopIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
+ }
+
+ //Suppressing until 1285425 is fixed.
+ @Suppress
+ public void testTabBasic() throws Exception {
+ mIntent = mTabIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
+ }
+
+ //Marking flaky until bug 1164344 is fixed.
+ // @FlakyTest(tolerance=2)
+ // @LargeTest
+ public void testScreen() throws Exception {
+ mIntent = mTopIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
+ }
+
+ //Marking flaky until bug 1164344 is fixed.
+ //@FlakyTest(tolerance=2)
+ //Suppressing until 1285425 is fixed.
+ @Suppress
+ public void testTabScreen() throws Exception {
+ mIntent = mTabIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
+ }
+
+ //flaky test, removing from large suite until 1866891 is fixed
+ //@LargeTest
+ public void testDialog() throws Exception {
+ mIntent = mTopIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
+ }
+
+ //Suppressing until 1285425 is fixed.
+ @Suppress
+ public void testTabDialog() throws Exception {
+ mIntent = mTabIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
+ }
+
+ @MediumTest
+ public void testFinishCreate() throws Exception {
+ mIntent = mTopIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_FINISH_CREATE);
+ }
+
+ //Suppressing until 1285425 is fixed.
+ @Suppress
+ public void testTabFinishCreate() throws Exception {
+ mIntent = mTabIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_FINISH_CREATE);
+ }
+
+ @MediumTest
+ public void testFinishStart() throws Exception {
+ mIntent = mTopIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_FINISH_START);
+ }
+
+ //Suppressing until 1285425 is fixed.
+ @Suppress
+ public void testTabFinishStart() throws Exception {
+ mIntent = mTabIntent;
+ runLaunchpad(LaunchpadActivity.LIFECYCLE_FINISH_START);
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/LocalActivity.java b/core/tests/coretests/src/android/app/activity/LocalActivity.java
new file mode 100644
index 0000000..01f1fb6
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import java.util.Map;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+
+public class LocalActivity extends TestedActivity
+{
+ public LocalActivity()
+ {
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java b/core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java
new file mode 100644
index 0000000..2120a1d
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+
+class LocalDeniedReceiver extends BroadcastReceiver {
+ public LocalDeniedReceiver() {
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ try {
+ IBinder caller = intent.getIBinderExtra("caller");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(LaunchpadActivity.LAUNCH);
+ data.writeString(BroadcastTest.RECEIVER_LOCAL);
+ caller.transact(BroadcastTest.GOT_RECEIVE_TRANSACTION, data, null, 0);
+ data.recycle();
+ } catch (RemoteException ex) {
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalDeniedService.java b/core/tests/coretests/src/android/app/activity/LocalDeniedService.java
new file mode 100644
index 0000000..3bdac22
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalDeniedService.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+public class LocalDeniedService extends LocalService
+{
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalDialog.java b/core/tests/coretests/src/android/app/activity/LocalDialog.java
new file mode 100644
index 0000000..c92fa43
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalDialog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import java.util.Map;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+
+public class LocalDialog extends TestedScreen
+{
+ public LocalDialog()
+ {
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalGrantedReceiver.java b/core/tests/coretests/src/android/app/activity/LocalGrantedReceiver.java
new file mode 100644
index 0000000..c9e6ab4
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalGrantedReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+
+public class LocalGrantedReceiver extends BroadcastReceiver {
+ public LocalGrantedReceiver() {
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ try {
+ IBinder caller = intent.getIBinderExtra("caller");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(LaunchpadActivity.LAUNCH);
+ data.writeString(BroadcastTest.RECEIVER_LOCAL);
+ caller.transact(BroadcastTest.GOT_RECEIVE_TRANSACTION, data, null, 0);
+ data.recycle();
+ } catch (RemoteException ex) {
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalGrantedService.java b/core/tests/coretests/src/android/app/activity/LocalGrantedService.java
new file mode 100644
index 0000000..7ab0fb4
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalGrantedService.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+public class LocalGrantedService extends LocalService
+{
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalProvider.java b/core/tests/coretests/src/android/app/activity/LocalProvider.java
new file mode 100644
index 0000000..085e622
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalProvider.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007 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 android.app.activity;
+
+import android.content.UriMatcher;
+import android.content.*;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.util.Config;
+import android.util.Log;
+
+/** Simple test provider that runs in the local process. */
+public class LocalProvider extends ContentProvider {
+ private static final String TAG = "LocalProvider";
+
+ private SQLiteOpenHelper mOpenHelper;
+
+ private static final int DATA = 1;
+ private static final int DATA_ID = 2;
+ private static final UriMatcher sURLMatcher = new UriMatcher(
+ UriMatcher.NO_MATCH);
+
+ static {
+ sURLMatcher.addURI("*", "data", DATA);
+ sURLMatcher.addURI("*", "data/#", DATA_ID);
+ }
+
+ private static class DatabaseHelper extends SQLiteOpenHelper {
+ private static final String DATABASE_NAME = "local.db";
+ private static final int DATABASE_VERSION = 1;
+
+ public DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE data (" +
+ "_id INTEGER PRIMARY KEY," +
+ "text TEXT, " +
+ "integer INTEGER);");
+
+ // insert alarms
+ db.execSQL("INSERT INTO data (text, integer) VALUES ('first data', 100);");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+ Log.w(TAG, "Upgrading test database from version " +
+ oldVersion + " to " + currentVersion +
+ ", which will destroy all old data");
+ db.execSQL("DROP TABLE IF EXISTS data");
+ onCreate(db);
+ }
+ }
+
+
+ public LocalProvider() {
+ }
+
+ @Override
+ public boolean onCreate() {
+ mOpenHelper = new DatabaseHelper(getContext());
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri url, String[] projectionIn, String selection,
+ String[] selectionArgs, String sort) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+
+ // Generate the body of the query
+ int match = sURLMatcher.match(url);
+ switch (match) {
+ case DATA:
+ qb.setTables("data");
+ break;
+ case DATA_ID:
+ qb.setTables("data");
+ qb.appendWhere("_id=");
+ qb.appendWhere(url.getPathSegments().get(1));
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URL " + url);
+ }
+
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,
+ null, null, sort);
+
+ if (ret == null) {
+ if (Config.LOGD) Log.d(TAG, "Alarms.query: failed");
+ } else {
+ ret.setNotificationUri(getContext().getContentResolver(), url);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public String getType(Uri url) {
+ int match = sURLMatcher.match(url);
+ switch (match) {
+ case DATA:
+ return "vnd.android.cursor.dir/vnd.google.unit_tests.local";
+ case DATA_ID:
+ return "vnd.android.cursor.item/vnd.google.unit_tests.local";
+ default:
+ throw new IllegalArgumentException("Unknown URL");
+ }
+ }
+
+ @Override
+ public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
+ int count;
+ long rowId = 0;
+ int match = sURLMatcher.match(url);
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ switch (match) {
+ case DATA_ID: {
+ String segment = url.getPathSegments().get(1);
+ rowId = Long.parseLong(segment);
+ count = db.update("data", values, "_id=" + rowId, null);
+ break;
+ }
+ default: {
+ throw new UnsupportedOperationException(
+ "Cannot update URL: " + url);
+ }
+ }
+ if (Config.LOGD) Log.d(TAG, "*** notifyChange() rowId: " + rowId);
+ getContext().getContentResolver().notifyChange(url, null);
+ return count;
+ }
+
+
+ @Override
+ public Uri insert(Uri url, ContentValues initialValues) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri url, String where, String[] whereArgs) {
+ throw new UnsupportedOperationException("delete not supported");
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/LocalReceiver.java b/core/tests/coretests/src/android/app/activity/LocalReceiver.java
new file mode 100644
index 0000000..bfd543f
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalReceiver.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ReceiverCallNotAllowedException;
+import android.content.ServiceConnection;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+
+public class LocalReceiver extends BroadcastReceiver {
+ public LocalReceiver() {
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ String resultString = LaunchpadActivity.RECEIVER_LOCAL;
+ if (BroadcastTest.BROADCAST_FAIL_REGISTER.equals(intent.getAction())) {
+ resultString = "Successfully registered, but expected it to fail";
+ try {
+ context.registerReceiver(this, new IntentFilter("foo.bar"));
+ context.unregisterReceiver(this);
+ } catch (ReceiverCallNotAllowedException e) {
+ //resultString = "This is the correct behavior but not yet implemented";
+ resultString = LaunchpadActivity.RECEIVER_LOCAL;
+ }
+ } else if (BroadcastTest.BROADCAST_FAIL_BIND.equals(intent.getAction())) {
+ resultString = "Successfully bound to service, but expected it to fail";
+ try {
+ ServiceConnection sc = new ServiceConnection() {
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ };
+ context.bindService(new Intent(context, LocalService.class), sc, 0);
+ context.unbindService(sc);
+ } catch (ReceiverCallNotAllowedException e) {
+ //resultString = "This is the correct behavior but not yet implemented";
+ resultString = LaunchpadActivity.RECEIVER_LOCAL;
+ }
+ } else if (LaunchpadActivity.BROADCAST_REPEAT.equals(intent.getAction())) {
+ Intent newIntent = new Intent(intent);
+ newIntent.setAction(LaunchpadActivity.BROADCAST_LOCAL);
+ context.sendOrderedBroadcast(newIntent, null);
+ }
+ try {
+ IBinder caller = intent.getIBinderExtra("caller");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(LaunchpadActivity.LAUNCH);
+ data.writeString(resultString);
+ caller.transact(LaunchpadActivity.GOT_RECEIVE_TRANSACTION, data, null, 0);
+ data.recycle();
+ } catch (RemoteException ex) {
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalScreen.java b/core/tests/coretests/src/android/app/activity/LocalScreen.java
new file mode 100644
index 0000000..f7c8c33
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalScreen.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import java.util.Map;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+
+public class LocalScreen extends TestedScreen
+{
+ public LocalScreen()
+ {
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/LocalService.java b/core/tests/coretests/src/android/app/activity/LocalService.java
new file mode 100644
index 0000000..c31ca4b
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/LocalService.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.util.Log;
+
+public class LocalService extends Service {
+ private final IBinder mBinder = new Binder() {
+
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply,
+ int flags) throws RemoteException {
+ if (code == ServiceTest.SET_REPORTER_CODE) {
+ data.enforceInterface(ServiceTest.SERVICE_LOCAL);
+ mReportObject = data.readStrongBinder();
+ return true;
+ } else {
+ return super.onTransact(code, data, reply, flags);
+ }
+ }
+
+ };
+
+ private IBinder mReportObject;
+ private int mStartCount = 1;
+
+ public LocalService() {
+ }
+
+ @Override
+ public void onStart(Intent intent, int startId) {
+ //Log.i("LocalService", "onStart: " + intent);
+ if (intent.getExtras() != null) {
+ mReportObject = intent.getExtras().getIBinder(ServiceTest.REPORT_OBJ_NAME);
+ if (mReportObject != null) {
+ try {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
+ data.writeInt(mStartCount);
+ mStartCount++;
+ mReportObject.transact(
+ ServiceTest.STARTED_CODE, data, null, 0);
+ data.recycle();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.i("LocalService", "onDestroy: mReportObject=" + mReportObject);
+ if (mReportObject != null) {
+ try {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
+ mReportObject.transact(
+ ServiceTest.DESTROYED_CODE, data, null, 0);
+ data.recycle();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.i("LocalService", "onBind: " + intent);
+ return mBinder;
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ Log.i("LocalService", "onUnbind: " + intent);
+ if (mReportObject != null) {
+ try {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
+ mReportObject.transact(
+ ServiceTest.UNBIND_CODE, data, null, 0);
+ data.recycle();
+ } catch (RemoteException e) {
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void onRebind(Intent intent) {
+ Log.i("LocalService", "onUnbind: " + intent);
+ if (mReportObject != null) {
+ try {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
+ mReportObject.transact(
+ ServiceTest.REBIND_CODE, data, null, 0);
+ data.recycle();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/MetaDataTest.java b/core/tests/coretests/src/android/app/activity/MetaDataTest.java
new file mode 100644
index 0000000..214bc91
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/MetaDataTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Bundle;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import com.android.frameworks.coretests.R;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * Tests for meta-data associated with application components.
+ */
+public class MetaDataTest extends AndroidTestCase {
+
+ private void checkMetaData(ComponentName cn, PackageItemInfo ci)
+ throws IOException, XmlPullParserException {
+ assertNotNull("Unable to find component " + cn, ci);
+
+ Bundle md = ci.metaData;
+ assertNotNull("No meta data found", md);
+
+ assertEquals("foo", md.getString("com.android.frameworks.coretests.string"));
+ assertTrue(md.getBoolean("com.android.frameworks.coretests.boolean"));
+ assertEquals(100, md.getInt("com.android.frameworks.coretests.integer"));
+ assertEquals(0xff000000, md.getInt("com.android.frameworks.coretests.color"));
+
+ assertEquals((double) 1001,
+ Math.floor(md.getFloat("com.android.frameworks.coretests.float") * 10 + .5));
+
+ assertEquals(R.xml.metadata, md.getInt("com.android.frameworks.coretests.reference"));
+
+ XmlResourceParser xml = ci.loadXmlMetaData(mContext.getPackageManager(),
+ "com.android.frameworks.coretests.reference");
+ assertNotNull(xml);
+
+ int type;
+ while ((type = xml.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ }
+ assertEquals(XmlPullParser.START_TAG, type);
+ assertEquals("thedata", xml.getName());
+
+ // method 1: direct access
+ final String rawAttr = xml.getAttributeValue(null, "rawText");
+ assertEquals("some raw text", rawAttr);
+
+ // method 2: direct access of typed value
+ final int rawColorIntAttr = xml.getAttributeIntValue(null, "rawColor", 0);
+ assertEquals(0xffffff00, rawColorIntAttr);
+ final String rawColorStrAttr = xml.getAttributeValue(null, "rawColor");
+ assertEquals("#ffffff00", rawColorStrAttr);
+
+ // method 2: direct access of resource attribute
+ final String nameSpace = "http://schemas.android.com/apk/res/android";
+ final int colorIntAttr = xml.getAttributeIntValue(nameSpace, "color", 0);
+ assertEquals(0xffff0000, colorIntAttr);
+ final String colorStrAttr = xml.getAttributeValue(nameSpace, "color");
+ assertEquals("#ffff0000", colorStrAttr);
+
+ // method 3: styled access (borrowing an attr from view system here)
+ TypedArray a = mContext.obtainStyledAttributes(xml,
+ android.R.styleable.TextView);
+ String styledAttr = a.getString(android.R.styleable.TextView_text);
+ assertEquals("text", styledAttr);
+ a.recycle();
+
+ xml.close();
+ }
+
+ @SmallTest
+ public void testActivityWithData() throws Exception {
+ ComponentName cn = new ComponentName(mContext, LocalActivity.class);
+ ActivityInfo ai = mContext.getPackageManager().getActivityInfo(
+ cn, PackageManager.GET_META_DATA);
+
+ checkMetaData(cn, ai);
+
+ ai = mContext.getPackageManager().getActivityInfo(cn, 0);
+
+ assertNull("Meta data returned when not requested", ai.metaData);
+ }
+
+ @SmallTest
+ public void testReceiverWithData() throws Exception {
+ ComponentName cn = new ComponentName(mContext, LocalReceiver.class);
+ ActivityInfo ai = mContext.getPackageManager().getReceiverInfo(
+ cn, PackageManager.GET_META_DATA);
+
+ checkMetaData(cn, ai);
+
+ ai = mContext.getPackageManager().getReceiverInfo(cn, 0);
+
+ assertNull("Meta data returned when not requested", ai.metaData);
+ }
+
+ @SmallTest
+ public void testServiceWithData() throws Exception {
+ ComponentName cn = new ComponentName(mContext, LocalService.class);
+ ServiceInfo si = mContext.getPackageManager().getServiceInfo(
+ cn, PackageManager.GET_META_DATA);
+
+ checkMetaData(cn, si);
+
+ si = mContext.getPackageManager().getServiceInfo(cn, 0);
+
+ assertNull("Meta data returned when not requested", si.metaData);
+ }
+
+ @MediumTest
+ public void testProviderWithData() throws Exception {
+ ComponentName cn = new ComponentName(mContext, LocalProvider.class);
+ ProviderInfo pi = mContext.getPackageManager().resolveContentProvider(
+ "com.android.frameworks.coretests.LocalProvider",
+ PackageManager.GET_META_DATA);
+ checkMetaData(cn, pi);
+
+ pi = mContext.getPackageManager().resolveContentProvider(
+ "com.android.frameworks.coretests.LocalProvider", 0);
+
+ assertNull("Meta data returned when not requested", pi.metaData);
+ }
+
+ @SmallTest
+ public void testPermissionWithData() throws Exception {
+ ComponentName cn = new ComponentName("foo",
+ "com.android.frameworks.coretests.permission.TEST_GRANTED");
+ PermissionInfo pi = mContext.getPackageManager().getPermissionInfo(
+ cn.getClassName(), PackageManager.GET_META_DATA);
+ checkMetaData(cn, pi);
+
+ pi = mContext.getPackageManager().getPermissionInfo(
+ cn.getClassName(), 0);
+
+ assertNull("Meta data returned when not requested", pi.metaData);
+ }
+}
+
+
diff --git a/core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java b/core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java
new file mode 100644
index 0000000..7c89346
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+
+class RemoteDeniedReceiver extends BroadcastReceiver {
+ public RemoteDeniedReceiver() {
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ try {
+ IBinder caller = intent.getIBinderExtra("caller");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(LaunchpadActivity.LAUNCH);
+ data.writeString(BroadcastTest.RECEIVER_REMOTE);
+ caller.transact(BroadcastTest.GOT_RECEIVE_TRANSACTION, data, null, 0);
+ data.recycle();
+ } catch (RemoteException ex) {
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/RemoteGrantedReceiver.java b/core/tests/coretests/src/android/app/activity/RemoteGrantedReceiver.java
new file mode 100644
index 0000000..0eca8f7
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/RemoteGrantedReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+
+public class RemoteGrantedReceiver extends BroadcastReceiver {
+ public RemoteGrantedReceiver() {
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ try {
+ IBinder caller = intent.getIBinderExtra("caller");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(LaunchpadActivity.LAUNCH);
+ data.writeString(BroadcastTest.RECEIVER_REMOTE);
+ caller.transact(BroadcastTest.GOT_RECEIVE_TRANSACTION, data, null, 0);
+ data.recycle();
+ } catch (RemoteException ex) {
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/RemoteReceiver.java b/core/tests/coretests/src/android/app/activity/RemoteReceiver.java
new file mode 100644
index 0000000..9608fc4
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/RemoteReceiver.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+
+public class RemoteReceiver extends BroadcastReceiver
+{
+ public RemoteReceiver()
+ {
+ }
+
+ public void onReceive(Context context, Intent intent)
+ {
+ if (LaunchpadActivity.BROADCAST_REPEAT.equals(intent.getAction())) {
+ Intent newIntent = new Intent(intent);
+ newIntent.setAction(LaunchpadActivity.BROADCAST_REMOTE);
+ context.sendOrderedBroadcast(newIntent, null);
+ }
+ try {
+ IBinder caller = intent.getIBinderExtra("caller");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(LaunchpadActivity.LAUNCH);
+ data.writeString(LaunchpadActivity.RECEIVER_REMOTE);
+ caller.transact(LaunchpadActivity.GOT_RECEIVE_TRANSACTION, data, null, 0);
+ data.recycle();
+ } catch (RemoteException ex) {
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
new file mode 100644
index 0000000..e969d10
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
@@ -0,0 +1,59 @@
+/* //device/apps/AndroidTests/src/com.android.unit_tests/activity/TestedScreen.java
+**
+** Copyright 2006, 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 android.app.activity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Process;
+import android.util.Log;
+
+public class RemoteSubActivityScreen extends SubActivityScreen {
+ Handler mHandler = new Handler();
+ boolean mFirst = false;
+
+ public RemoteSubActivityScreen() {
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ // We are running in a remote process, so want to have the sub-activity
+ // sending the result back in the original process.
+ Intent intent = getIntent();
+ intent.setClass(this, SubActivityScreen.class);
+
+ super.onCreate(icicle);
+
+ boolean kill = intent.getBooleanExtra("kill", false);
+ //Log.i("foo", "RemoteSubActivityScreen pid=" + Process.myPid()
+ // + " kill=" + kill);
+
+ if (kill) {
+ // After finishing initialization, kill the process! But only if
+ // this is the first time...
+ if (icicle == null) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ handleBeforeStopping();
+ Process.killProcess(Process.myPid());
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/ResultReceiver.java b/core/tests/coretests/src/android/app/activity/ResultReceiver.java
new file mode 100644
index 0000000..f7daf2c
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/ResultReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Bundle;
+
+import java.util.Map;
+
+public class ResultReceiver extends BroadcastReceiver
+{
+ public ResultReceiver()
+ {
+ }
+
+ public void onReceive(Context context, Intent intent)
+ {
+ setResultCode(3);
+ setResultData("bar");
+ Bundle map = getResultExtras(false);
+ map.remove("remove");
+ map.putString("bar", "them");
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/SearchableActivity.java b/core/tests/coretests/src/android/app/activity/SearchableActivity.java
new file mode 100644
index 0000000..e238572
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/SearchableActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 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 android.app.activity;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class SearchableActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ finish();
+ }
+
+}
diff --git a/core/tests/coretests/src/android/app/activity/ServiceTest.java b/core/tests/coretests/src/android/app/activity/ServiceTest.java
new file mode 100644
index 0000000..d3ae415
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/ServiceTest.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+
+// These test binders purport to support an interface whose canonical
+// interface name is ServiceTest.SERVICE_LOCAL
+// Temporarily suppress, this test is causing unit test suite run to fail
+// TODO: remove this suppress
+@Suppress
+public class ServiceTest extends ActivityTestsBase {
+
+ public static final String SERVICE_LOCAL =
+ "com.android.frameworks.coretests.activity.SERVICE_LOCAL";
+ public static final String SERVICE_LOCAL_GRANTED =
+ "com.android.frameworks.coretests.activity.SERVICE_LOCAL_GRANTED";
+ public static final String SERVICE_LOCAL_DENIED =
+ "com.android.frameworks.coretests.activity.SERVICE_LOCAL_DENIED";
+
+ public static final String REPORT_OBJ_NAME = "report";
+
+ public static final int STARTED_CODE = 1;
+ public static final int DESTROYED_CODE = 2;
+ public static final int SET_REPORTER_CODE = 3;
+ public static final int UNBIND_CODE = 4;
+ public static final int REBIND_CODE = 5;
+
+ public static final int STATE_START_1 = 0;
+ public static final int STATE_START_2 = 1;
+ public static final int STATE_UNBIND = 2;
+ public static final int STATE_DESTROY = 3;
+ public static final int STATE_REBIND = 4;
+ public static final int STATE_UNBIND_ONLY = 5;
+ public int mStartState;
+
+ public IBinder mStartReceiver = new Binder() {
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply,
+ int flags) throws RemoteException {
+ //Log.i("ServiceTest", "Received code " + code + " in state " + mStartState);
+ if (code == STARTED_CODE) {
+ data.enforceInterface(SERVICE_LOCAL);
+ int count = data.readInt();
+ if (mStartState == STATE_START_1) {
+ if (count == 1) {
+ finishGood();
+ } else {
+ finishBad("onStart() again on an object when it should have been the first time");
+ }
+ } else if (mStartState == STATE_START_2) {
+ if (count == 2) {
+ finishGood();
+ } else {
+ finishBad("onStart() the first time on an object when it should have been the second time");
+ }
+ } else {
+ finishBad("onStart() was called when not expected (state="+mStartState+")");
+ }
+ return true;
+ } else if (code == DESTROYED_CODE) {
+ data.enforceInterface(SERVICE_LOCAL);
+ if (mStartState == STATE_DESTROY) {
+ finishGood();
+ } else {
+ finishBad("onDestroy() was called when not expected (state="+mStartState+")");
+ }
+ return true;
+ } else if (code == UNBIND_CODE) {
+ data.enforceInterface(SERVICE_LOCAL);
+ if (mStartState == STATE_UNBIND) {
+ mStartState = STATE_DESTROY;
+ } else if (mStartState == STATE_UNBIND_ONLY) {
+ finishGood();
+ } else {
+ finishBad("onUnbind() was called when not expected (state="+mStartState+")");
+ }
+ return true;
+ } else if (code == REBIND_CODE) {
+ data.enforceInterface(SERVICE_LOCAL);
+ if (mStartState == STATE_REBIND) {
+ finishGood();
+ } else {
+ finishBad("onRebind() was called when not expected (state="+mStartState+")");
+ }
+ return true;
+ } else {
+ return super.onTransact(code, data, reply, flags);
+ }
+ }
+ };
+
+ public class EmptyConnection implements ServiceConnection {
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ }
+
+ public class TestConnection implements ServiceConnection {
+ private final boolean mExpectDisconnect;
+ private final boolean mSetReporter;
+ private boolean mMonitor;
+ private int mCount;
+
+ public TestConnection(boolean expectDisconnect, boolean setReporter) {
+ mExpectDisconnect = expectDisconnect;
+ mSetReporter = setReporter;
+ mMonitor = !setReporter;
+ }
+
+ void setMonitor(boolean v) {
+ mMonitor = v;
+ }
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (mSetReporter) {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(SERVICE_LOCAL);
+ data.writeStrongBinder(mStartReceiver);
+ try {
+ service.transact(SET_REPORTER_CODE, data, null, 0);
+ } catch (RemoteException e) {
+ finishBad("DeadObjectException when sending reporting object");
+ }
+ data.recycle();
+ }
+
+ if (mMonitor) {
+ mCount++;
+ if (mStartState == STATE_START_1) {
+ if (mCount == 1) {
+ finishGood();
+ } else {
+ finishBad("onServiceConnected() again on an object when it should have been the first time");
+ }
+ } else if (mStartState == STATE_START_2) {
+ if (mCount == 2) {
+ finishGood();
+ } else {
+ finishBad("onServiceConnected() the first time on an object when it should have been the second time");
+ }
+ } else {
+ finishBad("onServiceConnected() called unexpectedly");
+ }
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ if (mMonitor) {
+ if (mStartState == STATE_DESTROY) {
+ if (mExpectDisconnect) {
+ finishGood();
+ } else {
+ finishBad("onServiceDisconnected() when it shouldn't have been");
+ }
+ } else {
+ finishBad("onServiceDisconnected() called unexpectedly");
+ }
+ }
+ }
+ }
+
+ void startExpectResult(Intent service) {
+ startExpectResult(service, new Bundle());
+ }
+
+ void startExpectResult(Intent service, Bundle bundle) {
+ bundle.putIBinder(REPORT_OBJ_NAME, mStartReceiver);
+ boolean success = false;
+ try {
+ //Log.i("foo", "STATE_START_1");
+ mStartState = STATE_START_1;
+ getContext().startService(new Intent(service).putExtras(bundle));
+ waitForResultOrThrow(5 * 1000, "service to start first time");
+ //Log.i("foo", "STATE_START_2");
+ mStartState = STATE_START_2;
+ getContext().startService(new Intent(service).putExtras(bundle));
+ waitForResultOrThrow(5 * 1000, "service to start second time");
+ success = true;
+ } finally {
+ if (!success) {
+ try {
+ getContext().stopService(service);
+ } catch (Exception e) {
+ // eat
+ }
+ }
+ }
+ //Log.i("foo", "STATE_DESTROY");
+ mStartState = STATE_DESTROY;
+ getContext().stopService(service);
+ waitForResultOrThrow(5 * 1000, "service to be destroyed");
+ }
+
+ void startExpectNoPermission(Intent service) {
+ try {
+ getContext().startService(service);
+ fail("Expected security exception when starting " + service);
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ void bindExpectResult(Intent service) {
+ TestConnection conn = new TestConnection(true, false);
+ TestConnection conn2 = new TestConnection(false, false);
+ boolean success = false;
+ try {
+ // Expect to see the TestConnection connected.
+ mStartState = STATE_START_1;
+ getContext().bindService(service, conn, 0);
+ getContext().startService(service);
+ waitForResultOrThrow(5 * 1000, "existing connection to receive service");
+
+ // Expect to see the second TestConnection connected.
+ getContext().bindService(service, conn2, 0);
+ waitForResultOrThrow(5 * 1000, "new connection to receive service");
+
+ getContext().unbindService(conn2);
+ success = true;
+ } finally {
+ if (!success) {
+ try {
+ getContext().stopService(service);
+ getContext().unbindService(conn);
+ getContext().unbindService(conn2);
+ } catch (Exception e) {
+ // eat
+ }
+ }
+ }
+
+ // Expect to see the TestConnection disconnected.
+ mStartState = STATE_DESTROY;
+ getContext().stopService(service);
+ waitForResultOrThrow(5 * 1000, "existing connection to lose service");
+
+ getContext().unbindService(conn);
+
+ conn = new TestConnection(true, true);
+ success = false;
+ try {
+ // Expect to see the TestConnection connected.
+ conn.setMonitor(true);
+ mStartState = STATE_START_1;
+ getContext().bindService(service, conn, 0);
+ getContext().startService(service);
+ waitForResultOrThrow(5 * 1000, "existing connection to receive service");
+
+ success = true;
+ } finally {
+ if (!success) {
+ try {
+ getContext().stopService(service);
+ getContext().unbindService(conn);
+ } catch (Exception e) {
+ // eat
+ }
+ }
+ }
+
+ // Expect to see the service unbind and then destroyed.
+ conn.setMonitor(false);
+ mStartState = STATE_UNBIND;
+ getContext().stopService(service);
+ waitForResultOrThrow(5 * 1000, "existing connection to lose service");
+
+ getContext().unbindService(conn);
+
+ conn = new TestConnection(true, true);
+ success = false;
+ try {
+ // Expect to see the TestConnection connected.
+ conn.setMonitor(true);
+ mStartState = STATE_START_1;
+ getContext().bindService(service, conn, 0);
+ getContext().startService(service);
+ waitForResultOrThrow(5 * 1000, "existing connection to receive service");
+
+ success = true;
+ } finally {
+ if (!success) {
+ try {
+ getContext().stopService(service);
+ getContext().unbindService(conn);
+ } catch (Exception e) {
+ // eat
+ }
+ }
+ }
+
+ // Expect to see the service unbind but not destroyed.
+ conn.setMonitor(false);
+ mStartState = STATE_UNBIND_ONLY;
+ getContext().unbindService(conn);
+ waitForResultOrThrow(5 * 1000, "existing connection to unbind service");
+
+ // Expect to see the service rebound.
+ mStartState = STATE_REBIND;
+ getContext().bindService(service, conn, 0);
+ waitForResultOrThrow(5 * 1000, "existing connection to rebind service");
+
+ // Expect to see the service unbind and then destroyed.
+ mStartState = STATE_UNBIND;
+ getContext().stopService(service);
+ waitForResultOrThrow(5 * 1000, "existing connection to lose service");
+
+ getContext().unbindService(conn);
+ }
+
+ void bindAutoExpectResult(Intent service) {
+ TestConnection conn = new TestConnection(false, true);
+ boolean success = false;
+ try {
+ conn.setMonitor(true);
+ mStartState = STATE_START_1;
+ getContext().bindService(
+ service, conn, Context.BIND_AUTO_CREATE);
+ waitForResultOrThrow(5 * 1000, "connection to start and receive service");
+ success = true;
+ } finally {
+ if (!success) {
+ try {
+ getContext().unbindService(conn);
+ } catch (Exception e) {
+ // eat
+ }
+ }
+ }
+ mStartState = STATE_UNBIND;
+ getContext().unbindService(conn);
+ waitForResultOrThrow(5 * 1000, "disconnecting from service");
+ }
+
+ void bindExpectNoPermission(Intent service) {
+ TestConnection conn = new TestConnection(false, false);
+ try {
+ getContext().bindService(service, conn, Context.BIND_AUTO_CREATE);
+ fail("Expected security exception when binding " + service);
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ getContext().unbindService(conn);
+ }
+ }
+
+
+ @MediumTest
+ public void testLocalStartClass() throws Exception {
+ startExpectResult(new Intent(getContext(), LocalService.class));
+ }
+
+ @MediumTest
+ public void testLocalStartAction() throws Exception {
+ startExpectResult(new Intent(SERVICE_LOCAL));
+ }
+
+ @MediumTest
+ public void testLocalBindClass() throws Exception {
+ bindExpectResult(new Intent(getContext(), LocalService.class));
+ }
+
+ @MediumTest
+ public void testLocalBindAction() throws Exception {
+ bindExpectResult(new Intent(SERVICE_LOCAL));
+ }
+
+ @MediumTest
+ public void testLocalBindAutoClass() throws Exception {
+ bindAutoExpectResult(new Intent(getContext(), LocalService.class));
+ }
+
+ @MediumTest
+ public void testLocalBindAutoAction() throws Exception {
+ bindAutoExpectResult(new Intent(SERVICE_LOCAL));
+ }
+
+ @MediumTest
+ public void testLocalStartClassPermissionGranted() throws Exception {
+ startExpectResult(new Intent(getContext(), LocalGrantedService.class));
+ }
+
+ @MediumTest
+ public void testLocalStartActionPermissionGranted() throws Exception {
+ startExpectResult(new Intent(SERVICE_LOCAL_GRANTED));
+ }
+
+ @MediumTest
+ public void testLocalBindClassPermissionGranted() throws Exception {
+ bindExpectResult(new Intent(getContext(), LocalGrantedService.class));
+ }
+
+ @MediumTest
+ public void testLocalBindActionPermissionGranted() throws Exception {
+ bindExpectResult(new Intent(SERVICE_LOCAL_GRANTED));
+ }
+
+ @MediumTest
+ public void testLocalBindAutoClassPermissionGranted() throws Exception {
+ bindAutoExpectResult(new Intent(getContext(), LocalGrantedService.class));
+ }
+
+ @MediumTest
+ public void testLocalBindAutoActionPermissionGranted() throws Exception {
+ bindAutoExpectResult(new Intent(SERVICE_LOCAL_GRANTED));
+ }
+
+ @MediumTest
+ public void testLocalStartClassPermissionDenied() throws Exception {
+ startExpectNoPermission(new Intent(getContext(), LocalDeniedService.class));
+ }
+
+ @MediumTest
+ public void testLocalStartActionPermissionDenied() throws Exception {
+ startExpectNoPermission(new Intent(SERVICE_LOCAL_DENIED));
+ }
+
+ @MediumTest
+ public void testLocalBindClassPermissionDenied() throws Exception {
+ bindExpectNoPermission(new Intent(getContext(), LocalDeniedService.class));
+ }
+
+ @MediumTest
+ public void testLocalBindActionPermissionDenied() throws Exception {
+ bindExpectNoPermission(new Intent(SERVICE_LOCAL_DENIED));
+ }
+
+ @MediumTest
+ public void testLocalUnbindTwice() throws Exception {
+ EmptyConnection conn = new EmptyConnection();
+ getContext().bindService(
+ new Intent(SERVICE_LOCAL_GRANTED), conn, 0);
+ getContext().unbindService(conn);
+ try {
+ getContext().unbindService(conn);
+ fail("No exception thrown on second unbind");
+ } catch (IllegalArgumentException e) {
+ //Log.i("foo", "Unbind exception", e);
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/SetTimeZonePermissionsTest.java b/core/tests/coretests/src/android/app/activity/SetTimeZonePermissionsTest.java
new file mode 100644
index 0000000..41b9547
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/SetTimeZonePermissionsTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008 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 android.app.activity;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.util.TimeZone;
+
+public class SetTimeZonePermissionsTest extends AndroidTestCase {
+
+ private String[] mZones;
+ private String mCurrentZone;
+ private AlarmManager mAlarm;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mZones = TimeZone.getAvailableIDs();
+ mCurrentZone = TimeZone.getDefault().getID();
+ mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+ }
+
+ /**
+ * Verify that non-system processes cannot set the time zone.
+ */
+ @LargeTest
+ public void testSetTimeZonePermissions() {
+ /**
+ * Attempt to set several predefined time zones, verifying that the system
+ * system default time zone has not actually changed from its prior state
+ * after each attempt.
+ */
+ int max = (mZones.length > 10) ? mZones.length : 10;
+ assertTrue("No system-defined time zones - test invalid", max > 0);
+
+ for (int i = 0; i < max; i++) {
+ String tz = mZones[i];
+ try {
+ mAlarm.setTimeZone(tz);
+ } catch (SecurityException se) {
+ // Expected failure; no need to handle specially since we're
+ // about to assert that the test invariant holds: no change
+ // to the system time zone.
+ }
+
+ String newZone = TimeZone.getDefault().getID();
+ assertEquals("AlarmManager.setTimeZone() succeeded despite lack of permission",
+ mCurrentZone,
+ newZone);
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/SubActivityScreen.java b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
new file mode 100644
index 0000000..919c591
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class SubActivityScreen extends Activity {
+ static final int NO_RESULT_MODE = 0;
+ static final int RESULT_MODE = 1;
+ static final int PENDING_RESULT_MODE = 2;
+ static final int FINISH_SUB_MODE = 3;
+
+ static final int CHILD_OFFSET = 1000;
+
+ int mMode;
+
+ public SubActivityScreen() {
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mMode = getIntent().getIntExtra("mode", mMode);
+ //Log.i("foo", "SubActivityScreen pid=" + Process.myPid()
+ // + " mode=" + mMode);
+
+ // Move on to the next thing that will generate a result... but only
+ // if we are being launched for the first time.
+ if (icicle == null) {
+ if (mMode == PENDING_RESULT_MODE) {
+ PendingIntent apr = createPendingResult(1, null,
+ Intent.FILL_IN_ACTION);
+ Intent res = new Intent();
+ res.putExtra("tkey", "tval");
+ res.setAction("test");
+ try {
+ apr.send(this, RESULT_OK, res);
+ } catch (PendingIntent.CanceledException e) {
+ }
+ } else if (mMode < CHILD_OFFSET) {
+ Intent intent = new Intent();
+ intent.setClass(this, SubActivityScreen.class);
+ intent.putExtra("mode", CHILD_OFFSET+mMode);
+ //System.out.println("*** Starting from onStart: " + intent);
+ startActivityForResult(intent, 1);
+ return;
+ }
+ }
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle state) {
+ super.onRestoreInstanceState(state);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ //Log.i("foo", "SubActivityScreen pid=" + Process.myPid() + " onResume");
+
+ if (mMode >= CHILD_OFFSET) {
+ // Wait a little bit, to give our parent time to kill itself
+ // if that is something it is into.
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ setResult(RESULT_CANCELED, (new Intent()).setAction("Interrupted!"));
+ finish();
+ return;
+ }
+ //System.out.println("Resuming sub-activity: mode=" + mMode);
+ switch (mMode-CHILD_OFFSET) {
+ case NO_RESULT_MODE:
+ finish();
+ break;
+ case RESULT_MODE:
+ Intent res = new Intent();
+ res.putExtra("tkey", "tval");
+ res.setAction("test");
+ setResult(RESULT_OK, res);
+ finish();
+ break;
+ case FINISH_SUB_MODE:
+ break;
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode,
+ Intent data) {
+ //Log.i("foo", "SubActivityScreen pid=" + Process.myPid()
+ // + " onActivityResult: req=" + requestCode
+ // + " res=" + resultCode);
+
+ // Assume success.
+ setResult(RESULT_OK);
+
+ if (requestCode == 1) {
+ switch (mMode) {
+ case NO_RESULT_MODE:
+ case FINISH_SUB_MODE:
+ if (resultCode != RESULT_CANCELED) {
+ setResult(RESULT_CANCELED, (new Intent()).setAction(
+ "Incorrect result code returned: " + resultCode));
+ }
+ break;
+ case RESULT_MODE:
+ case PENDING_RESULT_MODE:
+ if (resultCode != RESULT_OK) {
+ setResult(RESULT_CANCELED, (new Intent()).setAction(
+ "Incorrect result code returned: " + resultCode));
+ } else if (data == null) {
+ setResult(RESULT_CANCELED, (new Intent()).setAction(
+ "null data returned"));
+ } else if (!("test".equals(data.getAction()))) {
+ setResult(RESULT_CANCELED, (new Intent()).setAction(
+ "Incorrect action returned: " + data));
+ } else if (!("tval".equals(data.getStringExtra("tkey")))) {
+ setResult(RESULT_CANCELED, (new Intent()).setAction(
+ "Incorrect extras returned: " + data.getExtras()));
+ }
+ break;
+ }
+ } else {
+ setResult(RESULT_CANCELED, (new Intent()).setAction(
+ "Incorrect request code returned: " + requestCode));
+ }
+
+ finish();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ handleBeforeStopping();
+ }
+
+ public void handleBeforeStopping() {
+ if (mMode == FINISH_SUB_MODE) {
+ finishActivity(1);
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/SubActivityTest.java b/core/tests/coretests/src/android/app/activity/SubActivityTest.java
new file mode 100644
index 0000000..35dde8a
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/SubActivityTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.test.suitebuilder.annotation.Suppress;
+import android.content.ComponentName;
+
+@Suppress
+public class SubActivityTest extends ActivityTestsBase {
+
+ public void testPendingResult() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), SubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.PENDING_RESULT_MODE);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testNoResult() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), SubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.NO_RESULT_MODE);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testResult() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), SubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.RESULT_MODE);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testFinishSub() throws Exception {
+ mIntent.putExtra("component",
+ new ComponentName(getContext(), RemoteSubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.FINISH_SUB_MODE);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testRemoteNoResult() throws Exception {
+ mIntent.putExtra("component",
+ new ComponentName(getContext(), RemoteSubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.NO_RESULT_MODE);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testRemoteResult() throws Exception {
+ mIntent.putExtra("component",
+ new ComponentName(getContext(), RemoteSubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.RESULT_MODE);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testRemoteFinishSub() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), SubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.FINISH_SUB_MODE);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testRemoteRestartNoResult() throws Exception {
+ mIntent.putExtra("component",
+ new ComponentName(getContext(), RemoteSubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.NO_RESULT_MODE);
+ mIntent.putExtra("kill", true);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testRemoteRestartResult() throws Exception {
+ mIntent.putExtra("component",
+ new ComponentName(getContext(), RemoteSubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.RESULT_MODE);
+ mIntent.putExtra("kill", true);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+
+ public void testRemoteRestartFinishSub() throws Exception {
+ mIntent.putExtra("component", new ComponentName(getContext(), SubActivityScreen.class));
+ mIntent.putExtra("mode", SubActivityScreen.FINISH_SUB_MODE);
+ mIntent.putExtra("kill", true);
+ runLaunchpad(LaunchpadActivity.LAUNCH);
+ }
+}
diff --git a/core/tests/coretests/src/android/app/activity/TestedActivity.java b/core/tests/coretests/src/android/app/activity/TestedActivity.java
new file mode 100644
index 0000000..3a1c15f
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/TestedActivity.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.os.Bundle;
+
+public class TestedActivity extends Activity
+{
+ public TestedActivity()
+ {
+ }
+
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+ }
+
+ protected void onRestoreInstanceState(Bundle state)
+ {
+ super.onRestoreInstanceState(state);
+ }
+
+ protected void onResume()
+ {
+ super.onResume();
+ Looper.myLooper().myQueue().addIdleHandler(new Idler());
+ }
+
+ protected void onSaveInstanceState(Bundle outState)
+ {
+ super.onSaveInstanceState(outState);
+ }
+
+ protected void onStop()
+ {
+ super.onStop();
+ }
+
+ private Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ setResult(RESULT_OK);
+ finish();
+ }
+ };
+
+ private class Idler implements MessageQueue.IdleHandler
+ {
+ public final boolean queueIdle()
+ {
+ //Message m = Message.obtain();
+ //mHandler.sendMessageAtTime(m, SystemClock.uptimeMillis()+1000);
+ setResult(RESULT_OK);
+ finish();
+ return false;
+ }
+ }
+}
+
diff --git a/core/tests/coretests/src/android/app/activity/TestedScreen.java b/core/tests/coretests/src/android/app/activity/TestedScreen.java
new file mode 100644
index 0000000..1682d1a
--- /dev/null
+++ b/core/tests/coretests/src/android/app/activity/TestedScreen.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2006 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 android.app.activity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.os.SystemClock;
+import android.os.Bundle;
+import android.util.Log;
+
+public class TestedScreen extends Activity
+{
+ public static final String WAIT_BEFORE_FINISH = "TestedScreen.WAIT_BEFORE_FINISH";
+ public static final String DELIVER_RESULT = "TestedScreen.DELIVER_RESULT";
+ public static final String CLEAR_TASK = "TestedScreen.CLEAR_TASK";
+
+ public TestedScreen() {
+ }
+
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "CREATE tested "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ if (LaunchpadActivity.FORWARD_RESULT.equals(getIntent().getAction())) {
+ Intent intent = new Intent(getIntent());
+ intent.setAction(DELIVER_RESULT);
+ intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ startActivity(intent);
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "Finishing tested "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ finish();
+ } else if (DELIVER_RESULT.equals(getIntent().getAction())) {
+ setResult(RESULT_OK, (new Intent()).setAction(
+ LaunchpadActivity.RETURNED_RESULT));
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "Finishing tested "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ finish();
+ } else if (CLEAR_TASK.equals(getIntent().getAction())) {
+ if (!getIntent().getBooleanExtra(ClearTop.WAIT_CLEAR_TASK, false)) {
+ launchClearTask();
+ }
+ }
+ }
+
+ protected void onRestoreInstanceState(Bundle state) {
+ super.onRestoreInstanceState(state);
+ }
+
+ protected void onResume() {
+ super.onResume();
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "RESUME tested "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ if (CLEAR_TASK.equals(getIntent().getAction())) {
+ if (getIntent().getBooleanExtra(ClearTop.WAIT_CLEAR_TASK, false)) {
+ Looper.myLooper().myQueue().addIdleHandler(new Idler());
+ }
+ } else {
+ Looper.myLooper().myQueue().addIdleHandler(new Idler());
+ }
+ }
+
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ protected void onStop() {
+ super.onStop();
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "STOP tested "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ }
+
+ private void launchClearTask() {
+ Intent intent = new Intent(getIntent()).
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP).
+ setClass(this, ClearTop.class);
+ startActivity(intent);
+ }
+
+ private Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ if (CLEAR_TASK.equals(getIntent().getAction())) {
+ launchClearTask();
+ } else {
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "Finishing tested "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ setResult(RESULT_OK);
+ finish();
+ }
+ }
+ };
+
+ private class Idler implements MessageQueue.IdleHandler {
+ public final boolean queueIdle() {
+ if (WAIT_BEFORE_FINISH.equals(getIntent().getAction())) {
+ Message m = Message.obtain();
+ mHandler.sendMessageAtTime(m, SystemClock.uptimeMillis()+1000);
+ } else if (CLEAR_TASK.equals(getIntent().getAction())) {
+ Message m = Message.obtain();
+ mHandler.sendMessageAtTime(m, SystemClock.uptimeMillis()+1000);
+ } else {
+ if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "Finishing tested "
+ + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
+ setResult(RESULT_OK);
+ finish();
+ }
+ return false;
+ }
+ }
+}
+