diff options
author | Brett Chabot <brettchabot@android.com> | 2010-04-01 18:21:38 -0700 |
---|---|---|
committer | Brett Chabot <brettchabot@android.com> | 2010-04-01 18:31:11 -0700 |
commit | 0dc59e78e18493aecd37427531d093e800846c3e (patch) | |
tree | f78a49ef7fdeb85648a93444850f06b4243a9555 /core/tests | |
parent | 2d8234b73d11fdc2178232cabad3ffaa23723405 (diff) | |
download | frameworks_base-0dc59e78e18493aecd37427531d093e800846c3e.zip frameworks_base-0dc59e78e18493aecd37427531d093e800846c3e.tar.gz frameworks_base-0dc59e78e18493aecd37427531d093e800846c3e.tar.bz2 |
More framework tests cleanup.
Move all tests for android.* classes from tests/AndroidTests and
tests/CoreTests into framework/base/<core|graphics>/tests.
Consolidate all tests for java.* classes to tests/CoreTests.
Eventually hopefully these will be moved to dalvik/ somewhere.
Remove tests/AndroidTests entirely.
Change-Id: I86584d086ab7bd045bb38a10b699907805298a95
Diffstat (limited to 'core/tests')
40 files changed, 4592 insertions, 25 deletions
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk index b0e2843..c067b80 100644 --- a/core/tests/coretests/Android.mk +++ b/core/tests/coretests/Android.mk @@ -7,6 +7,8 @@ LOCAL_MODULE_TAGS := tests # Include all test java files. LOCAL_SRC_FILES := \ $(call all-java-files-under, src) \ + $(call all-java-files-under, DisabledTestApp/src) \ + $(call all-java-files-under, EnabledTestApp/src) \ src/android/os/IAidlTest.aidl LOCAL_STATIC_JAVA_LIBRARIES += android-common @@ -18,3 +20,4 @@ LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 9972a8c..30855d1 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -16,7 +16,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" - package="com.android.frameworks.coretests"> + package="com.android.frameworks.coretests" + android:sharedUserId="com.android.uid.test"> <permission android:name="com.android.frameworks.coretests.permission.TEST_GRANTED" android:protectionLevel="normal" diff --git a/core/tests/coretests/DisabledTestApp/Android.mk b/core/tests/coretests/DisabledTestApp/Android.mk new file mode 100644 index 0000000..a5daedf --- /dev/null +++ b/core/tests/coretests/DisabledTestApp/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := DisabledTestApp +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/DisabledTestApp/AndroidManifest.xml b/core/tests/coretests/DisabledTestApp/AndroidManifest.xml new file mode 100644 index 0000000..5bd840f --- /dev/null +++ b/core/tests/coretests/DisabledTestApp/AndroidManifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.disabled_app" + android:sharedUserId="com.android.uid.test"> + + <application enabled="false"> + + <!-- Used to test package component enabling and disabling --> + <activity android:name=".DisabledActivity" android:enabled="false" > + </activity> + <activity android:name=".EnabledActivity" > + </activity> + </application> +</manifest> diff --git a/core/tests/coretests/DisabledTestApp/src/com/android/frameworks/coretests/disabled_app/EnabledActivity.java b/core/tests/coretests/DisabledTestApp/src/com/android/frameworks/coretests/disabled_app/EnabledActivity.java new file mode 100644 index 0000000..e676231 --- /dev/null +++ b/core/tests/coretests/DisabledTestApp/src/com/android/frameworks/coretests/disabled_app/EnabledActivity.java @@ -0,0 +1,27 @@ +/* + * 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 com.android.frameworks.coretests.disabled_app; + +import android.app.Activity; + +/** + * Empty Activity for testing + */ + +public class EnabledActivity extends Activity { + +} diff --git a/core/tests/coretests/EnabledTestApp/Android.mk b/core/tests/coretests/EnabledTestApp/Android.mk new file mode 100644 index 0000000..4b986d3 --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := EnabledTestApp +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/EnabledTestApp/AndroidManifest.xml b/core/tests/coretests/EnabledTestApp/AndroidManifest.xml new file mode 100644 index 0000000..72d933a --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/AndroidManifest.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.enabled_app" + android:sharedUserId="com.android.uid.test"> + + <application> + + <!-- Used to test package component enabling and disabling --> + <activity android:name=".DisabledActivity" android:enabled="false" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="com.android.frameworks.coretests.enabled_app.TEST_CATEGORY" /> + </intent-filter> + </activity> + <service android:name=".DisabledService" android:enabled="false" > + </service> + <receiver android:name=".DisabledReceiver" android:enabled="false" > + <intent-filter> + <action android:name="android.intent.action.ENABLED_APP_DISABLED_RECEIVER" /> + </intent-filter> + </receiver> + <provider android:name=".DisabledProvider" android:enabled="false" + android:authorities="com.android.frameworks.coretests.enabled_app.DisabledProvider" + android:process=":disabled.provider.process" /> + <activity android:name=".EnabledActivity" > + </activity> + <service android:name=".EnabledService" android:enabled="true" > + </service> + <receiver android:name=".EnabledReceiver" > + <intent-filter> + <action android:name="android.intent.action.ENABLED_APP_ENABLED_RECEIVER" /> + </intent-filter> + </receiver> + <provider android:name=".EnabledProvider" + android:authorities="com.android.frameworks.coretests.enabled_app.EnabledProvider" + android:process=":enabled.provider.process" /> + </application> +</manifest> diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledActivity.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledActivity.java new file mode 100644 index 0000000..325adfe --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledActivity.java @@ -0,0 +1,27 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.app.Activity; + +/** + * Empty Activity for testing + */ + +public class DisabledActivity extends Activity { + +} diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledProvider.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledProvider.java new file mode 100644 index 0000000..26781c4 --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledProvider.java @@ -0,0 +1,54 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +/** + * Empty ContentProvider for testing + */ + +public class DisabledProvider extends ContentProvider { + + public boolean onCreate() { + return false; + } + + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + public String getType(Uri uri) { + return null; + } + + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledReceiver.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledReceiver.java new file mode 100644 index 0000000..b06d2ce --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledReceiver.java @@ -0,0 +1,32 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +/** + * Empty IntentReceiver for testing + */ + +public class DisabledReceiver extends BroadcastReceiver { + + public void onReceive(Context context, Intent intent) { + + } +} diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledService.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledService.java new file mode 100644 index 0000000..ac66ae5 --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/DisabledService.java @@ -0,0 +1,32 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.app.Service; +import android.os.IBinder; +import android.content.Intent; + +/** + * Empty Service for testing + */ + +public class DisabledService extends Service { + + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledActivity.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledActivity.java new file mode 100644 index 0000000..1b0ac6d --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledActivity.java @@ -0,0 +1,27 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.app.Activity; + +/** + * Empty Activity for testing + */ + +public class EnabledActivity extends Activity { + +} diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledProvider.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledProvider.java new file mode 100644 index 0000000..8da70b4 --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledProvider.java @@ -0,0 +1,54 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +/** + * Empty ContentProvider for testing + */ + +public class EnabledProvider extends ContentProvider { + + public boolean onCreate() { + return false; + } + + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + public String getType(Uri uri) { + return null; + } + + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledReceiver.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledReceiver.java new file mode 100644 index 0000000..6cee98d --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledReceiver.java @@ -0,0 +1,32 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +/** + * Empty IntentReceiver for testing + */ + +public class EnabledReceiver extends BroadcastReceiver { + + public void onReceive(Context context, Intent intent) { + + } +} diff --git a/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledService.java b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledService.java new file mode 100644 index 0000000..7d05db0 --- /dev/null +++ b/core/tests/coretests/EnabledTestApp/src/com/android/frameworks/coretests/enabled_app/EnabledService.java @@ -0,0 +1,32 @@ +/* + * 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 com.android.frameworks.coretests.enabled_app; + +import android.app.Service; +import android.os.IBinder; +import android.content.Intent; + +/** + * Empty Service for testing + */ + +public class EnabledService extends Service { + + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/core/tests/coretests/apks/install_decl_perm/Android.mk b/core/tests/coretests/apks/install_decl_perm/Android.mk new file mode 100644 index 0000000..c38e981 --- /dev/null +++ b/core/tests/coretests/apks/install_decl_perm/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_decl_perm + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/apks/install_decl_perm/AndroidManifest.xml b/core/tests/coretests/apks/install_decl_perm/AndroidManifest.xml new file mode 100644 index 0000000..9a1f0ff --- /dev/null +++ b/core/tests/coretests/apks/install_decl_perm/AndroidManifest.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.install_decl_perm"> + + <permission android:name="com.android.frameworks.coretests.NORMAL" + android:permissionGroup="android.permission-group.COST_MONEY" + android:protectionLevel="normal" + android:label="test normal perm" /> + + <permission android:name="com.android.frameworks.coretests.DANGEROUS" + android:permissionGroup="android.permission-group.COST_MONEY" + android:protectionLevel="dangerous" + android:label="test dangerous perm" /> + + <permission android:name="com.android.frameworks.coretests.SIGNATURE" + android:permissionGroup="android.permission-group.COST_MONEY" + android:protectionLevel="signature" + android:label="test signature perm" /> + + <application android:hasCode="false"> + </application> +</manifest> diff --git a/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml b/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml new file mode 100644 index 0000000..3b8b3b1 --- /dev/null +++ b/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- Just need this dummy file to have something to build. --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="dummy">dummy</string> +</resources> diff --git a/core/tests/coretests/apks/install_use_perm_good/Android.mk b/core/tests/coretests/apks/install_use_perm_good/Android.mk new file mode 100644 index 0000000..1a07fc8 --- /dev/null +++ b/core/tests/coretests/apks/install_use_perm_good/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_use_perm_good + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/apks/install_use_perm_good/AndroidManifest.xml b/core/tests/coretests/apks/install_use_perm_good/AndroidManifest.xml new file mode 100644 index 0000000..dadce7d --- /dev/null +++ b/core/tests/coretests/apks/install_use_perm_good/AndroidManifest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.install_use_perm_good"> + + <uses-permission android:name="com.android.frameworks.coretests.NORMAL" /> + <uses-permission android:name="com.android.frameworks.coretests.DANGEROUS" /> + <uses-permission android:name="com.android.frameworks.coretests.SIGNATURE" /> + + <application android:hasCode="false"> + </application> +</manifest> diff --git a/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml b/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml new file mode 100644 index 0000000..3b8b3b1 --- /dev/null +++ b/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- Just need this dummy file to have something to build. --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="dummy">dummy</string> +</resources> diff --git a/core/tests/coretests/res/raw/alt_ip_only.crt b/core/tests/coretests/res/raw/alt_ip_only.crt new file mode 100644 index 0000000..3ac9f5a --- /dev/null +++ b/core/tests/coretests/res/raw/alt_ip_only.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZqgAwIBAgIJALrC37YAXFIeMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV +BAYTAkpQMCAXDTEwMDExMjIxMzk0NloYDzIwNjQxMDE1MjEzOTQ2WjANMQswCQYD +VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALr8s/4Abpby +IYks5YCJE2nbWH7kj6XbwnRzsVP9RVC33bPoQ1M+2ZY24HqkigjQS/HEXR0s0bYh +dewNUnTj1uGyGs6cYzsbu7x114vmVYqjxUo3hKjwfYiPeF6f3IE1vpLI7I2G32gq +Zwm9c1/vXNHIdWQxCpFcuPA8P3YGfoApFX4pQPFplBUNAQqnjdmA68cbxxMC+1F3 +mX42D7iIEVwyVpah5HjyxjIZQlf3X7QBj0bCmkL+ibIHTALrkNNwNM6i4xzYLz/5 +14GkN9ncHY87eSOk6r53ptER6mQMhCe9qPRjSHnpWTTyj6IXTaYe+dDQw657B80w +cSHL7Ed25zUCAwEAAaMTMBEwDwYDVR0RBAgwBocEwKgKATANBgkqhkiG9w0BAQUF +AAOCAQEAgrwrtOWZT3fbi1AafpGaAiOBWSJqYqRhtQy0AfiZBxv1U0XaYqmZmpnq +DVAqr0NkljowD28NBrxIFO5gBNum2ZOPDl2/5vjFn+IirUCJ9u9wS7zYkTCW2lQR +xE7Ic3mfWv7wUbKDfjlWqP1IDHUxwkrBTAl+HnwOPiaKKk1ttwcrgS8AHlqASe03 +mlwnvJ+Stk54IneRaegL0L93sNAy63RZqnPCTxGz7eHcFwX8Jdr4sbxTxQqV6pIc +WPjHQcWfpkFzAF5wyOq0kveVfx0g5xPhOVDd+U+q7WastbXICpCoHp9FxISmZVik +sAyifp8agkYdzaSh55fFmKXlFnRsQw== +-----END CERTIFICATE----- diff --git a/core/tests/coretests/res/raw/subject_alt_only.crt b/core/tests/coretests/res/raw/subject_alt_only.crt new file mode 100644 index 0000000..d5808fb --- /dev/null +++ b/core/tests/coretests/res/raw/subject_alt_only.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvTCCAaWgAwIBAgIJALbA0TZk2YmNMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV +BAYTAkpQMCAXDTEwMDExMjIwNTg1NFoYDzIwNjQxMDE1MjA1ODU0WjANMQswCQYD +VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMEg6acVC9V4 +xNGoLNVLPbqBc8IvMvcsc88dF6MW3d9VagX3aeWU8c79tI/KOV/1AOakH7WYxw/w +yD8aOX7+9BK1Hu0qKKKbSM+ycqaMthXd6xytrNDsIx5WiGUz8zTko0Gk3orIR7p7 +rPcNzB/zwtESkscqPv85aEn7S/yClNkzLfEzm3CtaYOc0tfhBMyzi/ipXzGMxUmx +PvOLr3v/Oz5pZEQw7Kxlm4+tAtn7bJlHziQ1UW4WPIy+T3hySBEpODFiqZi7Ok3X +Zjxdii62fgo5B2Ee7q5Amo0mUIwcQTDjJ2CLAqzYnSh3tpiPJGjEIjmRyCoMQ1bx +7D+y7nSPIq8CAwEAAaMeMBwwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29tMA0G +CSqGSIb3DQEBBQUAA4IBAQBsGEh+nHc0l9FJTzWqvG3qs7i6XoJZdtThCDx4HjKJ +8GMrJtreNN4JvIxn7KC+alVbnILjzCRO+c3rsnpxKBi5cp2imjuw5Kf/x2Seimb9 +UvZbaJvBVOzy4Q1IGef9bLy3wZzy2/WfBFyvPTAkgkRaX7LN2jnYOYVhNoNFrwqe +EWxkA6fzrpyseUEFeGFFjGxRSRCDcQ25Eq6d9rkC1x21zNtt4QwZBO0wHrTy155M +JPRynf9244Pn0Sr/wsnmdsTRFIFYynrc51hQ7DkwbUxpcaewkZzilru/SwZ3+pPT +9JSqm5hJ1pg5WDlPkW7c/1VA0/141N52Q8MIU+2ZpuOj +-----END CERTIFICATE----- diff --git a/core/tests/coretests/res/raw/subject_only.crt b/core/tests/coretests/res/raw/subject_only.crt new file mode 100644 index 0000000..11b34e7 --- /dev/null +++ b/core/tests/coretests/res/raw/subject_only.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIJANCQbJPPw31SMA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV +BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjA1ODE4 +WhgPMjA2NDEwMTUyMDU4MThaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu +ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDsdUJk +4KxADA3vlDHxNbyC27Ozw4yiSVzPTHUct471YmdDRW3orO2P5a5hRnUGV70gjH9X +MU4oeOdWYAgXB9pxfLyr6621k1+uNrmaZtzp0ECH9twcwxNJJFDZsN7o9vt7V6Ej +NN9weeqDr/aeQXo07a12vyVfR6jWO8jHB0e4aemwZNoYjNvM69fivQTse2ZoRVfj +eSHhjRTX6I8ry4a31Hwt+fT1QiWWNN6o7+WOtpJAhX3eg4smhSD1svi2kOT8tdUe +NS4hWlmXmumU9G4tI8PBurcLNTm7PB2lUlbn/IV18WavqKE/Uy/1WgAx+a1EJNdp +i07AG1PsqaONKkf1AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAJrNsuL7fZZNC8gL +BdePJ7DYW2e7mXANU3bCBe2BZqmXKQxKwibZnEsqA+yMLqcSd8uxISlyHY2tw9wT +4wB9KPIttfNLbwn/rk+MbOTHpvyF60d9WhJJVUkPBl8D4VuPSl+VnlA54kU9dtZN ++ZYdxYbNtSsI/Flz9SCoOV79W9GhN+uYJhv6RwyIMIHeMpZpyX1xSUVx5dZlmerQ +WAUvghDH3fFRt2ZdnA4OXoKkTAaM3Pv7PUMsnah8bux6MQi0AuLMWFWOI1H34koH +rs2oQLwOLnuifH52ey9+tJguabo+brlYYigAuWWFEzJfBzikDkIwnE/L7wlrypIk +taXDWI4= +-----END CERTIFICATE----- diff --git a/core/tests/coretests/res/raw/subject_with_alt_names.crt b/core/tests/coretests/res/raw/subject_with_alt_names.crt new file mode 100644 index 0000000..6963c7e --- /dev/null +++ b/core/tests/coretests/res/raw/subject_with_alt_names.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBDCCAeygAwIBAgIJALv14qjcuhw9MA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV +BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjA1OTM4 +WhgPMjA2NDEwMTUyMDU5MzhaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu +ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCiTVgU +kBO9KNYZZLmiPR0eBrk8u61CLnm35BGKW8EFpDaINLbbIFIQvqOMekURON/N+xFY +D8roo7aFZVuHWAUqFcOJ4e6NmviK5qocLihtzAexsw4f4AzZxM3A8kcLlWLyAt7e +EVLxhcMHogY7GaF6q+33Z8p+zp6x3tj07mwyPrriCLse2PeRsRunZl/fp/VvRlr6 +YbC7CbRrhnIv5nqohs8BsbBiiFpxQftsMQmiXhY2LUzqY2RXUIOw24fHjoQkHTL2 +4z5nUM3b6ueQe+CBnobUS6fzK/36Nct4dRpev9i/ORdRLuIDKJ+QR16G1V/BJYBR +dAK+3iXvg6z8vP1XAgMBAAGjMTAvMC0GA1UdEQQmMCSCEHd3dzIuZXhhbXBsZS5j +b22CEHd3dzMuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADggEBAJQNf38uXm3h +0vsF+Yd6/HqM48Su7tWnTDAfTXnQZZkzjzITq3JXzquMXICktAVN2cLnT9zPfRAE +8V8A3BNO5zXiR5W3o/mJP5HQ3/WxpzBGM2N+YmDCJyBoQrIVaAZaXAZUaBBvn5A+ +kEVfGWquwIFuvA67xegbJOCRLD4eUzRdNsn5+NFiakWO1tkFqEzqyQ0PNPviRjgu +z9NxdPvd1JQOhydkucsPKJzlEBbGyL5QL/Jkot3Qy+FOeuNzgQUfAGtQgzRrsZDK +hrTVypLSoRXuTB2aWilu4p6aNh84xTdyqo2avtNr2MiQMZIcdamBq8LdBIAShFXI +h5G2eVGXH/Y= +-----END CERTIFICATE----- diff --git a/core/tests/coretests/res/raw/subject_with_wild_alt_name.crt b/core/tests/coretests/res/raw/subject_with_wild_alt_name.crt new file mode 100644 index 0000000..19b1174 --- /dev/null +++ b/core/tests/coretests/res/raw/subject_with_wild_alt_name.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8DCCAdigAwIBAgIJAL/oWJ64VAdXMA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV +BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjEwMDAx +WhgPMjA2NDEwMTUyMTAwMDFaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu +ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbx1QB +92iea7VybLYICA4MX4LWipYrRsgXUXQrcIQ3YLTQ9rH0VwScrHL4O4JDxgXCQnR+ +4VOzD42q1KXHJAqzqGUYCNPyvZEzkGCnQ4FBIUEmxZd5SNEefJVH3Z6GizYJomTh +p78yDcoqymD9umxRC2cWFu8GscfFGMVyhsqLlOofu7UWOs22mkXPo43jDx+VOAoV +n48YP3P57a2Eo0gcd4zVL00y62VegqBO/1LW38aTS7teiCBFc1TkNYa5I40yN9lP +rB9ICHYQWyzf/7OxU9iauEK2w6DmSsQoLs9JzEhgeNZddkcc77ciSUCo2Hx0VpOJ +BFyf2rbryJeAk+FDAgMBAAGjHTAbMBkGA1UdEQQSMBCCDiouZXhhbXBsZTIuY29t +MA0GCSqGSIb3DQEBBQUAA4IBAQA2a14pRL+4laJ8sscQlucaDB/oSdb0cwhk4IkE +kKl/ZKr6rKwPZ81sJRgzvI4imLbUAKt4AJHdpI9cIQUq1gw9bzil7LKwmFtFSPmC +MYb1iadaYrvp7RE4yXrWCcSbU0hup9JQLHTrHLlqLtRuU48NHMvWYThBcS9Q/hQp +nJ/JxYy3am99MHALWLAfuRxQXhE4C5utDmBwI2KD6A8SA30s+CnuegmkYScuSqBu +Y3R0HZvKzNIU3pwAm69HCJoG+/9MZEIDJb0WJc5UygxDT45XE9zQMQe4dBOTaNXT ++ntgaB62kE10HzrzpqXAgoAWxWK4RzFcUpBWw9qYq9xOCewJ +-----END CERTIFICATE----- diff --git a/core/tests/coretests/res/raw/wild_alt_name_only.crt b/core/tests/coretests/res/raw/wild_alt_name_only.crt new file mode 100644 index 0000000..fafdebf --- /dev/null +++ b/core/tests/coretests/res/raw/wild_alt_name_only.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuzCCAaOgAwIBAgIJAP82tgcvmAGxMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV +BAYTAkpQMCAXDTEwMDExMjIxMDAyN1oYDzIwNjQxMDE1MjEwMDI3WjANMQswCQYD +VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALs528EQbcB1 +x4BwxthQBZrgDJzoO7KPV3dhGYoeP8EnRjapZm+T/sj9P/O4HvfxjnB+fsjYSdmE +WWUtnFrP7wtG9DUC748Ea2PMV8WFhOG58dqBNIko5XzkHB7SxkNZD5S/0KQYMGLr +rchDsDlmsEf2Qb6qiqpNEU70aSkExZJcH+B9nWdeBpsVFu7wtezwSWEc2NUa2bhW +gcXQ/aafwHZ4o2PyGwy0sgS/UifqO9tEllC2tPleSNJOmYsVudv5Bz4Q0GG38BSz +Pc0IcOoln0ZWpXbGr03V2vlXWCwzaFAl3I1T3O7YVqDiaSWoP+d0tHZzmw8aJLXd +B+KaUUGxRPsCAwEAAaMcMBowGAYDVR0RBBEwD4INKi5leGFtcGxlLmNvbTANBgkq +hkiG9w0BAQUFAAOCAQEAJbVan4QgJ0cvpJnK9UWIVJNC+UbP87RC5go2fQiTnmGv +prOrIuMqz1+vGcpIheLTLctJRHPoadXq0+UbQEIaU3pQbY6C4nNdfl+hcvmJeqrt +kOCcvmIamO68iNvTSeszuHuu4O38PefrW2Xd0nn7bjFZrzBzHFhTudmnqNliP3ue +KKQpqkUt5lCytnH8V/u/UCWdvVx5LnUa2XFGVLi3ongBIojW5fvF+yxn9ADqxdrI +va++ow5r1VxQXFJc0ZPzsDo+6TlktoDHaRQJGMqQomqHWT4i7F5UZgf6BHGfEUPU +qep+GsF3QRHSBtpObWkVDZNFvky3a1iZ2q25+hFIqQ== +-----END CERTIFICATE----- diff --git a/core/tests/coretests/src/android/content/BrickDeniedTest.java b/core/tests/coretests/src/android/content/BrickDeniedTest.java new file mode 100644 index 0000000..c7d0b7a --- /dev/null +++ b/core/tests/coretests/src/android/content/BrickDeniedTest.java @@ -0,0 +1,33 @@ +/* + * 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.content; + +import android.content.Intent; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.MediumTest; + +/** Test to make sure brick intents <b>don't</b> work without permission. */ +public class BrickDeniedTest extends AndroidTestCase { + @MediumTest + public void testBrick() { + // Try both the old and new brick intent names. Neither should work, + // since this test application doesn't have the required permission. + // If it does work, well, the test certainly won't pass. + getContext().sendBroadcast(new Intent("SHES_A_BRICK_HOUSE")); + getContext().sendBroadcast(new Intent("android.intent.action.BRICK")); + } +} diff --git a/core/tests/coretests/src/android/content/SyncQueueTest.java b/core/tests/coretests/src/android/content/SyncQueueTest.java new file mode 100644 index 0000000..1da59d1 --- /dev/null +++ b/core/tests/coretests/src/android/content/SyncQueueTest.java @@ -0,0 +1,164 @@ +/* + * 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.content; + +import android.test.AndroidTestCase; +import android.test.RenamingDelegatingContext; +import android.test.mock.MockContext; +import android.test.mock.MockContentResolver; +import android.accounts.Account; +import android.os.Bundle; +import android.os.SystemClock; + +public class SyncQueueTest extends AndroidTestCase { + private static final Account ACCOUNT1 = new Account("test.account1", "test.type1"); + private static final Account ACCOUNT2 = new Account("test.account2", "test.type2"); + private static final String AUTHORITY1 = "test.authority1"; + private static final String AUTHORITY2 = "test.authority2"; + private static final String AUTHORITY3 = "test.authority3"; + + private SyncStorageEngine mSettings; + private SyncQueue mSyncQueue; + + @Override + protected void setUp() throws Exception { + super.setUp(); + MockContentResolver mockResolver = new MockContentResolver(); + mSettings = SyncStorageEngine.newTestInstance(new TestContext(mockResolver, getContext())); + mSyncQueue = new SyncQueue(mSettings); + } + + public void testSyncQueueOrder() throws Exception { + final SyncOperation op1 = new SyncOperation( + ACCOUNT1, SyncStorageEngine.SOURCE_USER, AUTHORITY1, newTestBundle("1"), 0); + final SyncOperation op2 = new SyncOperation( + ACCOUNT2, SyncStorageEngine.SOURCE_USER, AUTHORITY2, newTestBundle("2"), 100); + final SyncOperation op3 = new SyncOperation( + ACCOUNT1, SyncStorageEngine.SOURCE_USER, AUTHORITY1, newTestBundle("3"), 150); + final SyncOperation op4 = new SyncOperation( + ACCOUNT2, SyncStorageEngine.SOURCE_USER, AUTHORITY2, newTestBundle("4"), 60); + final SyncOperation op5 = new SyncOperation( + ACCOUNT1, SyncStorageEngine.SOURCE_USER, AUTHORITY1, newTestBundle("5"), 80); + final SyncOperation op6 = new SyncOperation( + ACCOUNT2, SyncStorageEngine.SOURCE_USER, AUTHORITY2, newTestBundle("6"), 0); + op6.expedited = true; + + mSyncQueue.add(op1); + mSyncQueue.add(op2); + mSyncQueue.add(op3); + mSyncQueue.add(op4); + mSyncQueue.add(op5); + mSyncQueue.add(op6); + + long now = SystemClock.elapsedRealtime() + 200; + + assertEquals(op6, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op6); + + assertEquals(op1, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op1); + + assertEquals(op4, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op4); + + assertEquals(op5, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op5); + + assertEquals(op2, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op2); + + assertEquals(op3, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op3); + } + + public void testOrderWithBackoff() throws Exception { + final SyncOperation op1 = new SyncOperation( + ACCOUNT1, SyncStorageEngine.SOURCE_USER, AUTHORITY1, newTestBundle("1"), 0); + final SyncOperation op2 = new SyncOperation( + ACCOUNT2, SyncStorageEngine.SOURCE_USER, AUTHORITY2, newTestBundle("2"), 100); + final SyncOperation op3 = new SyncOperation( + ACCOUNT1, SyncStorageEngine.SOURCE_USER, AUTHORITY1, newTestBundle("3"), 150); + final SyncOperation op4 = new SyncOperation( + ACCOUNT2, SyncStorageEngine.SOURCE_USER, AUTHORITY3, newTestBundle("4"), 60); + final SyncOperation op5 = new SyncOperation( + ACCOUNT1, SyncStorageEngine.SOURCE_USER, AUTHORITY1, newTestBundle("5"), 80); + final SyncOperation op6 = new SyncOperation( + ACCOUNT2, SyncStorageEngine.SOURCE_USER, AUTHORITY2, newTestBundle("6"), 0); + op6.expedited = true; + + mSyncQueue.add(op1); + mSyncQueue.add(op2); + mSyncQueue.add(op3); + mSyncQueue.add(op4); + mSyncQueue.add(op5); + mSyncQueue.add(op6); + + long now = SystemClock.elapsedRealtime() + 200; + + assertEquals(op6, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op6); + + assertEquals(op1, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op1); + + mSettings.setBackoff(ACCOUNT2, AUTHORITY3, now + 200, 5); + assertEquals(op5, mSyncQueue.nextReadyToRun(now).first); + + mSettings.setBackoff(ACCOUNT2, AUTHORITY3, SyncStorageEngine.NOT_IN_BACKOFF_MODE, 0); + assertEquals(op4, mSyncQueue.nextReadyToRun(now).first); + + mSettings.setDelayUntilTime(ACCOUNT2, AUTHORITY3, now + 200); + assertEquals(op5, mSyncQueue.nextReadyToRun(now).first); + + mSettings.setDelayUntilTime(ACCOUNT2, AUTHORITY3, 0); + assertEquals(op4, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op4); + + assertEquals(op5, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op5); + + assertEquals(op2, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op2); + + assertEquals(op3, mSyncQueue.nextReadyToRun(now).first); + mSyncQueue.remove(op3); + } + + Bundle newTestBundle(String val) { + Bundle bundle = new Bundle(); + bundle.putString("test", val); + return bundle; + } + + static class TestContext extends ContextWrapper { + ContentResolver mResolver; + + public TestContext(ContentResolver resolver, Context realContext) { + super(new RenamingDelegatingContext(new MockContext(), realContext, "test.")); + mResolver = resolver; + } + + @Override + public void enforceCallingOrSelfPermission(String permission, String message) { + } + + @Override + public ContentResolver getContentResolver() { + return mResolver; + } + } +} diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java new file mode 100755 index 0000000..dbb10b1 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java @@ -0,0 +1,745 @@ +/* + * 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.content.pm; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageDataObserver; +import android.content.pm.IPackageStatsObserver; +import android.content.pm.PackageStats; +import android.content.pm.IPackageManager; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.test.suitebuilder.annotation.Suppress; +import android.util.Log; +import android.os.Handler; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.StatFs; + +public class AppCacheTest extends AndroidTestCase { + private static final boolean localLOGV = false; + public static final String TAG="AppCacheTest"; + public final long MAX_WAIT_TIME=60*1000; + public final long WAIT_TIME_INCR=10*1000; + private static final int THRESHOLD=5; + private static final int ACTUAL_THRESHOLD=10; + + @Override + protected void setUp() throws Exception { + super.setUp(); + if(localLOGV) Log.i(TAG, "Cleaning up cache directory first"); + cleanUpCacheDirectory(); + } + + void cleanUpDirectory(File pDir, String dirName) { + File testDir = new File(pDir, dirName); + if(!testDir.exists()) { + return; + } + String fList[] = testDir.list(); + for(int i = 0; i < fList.length; i++) { + File file = new File(testDir, fList[i]); + if(file.isDirectory()) { + cleanUpDirectory(testDir, fList[i]); + } else { + file.delete(); + } + } + testDir.delete(); + } + + void cleanUpCacheDirectory() { + File testDir = mContext.getCacheDir(); + if(!testDir.exists()) { + return; + } + + String fList[] = testDir.list(); + if(fList == null) { + testDir.delete(); + return; + } + for(int i = 0; i < fList.length; i++) { + File file = new File(testDir, fList[i]); + if(file.isDirectory()) { + cleanUpDirectory(testDir, fList[i]); + } else { + file.delete(); + } + } + } + + @SmallTest + public void testDeleteAllCacheFiles() { + String testName="testDeleteAllCacheFiles"; + cleanUpCacheDirectory(); + } + + void failStr(String errMsg) { + Log.w(TAG, "errMsg="+errMsg); + fail(errMsg); + } + void failStr(Exception e) { + Log.w(TAG, "e.getMessage="+e.getMessage()); + Log.w(TAG, "e="+e); + } + long getFreeStorageBlks(StatFs st) { + st.restat("/data"); + return st.getFreeBlocks(); + } + + long getFreeStorageSize(StatFs st) { + st.restat("/data"); + return (st.getFreeBlocks()*st.getBlockSize()); + } + @LargeTest + public void testFreeApplicationCacheAllFiles() throws Exception { + boolean TRACKING = true; + StatFs st = new StatFs("/data"); + long blks1 = getFreeStorageBlks(st); + long availableMem = getFreeStorageSize(st); + File cacheDir = mContext.getCacheDir(); + assertNotNull(cacheDir); + createTestFiles1(cacheDir, "testtmpdir", 5); + long blks2 = getFreeStorageBlks(st); + if(localLOGV || TRACKING) Log.i(TAG, "blk1="+blks1+", blks2="+blks2); + //this should free up the test files that were created earlier + invokePMFreeApplicationCache(availableMem); + long blks3 = getFreeStorageBlks(st); + if(localLOGV || TRACKING) Log.i(TAG, "blks3="+blks3); + verifyTestFiles1(cacheDir, "testtmpdir", 5); + } + + public void testFreeApplicationCacheSomeFiles() throws Exception { + StatFs st = new StatFs("/data"); + long blks1 = getFreeStorageBlks(st); + File cacheDir = mContext.getCacheDir(); + assertNotNull(cacheDir); + createTestFiles1(cacheDir, "testtmpdir", 5); + long blks2 = getFreeStorageBlks(st); + Log.i(TAG, "blk1="+blks1+", blks2="+blks2); + long diff = (blks1-blks2-2); + assertTrue(invokePMFreeApplicationCache(diff*st.getBlockSize())); + long blks3 = getFreeStorageBlks(st); + //blks3 should be greater than blks2 and less than blks1 + if(!((blks3 <= blks1) && (blks3 >= blks2))) { + failStr("Expected "+(blks1-blks2)+" number of blocks to be freed but freed only " + +(blks1-blks3)); + } + } + + /** + * This method opens an output file writes to it, opens the same file as an input + * stream, reads the contents and verifies the data that was written earlier can be read + */ + public void openOutFileInAppFilesDir(File pFile, String pFileOut) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(pFile); + } catch (FileNotFoundException e1) { + failStr("Error when opening file "+e1); + return; + } + try { + fos.write(pFileOut.getBytes()); + fos.close(); + } catch (FileNotFoundException e) { + failStr(e.getMessage()); + } catch (IOException e) { + failStr(e.getMessage()); + } + int count = pFileOut.getBytes().length; + byte[] buffer = new byte[count]; + try { + FileInputStream fis = new FileInputStream(pFile); + fis.read(buffer, 0, count); + fis.close(); + } catch (FileNotFoundException e) { + failStr("Failed when verifing output opening file "+e.getMessage()); + } catch (IOException e) { + failStr("Failed when verifying output, reading from written file "+e); + } + String str = new String(buffer); + assertEquals(str, pFileOut); + } + + /* + * This test case verifies that output written to a file + * using Context.openFileOutput has executed successfully. + * The operation is verified by invoking Context.openFileInput + */ + @MediumTest + public void testAppFilesCreateFile() { + String fileName = "testFile1.txt"; + String fileOut = "abcdefghijklmnopqrstuvwxyz"; + Context con = super.getContext(); + try { + FileOutputStream fos = con.openFileOutput(fileName, Context.MODE_PRIVATE); + fos.close(); + } catch (FileNotFoundException e) { + failStr(e); + } catch (IOException e) { + failStr(e); + } + } + + @SmallTest + public void testAppCacheCreateFile() { + String fileName = "testFile1.txt"; + String fileOut = "abcdefghijklmnopqrstuvwxyz"; + Context con = super.getContext(); + File file = new File(con.getCacheDir(), fileName); + openOutFileInAppFilesDir(file, fileOut); + cleanUpCacheDirectory(); + } + + @MediumTest + public void testAppCreateCacheFiles() { + File cacheDir = mContext.getCacheDir(); + String testDirName = "testtmp"; + File testTmpDir = new File(cacheDir, testDirName); + testTmpDir.mkdir(); + int numDirs = 3; + File fileArr[] = new File[numDirs]; + for(int i = 0; i < numDirs; i++) { + fileArr[i] = new File(testTmpDir, "dir"+(i+1)); + fileArr[i].mkdir(); + } + byte buffer[] = getBuffer(); + Log.i(TAG, "Size of bufer="+buffer.length); + for(int i = 0; i < numDirs; i++) { + for(int j = 1; j <= (i); j++) { + File file1 = new File(fileArr[i], "testFile"+j+".txt"); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file1); + for(int k = 1; k < 10; k++) { + fos.write(buffer); + } + Log.i(TAG, "wrote 10K bytes to "+file1); + fos.close(); + } catch (FileNotFoundException e) { + Log.i(TAG, "Excetion ="+e); + fail("Error when creating outputstream "+e); + } catch(IOException e) { + Log.i(TAG, "Excetion ="+e); + fail("Error when writing output "+e); + } + } + } + } + + byte[] getBuffer() { + String sbuffer = "a"; + for(int i = 0; i < 10; i++) { + sbuffer += sbuffer; + } + return sbuffer.getBytes(); + } + + long getFileNumBlocks(long fileSize, int blkSize) { + long ret = fileSize/blkSize; + if(ret*blkSize < fileSize) { + ret++; + } + return ret; + } + + //@LargeTest + public void testAppCacheClear() { + String dataDir="/data/data"; + StatFs st = new StatFs(dataDir); + int blkSize = st.getBlockSize(); + int totBlks = st.getBlockCount(); + long availableBlks = st.getFreeBlocks(); + long thresholdBlks = (totBlks*THRESHOLD)/100; + String testDirName = "testdir"; + //create directory in cache + File testDir = new File(mContext.getCacheDir(), testDirName); + testDir.mkdirs(); + byte[] buffer = getBuffer(); + int i = 1; + if(localLOGV) Log.i(TAG, "availableBlks="+availableBlks+", thresholdBlks="+thresholdBlks); + long createdFileBlks = 0; + int imax = 300; + while((availableBlks > thresholdBlks) &&(i < imax)) { + File testFile = new File(testDir, "testFile"+i+".txt"); + if(localLOGV) Log.i(TAG, "Creating "+i+"th test file "+testFile); + int jmax = i; + i++; + FileOutputStream fos; + try { + fos = new FileOutputStream(testFile); + } catch (FileNotFoundException e) { + Log.i(TAG, "Failed creating test file:"+testFile); + continue; + } + boolean err = false; + for(int j = 1; j <= jmax;j++) { + try { + fos.write(buffer); + } catch (IOException e) { + Log.i(TAG, "Failed to write to file:"+testFile); + err = true; + } + } + try { + fos.close(); + } catch (IOException e) { + Log.i(TAG, "Failed closing file:"+testFile); + } + if(err) { + continue; + } + createdFileBlks += getFileNumBlocks(testFile.length(), blkSize); + st.restat(dataDir); + availableBlks = st.getFreeBlocks(); + } + st.restat(dataDir); + long availableBytes = st.getFreeBlocks()*blkSize; + long shouldFree = (ACTUAL_THRESHOLD-THRESHOLD)*totBlks; + //would have run out of memory + //wait for some time and confirm cache is deleted + try { + Log.i(TAG, "Sleeping for 2 minutes..."); + Thread.sleep(2*60*1000); + } catch (InterruptedException e) { + fail("Exception when sleeping "+e); + } + boolean removedFlag = false; + long existingFileBlks = 0; + for(int k = 1; k <i; k++) { + File testFile = new File(testDir, "testFile"+k+".txt"); + if(!testFile.exists()) { + removedFlag = true; + if(localLOGV) Log.i(TAG, testFile+" removed"); + } else { + existingFileBlks += getFileNumBlocks(testFile.length(), blkSize); + } + } + if(localLOGV) Log.i(TAG, "createdFileBlks="+createdFileBlks+ + ", existingFileBlks="+existingFileBlks); + long fileSize = createdFileBlks-existingFileBlks; + //verify fileSize number of bytes have been cleared from cache + if(localLOGV) Log.i(TAG, "deletedFileBlks="+fileSize+" shouldFreeBlks="+shouldFree); + if((fileSize > (shouldFree-blkSize) && (fileSize < (shouldFree+blkSize)))) { + Log.i(TAG, "passed"); + } + assertTrue(removedFlag); + } + + //createTestFiles(new File(super.getContext().getCacheDir(), "testtmp", "dir", 3) + void createTestFiles1(File cacheDir, String testFilePrefix, int numTestFiles) { + byte buffer[] = getBuffer(); + for(int i = 0; i < numTestFiles; i++) { + File file1 = new File(cacheDir, testFilePrefix+i+".txt"); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file1); + for(int k = 1; k < 10; k++) { + fos.write(buffer); + } + fos.close(); + } catch (FileNotFoundException e) { + Log.i(TAG, "Exception ="+e); + fail("Error when creating outputstream "+e); + } catch(IOException e) { + Log.i(TAG, "Exception ="+e); + fail("Error when writing output "+e); + } + try { + //introduce sleep for 1 s to avoid common time stamps for files being created + Thread.sleep(1000); + } catch (InterruptedException e) { + fail("Exception when sleeping "+e); + } + } + } + + void verifyTestFiles1(File cacheDir, String testFilePrefix, int numTestFiles) { + for(int i = 0; i < numTestFiles; i++) { + File file1 = new File(cacheDir, testFilePrefix+i+".txt"); + if(file1.exists()) { + fail("file:"+file1+" should not exist"); + } + } + } + + void createTestFiles2(File cacheDir, String rootTestDirName, String subDirPrefix, int numDirs, String testFilePrefix) { + Context con = super.getContext(); + File testTmpDir = new File(cacheDir, rootTestDirName); + testTmpDir.mkdir(); + File fileArr[] = new File[numDirs]; + for(int i = 0; i < numDirs; i++) { + fileArr[i] = new File(testTmpDir, subDirPrefix+(i+1)); + fileArr[i].mkdir(); + } + byte buffer[] = getBuffer(); + for(int i = 0; i < numDirs; i++) { + for(int j = 1; j <= (i); j++) { + File file1 = new File(fileArr[i], testFilePrefix+j+".txt"); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file1); + for(int k = 1; k < 10; k++) { + fos.write(buffer); + } + fos.close(); + } catch (FileNotFoundException e) { + Log.i(TAG, "Exception ="+e); + fail("Error when creating outputstream "+e); + } catch(IOException e) { + Log.i(TAG, "Exception ="+e); + fail("Error when writing output "+e); + } + try { + //introduce sleep for 10 ms to avoid common time stamps for files being created + Thread.sleep(10); + } catch (InterruptedException e) { + fail("Exception when sleeping "+e); + } + } + } + } + + class PackageDataObserver extends IPackageDataObserver.Stub { + public boolean retValue = false; + private boolean doneFlag = false; + public void onRemoveCompleted(String packageName, boolean succeeded) + throws RemoteException { + synchronized(this) { + retValue = succeeded; + doneFlag = true; + notifyAll(); + } + } + public boolean isDone() { + return doneFlag; + } + } + + IPackageManager getPm() { + return IPackageManager.Stub.asInterface(ServiceManager.getService("package")); + } + + boolean invokePMDeleteAppCacheFiles() throws Exception { + try { + String packageName = mContext.getPackageName(); + PackageDataObserver observer = new PackageDataObserver(); + //wait on observer + synchronized(observer) { + getPm().deleteApplicationCacheFiles(packageName, observer); + long waitTime = 0; + while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if(!observer.isDone()) { + throw new Exception("timed out waiting for PackageDataObserver.onRemoveCompleted"); + } + } + return observer.retValue; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e); + return false; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :"+e); + return false; + } + } + + boolean invokePMFreeApplicationCache(long idealStorageSize) throws Exception { + try { + String packageName = mContext.getPackageName(); + PackageDataObserver observer = new PackageDataObserver(); + //wait on observer + synchronized(observer) { + getPm().freeStorageAndNotify(idealStorageSize, observer); + long waitTime = 0; + while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if(!observer.isDone()) { + throw new Exception("timed out waiting for PackageDataObserver.onRemoveCompleted"); + } + } + return observer.retValue; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e); + return false; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :"+e); + return false; + } + } + + boolean invokePMFreeStorage(long idealStorageSize, FreeStorageReceiver r, + PendingIntent pi) throws Exception { + try { + // Spin lock waiting for call back + synchronized(r) { + getPm().freeStorage(idealStorageSize, pi.getIntentSender()); + long waitTime = 0; + while(!r.isDone() && (waitTime < MAX_WAIT_TIME)) { + r.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if(!r.isDone()) { + throw new Exception("timed out waiting for call back from PendingIntent"); + } + } + return r.getResultCode() == 1; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e); + return false; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :"+e); + return false; + } + } + + @LargeTest + public void testDeleteAppCacheFiles() throws Exception { + String testName="testDeleteAppCacheFiles"; + File cacheDir = mContext.getCacheDir(); + createTestFiles1(cacheDir, "testtmpdir", 5); + assertTrue(invokePMDeleteAppCacheFiles()); + //confirm files dont exist + verifyTestFiles1(cacheDir, "testtmpdir", 5); + } + + class PackageStatsObserver extends IPackageStatsObserver.Stub { + public boolean retValue = false; + public PackageStats stats; + private boolean doneFlag = false; + + public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) + throws RemoteException { + synchronized(this) { + retValue = succeeded; + stats = pStats; + doneFlag = true; + notifyAll(); + } + } + public boolean isDone() { + return doneFlag; + } + } + + public PackageStats invokePMGetPackageSizeInfo() throws Exception { + try { + String packageName = mContext.getPackageName(); + PackageStatsObserver observer = new PackageStatsObserver(); + //wait on observer + synchronized(observer) { + getPm().getPackageSizeInfo(packageName, observer); + long waitTime = 0; + while((!observer.isDone()) || (waitTime > MAX_WAIT_TIME) ) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if(!observer.isDone()) { + throw new Exception("Timed out waiting for PackageStatsObserver.onGetStatsCompleted"); + } + } + if(localLOGV) Log.i(TAG, "OBSERVER RET VALUES code="+observer.stats.codeSize+ + ", data="+observer.stats.dataSize+", cache="+observer.stats.cacheSize); + return observer.stats; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e); + return null; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :"+e); + return null; + } + } + + @SmallTest + public void testGetPackageSizeInfo() throws Exception { + String testName="testGetPackageSizeInfo"; + PackageStats stats = invokePMGetPackageSizeInfo(); + assertTrue(stats!=null); + //confirm result + if(localLOGV) Log.i(TAG, "code="+stats.codeSize+", data="+stats.dataSize+ + ", cache="+stats.cacheSize); + } + + @SmallTest + public void testGetSystemSharedLibraryNames() throws Exception { + try { + String[] sharedLibs = getPm().getSystemSharedLibraryNames(); + if (localLOGV) { + for (String str : sharedLibs) { + Log.i(TAG, str); + } + } + } catch (RemoteException e) { + fail("Failed invoking getSystemSharedLibraryNames with exception:" + e); + } + } + + class FreeStorageReceiver extends BroadcastReceiver { + public static final String ACTION_FREE = "com.android.unit_tests.testcallback"; + private boolean doneFlag = false; + + public boolean isDone() { + return doneFlag; + } + + @Override + public void onReceive(Context context, Intent intent) { + if(intent.getAction().equalsIgnoreCase(ACTION_FREE)) { + if (localLOGV) Log.i(TAG, "Got notification: clear cache succeeded "+getResultCode()); + synchronized (this) { + doneFlag = true; + notifyAll(); + } + } + } + } + + @SmallTest + public void testFreeStorage() throws Exception { + boolean TRACKING = true; + StatFs st = new StatFs("/data"); + long blks1 = getFreeStorageBlks(st); + if(localLOGV || TRACKING) Log.i(TAG, "Available free blocks="+blks1); + long availableMem = getFreeStorageSize(st); + File cacheDir = mContext.getCacheDir(); + assertNotNull(cacheDir); + createTestFiles1(cacheDir, "testtmpdir", 5); + long blks2 = getFreeStorageBlks(st); + if(localLOGV || TRACKING) Log.i(TAG, "Available blocks after writing test files in application cache="+blks2); + // Create receiver and register it + FreeStorageReceiver receiver = new FreeStorageReceiver(); + mContext.registerReceiver(receiver, new IntentFilter(FreeStorageReceiver.ACTION_FREE)); + PendingIntent pi = PendingIntent.getBroadcast(mContext, + 0, new Intent(FreeStorageReceiver.ACTION_FREE), 0); + // Invoke PackageManager api + invokePMFreeStorage(availableMem, receiver, pi); + long blks3 = getFreeStorageBlks(st); + if(localLOGV || TRACKING) Log.i(TAG, "Available blocks after freeing cache"+blks3); + assertEquals(receiver.getResultCode(), 1); + mContext.unregisterReceiver(receiver); + // Verify result + verifyTestFiles1(cacheDir, "testtmpdir", 5); + } + + /* utility method used to create observer and check async call back from PackageManager. + * ClearApplicationUserData + */ + boolean invokePMClearApplicationUserData() throws Exception { + try { + String packageName = mContext.getPackageName(); + PackageDataObserver observer = new PackageDataObserver(); + //wait on observer + synchronized(observer) { + getPm().clearApplicationUserData(packageName, observer); + long waitTime = 0; + while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if(!observer.isDone()) { + throw new Exception("timed out waiting for PackageDataObserver.onRemoveCompleted"); + } + } + return observer.retValue; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e); + return false; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :"+e); + return false; + } + } + + void verifyUserDataCleared(File pDir) { + if(localLOGV) Log.i(TAG, "Verifying "+pDir); + if(pDir == null) { + return; + } + String fileList[] = pDir.list(); + if(fileList == null) { + return; + } + int imax = fileList.length; + //look recursively in user data dir + for(int i = 0; i < imax; i++) { + if(localLOGV) Log.i(TAG, "Found entry "+fileList[i]+ "in "+pDir); + if("lib".equalsIgnoreCase(fileList[i])) { + if(localLOGV) Log.i(TAG, "Ignoring lib directory"); + continue; + } + fail(pDir+" should be empty or contain only lib subdirectory. Found "+fileList[i]); + } + } + + File getDataDir() { + try { + ApplicationInfo appInfo = getPm().getApplicationInfo(mContext.getPackageName(), 0); + return new File(appInfo.dataDir); + } catch (RemoteException e) { + throw new RuntimeException("Pacakge manager dead", e); + } + } + + @LargeTest + public void testClearApplicationUserDataWithTestData() throws Exception { + File cacheDir = mContext.getCacheDir(); + createTestFiles1(cacheDir, "testtmpdir", 5); + if(localLOGV) { + Log.i(TAG, "Created test data Waiting for 60seconds before continuing"); + Thread.sleep(60*1000); + } + assertTrue(invokePMClearApplicationUserData()); + //confirm files dont exist + verifyUserDataCleared(getDataDir()); + } + + @SmallTest + public void testClearApplicationUserDataWithNoTestData() throws Exception { + assertTrue(invokePMClearApplicationUserData()); + //confirm files dont exist + verifyUserDataCleared(getDataDir()); + } + + @LargeTest + public void testClearApplicationUserDataNoObserver() throws Exception { + getPm().clearApplicationUserData(mContext.getPackageName(), null); + //sleep for 1 minute + Thread.sleep(60*1000); + //confirm files dont exist + verifyUserDataCleared(getDataDir()); + } + +} diff --git a/core/tests/coretests/src/android/content/pm/ComponentTest.java b/core/tests/coretests/src/android/content/pm/ComponentTest.java new file mode 100644 index 0000000..ebfbd68 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/ComponentTest.java @@ -0,0 +1,738 @@ +/* + * 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.content.pm; + +import com.android.frameworks.coretests.enabled_app.DisabledActivity; +import com.android.frameworks.coretests.enabled_app.DisabledProvider; +import com.android.frameworks.coretests.enabled_app.DisabledReceiver; +import com.android.frameworks.coretests.enabled_app.DisabledService; +import com.android.frameworks.coretests.enabled_app.EnabledActivity; +import com.android.frameworks.coretests.enabled_app.EnabledProvider; +import com.android.frameworks.coretests.enabled_app.EnabledReceiver; +import com.android.frameworks.coretests.enabled_app.EnabledService; + +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ComponentInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; +import static android.content.pm.PackageManager.GET_DISABLED_COMPONENTS; +import android.content.pm.ProviderInfo; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.test.AndroidTestCase; + +import java.util.List; + +/** + * Tests for disabling and enabling application components. + * + * Note: These tests are on the slow side. This is probably because most of the tests trigger the + * package settings file to get written out by the PackageManagerService. Better, more unit-y test + * would fix this. + */ + +public class ComponentTest extends AndroidTestCase { + + private PackageManager mPackageManager; + private Intent mDisabledActivityIntent; + private Intent mEnabledActivityIntent; + private Intent mDisabledServiceIntent; + private Intent mEnabledServiceIntent; + private Intent mDisabledReceiverIntent; + private Intent mEnabledReceiverIntent; + private Intent mDisabledAppEnabledActivityIntent; + + private static final String ENABLED_PACKAGENAME = + "com.android.frameworks.coretests.enabled_app"; + private static final String DISABLED_PACKAGENAME = + "com.android.frameworks.coretests.disabled_app"; + private static final String DISABLED_ACTIVITY_CLASSNAME = + DisabledActivity.class.getName(); + private static final ComponentName DISABLED_ACTIVITY_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, DISABLED_ACTIVITY_CLASSNAME); + private static final String ENABLED_ACTIVITY_CLASSNAME = + EnabledActivity.class.getName(); + private static final ComponentName ENABLED_ACTIVITY_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, ENABLED_ACTIVITY_CLASSNAME); + private static final String DISABLED_SERVICE_CLASSNAME = + DisabledService.class.getName(); + private static final ComponentName DISABLED_SERVICE_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, DISABLED_SERVICE_CLASSNAME); + private static final String DISABLED_PROVIDER_CLASSNAME = + DisabledProvider.class.getName(); + private static final ComponentName DISABLED_PROVIDER_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, DISABLED_PROVIDER_CLASSNAME); + private static final String DISABLED_PROVIDER_NAME = DisabledProvider.class.getName(); + private static final String ENABLED_SERVICE_CLASSNAME = + EnabledService.class.getName(); + private static final ComponentName ENABLED_SERVICE_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, ENABLED_SERVICE_CLASSNAME); + private static final String DISABLED_RECEIVER_CLASSNAME = + DisabledReceiver.class.getName(); + private static final ComponentName DISABLED_RECEIVER_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, DISABLED_RECEIVER_CLASSNAME); + private static final String ENABLED_RECEIVER_CLASSNAME = + EnabledReceiver.class.getName(); + private static final ComponentName ENABLED_RECEIVER_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, ENABLED_RECEIVER_CLASSNAME); + private static final String ENABLED_PROVIDER_CLASSNAME = + EnabledProvider.class.getName(); + private static final ComponentName ENABLED_PROVIDER_COMPONENTNAME = + new ComponentName(ENABLED_PACKAGENAME, ENABLED_PROVIDER_CLASSNAME); + private static final String ENABLED_PROVIDER_NAME = EnabledProvider.class.getName(); + private static final String DISABLED_APP_ENABLED_ACTIVITY_CLASSNAME = + com.android.frameworks.coretests.disabled_app.EnabledActivity.class.getName(); + private static final ComponentName DISABLED_APP_ENABLED_ACTIVITY_COMPONENTNAME = + new ComponentName(DISABLED_PACKAGENAME, DISABLED_APP_ENABLED_ACTIVITY_CLASSNAME); + private static final String TEST_CATEGORY = + "com.android.frameworks.coretests.enabled_app.TEST_CATEGORY"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mPackageManager = mContext.getPackageManager(); + mDisabledActivityIntent = new Intent(); + mDisabledActivityIntent.setComponent(DISABLED_ACTIVITY_COMPONENTNAME); + mEnabledActivityIntent = new Intent(); + mEnabledActivityIntent.setComponent(ENABLED_ACTIVITY_COMPONENTNAME); + mDisabledServiceIntent = new Intent(); + mDisabledServiceIntent.setComponent(DISABLED_SERVICE_COMPONENTNAME); + mEnabledServiceIntent = new Intent(); + mEnabledServiceIntent.setComponent(ENABLED_SERVICE_COMPONENTNAME); + mDisabledReceiverIntent = new Intent("android.intent.action.ENABLED_APP_DISABLED_RECEIVER"); + mDisabledReceiverIntent.setComponent(DISABLED_RECEIVER_COMPONENTNAME); + mEnabledReceiverIntent = new Intent("android.intent.action.ENABLED_APP_ENABLED_RECEIVER"); + mEnabledReceiverIntent.setComponent(ENABLED_RECEIVER_COMPONENTNAME); + mDisabledAppEnabledActivityIntent = new Intent(); + mDisabledAppEnabledActivityIntent.setComponent(DISABLED_APP_ENABLED_ACTIVITY_COMPONENTNAME); + } + + @SmallTest + public void testContextNotNull() throws Exception { + assertNotNull(mContext); + } + + @MediumTest + public void testResolveDisabledActivity() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveActivity(mDisabledActivityIntent, 0); + assertNull(info); + + final ResolveInfo info2 = mPackageManager.resolveActivity( + mDisabledActivityIntent, GET_DISABLED_COMPONENTS); + assertNotNull(info2); + assertNotNull(info2.activityInfo); + assertFalse(info2.activityInfo.enabled); + } + + @MediumTest + public void testResolveEnabledActivity() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveActivity(mEnabledActivityIntent, 0); + assertNotNull(info); + assertNotNull(info); + assertNotNull(info.activityInfo); + assertTrue(info.activityInfo.enabled); + } + + @MediumTest + public void testQueryDisabledActivity() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final List<ResolveInfo> infoList = + mPackageManager.queryIntentActivities(mDisabledActivityIntent, 0); + assertEquals(0, infoList.size()); + + final List<ResolveInfo> infoList2 = + mPackageManager.queryIntentActivities(mDisabledActivityIntent, + GET_DISABLED_COMPONENTS); + assertEquals(1, infoList2.size()); + final ResolveInfo info = infoList2.get(0); + assertNotNull(info); + assertNotNull(info.activityInfo); + assertFalse(info.activityInfo.enabled); + } + + @MediumTest + public void testQueryEnabledActivity() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final List<ResolveInfo> infoList = + mPackageManager.queryIntentActivities(mEnabledActivityIntent, 0); + assertEquals(1, infoList.size()); + final ResolveInfo info = infoList.get(0); + assertNotNull(info); + assertNotNull(info.activityInfo); + assertTrue(info.activityInfo.enabled); + } + + @MediumTest + public void testGetDisabledActivityInfo() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + try { + mPackageManager.getActivityInfo(DISABLED_ACTIVITY_COMPONENTNAME, 0); + fail("Attempt to get info on disabled component should fail."); + } catch (PackageManager.NameNotFoundException e) { + // expected + } + + final ActivityInfo activityInfo = + mPackageManager.getActivityInfo(DISABLED_ACTIVITY_COMPONENTNAME, + GET_DISABLED_COMPONENTS); + assertNotNull(activityInfo); + assertFalse(activityInfo.enabled); + } + + @MediumTest + public void testGetEnabledActivityInfo() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + ActivityInfo activityInfo = + mPackageManager.getActivityInfo(ENABLED_ACTIVITY_COMPONENTNAME, 0); + assertNotNull(activityInfo); + assertTrue(activityInfo.enabled); + } + + @MediumTest + public void testEnableActivity() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveActivity(mDisabledActivityIntent, 0); + assertNull(info); + mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + final ResolveInfo info2 = + mPackageManager.resolveActivity(mDisabledActivityIntent, + 0); + assertNotNull(info2); + assertNotNull(info2.activityInfo); + assertFalse(info2.activityInfo.enabled); + + final List<ResolveInfo> infoList = + mPackageManager.queryIntentActivities(mDisabledActivityIntent, 0); + assertEquals(1, infoList.size()); + } + + @LargeTest + public void testDisableActivity() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveActivity(mEnabledActivityIntent, 0); + assertNotNull(info); + assertNotNull(info.activityInfo); + mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + final ResolveInfo info2 = + mPackageManager.resolveActivity(mEnabledActivityIntent, + 0); + assertNull(info2); + + final ResolveInfo info3 = mPackageManager.resolveActivity(mEnabledActivityIntent, + GET_DISABLED_COMPONENTS); + assertNotNull(info3); + assertNotNull(info3.activityInfo); + assertTrue(info3.activityInfo.enabled); + + final List<ResolveInfo> infoList = + mPackageManager.queryIntentActivities(mEnabledActivityIntent, 0); + assertEquals(0, infoList.size()); + } + + @MediumTest + public void testResolveDisabledService() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveService(mDisabledServiceIntent, 0); + assertNull(info); + + final ResolveInfo info2 = mPackageManager.resolveService( + mDisabledServiceIntent, GET_DISABLED_COMPONENTS); + assertNotNull(info2); + assertNotNull(info2.serviceInfo); + assertFalse(info2.serviceInfo.enabled); + } + + @MediumTest + public void testResolveEnabledService() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveService(mEnabledServiceIntent, 0); + assertNotNull(info); + assertNotNull(info); + assertNotNull(info.serviceInfo); + assertTrue(info.serviceInfo.enabled); + } + + @MediumTest + public void testQueryDisabledService() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final List<ResolveInfo> infoList = + mPackageManager.queryIntentServices(mDisabledServiceIntent, 0); + assertEquals(0, infoList.size()); + + final List<ResolveInfo> infoList2 = + mPackageManager.queryIntentServices(mDisabledServiceIntent, + GET_DISABLED_COMPONENTS); + assertEquals(1, infoList2.size()); + final ResolveInfo info = infoList2.get(0); + assertNotNull(info); + assertNotNull(info.serviceInfo); + assertFalse(info.serviceInfo.enabled); + } + + @MediumTest + public void testQueryEnabledService() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final List<ResolveInfo> infoList = + mPackageManager.queryIntentServices(mEnabledServiceIntent, 0); + assertEquals(1, infoList.size()); + final ResolveInfo info = infoList.get(0); + assertNotNull(info); + assertNotNull(info.serviceInfo); + assertTrue(info.serviceInfo.enabled); + } + + @MediumTest + public void testGetDisabledServiceInfo() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + try { + mPackageManager.getServiceInfo(DISABLED_SERVICE_COMPONENTNAME, 0); + fail("Attempt to get info on disabled component should fail."); + } catch (PackageManager.NameNotFoundException e) { + // expected + } + + final ServiceInfo serviceInfo = + mPackageManager.getServiceInfo(DISABLED_SERVICE_COMPONENTNAME, + GET_DISABLED_COMPONENTS); + assertNotNull(serviceInfo); + assertFalse(serviceInfo.enabled); + } + + @MediumTest + public void testGetEnabledServiceInfo() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + ServiceInfo serviceInfo = + mPackageManager.getServiceInfo(ENABLED_SERVICE_COMPONENTNAME, 0); + assertNotNull(serviceInfo); + assertTrue(serviceInfo.enabled); + } + + @MediumTest + public void testEnableService() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveService(mDisabledServiceIntent, 0); + assertNull(info); + mPackageManager.setComponentEnabledSetting(DISABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + final ResolveInfo info2 = + mPackageManager.resolveService(mDisabledServiceIntent, + 0); + assertNotNull(info2); + assertNotNull(info2.serviceInfo); + assertFalse(info2.serviceInfo.enabled); + } + + @LargeTest + public void testDisableService() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveService(mEnabledServiceIntent, 0); + assertNotNull(info); + assertNotNull(info.serviceInfo); + mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + final ResolveInfo info2 = + mPackageManager.resolveService(mEnabledServiceIntent, + 0); + assertNull(info2); + + final ResolveInfo info3 = mPackageManager.resolveService(mEnabledServiceIntent, + GET_DISABLED_COMPONENTS); + assertNotNull(info3); + assertNotNull(info3.serviceInfo); + assertTrue(info3.serviceInfo.enabled); + } + + @MediumTest + public void testQueryDisabledReceiver() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final List<ResolveInfo> infoList = + mPackageManager.queryBroadcastReceivers(mDisabledReceiverIntent, 0); + assertEquals(0, infoList.size()); + + final List<ResolveInfo> infoList2 = + mPackageManager.queryBroadcastReceivers(mDisabledReceiverIntent, + GET_DISABLED_COMPONENTS); + assertEquals(1, infoList2.size()); + final ResolveInfo info = infoList2.get(0); + assertNotNull(info); + assertNotNull(info.activityInfo); + assertFalse(info.activityInfo.enabled); + } + + @MediumTest + public void testQueryEnabledReceiver() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final List<ResolveInfo> infoList = + mPackageManager.queryBroadcastReceivers(mEnabledReceiverIntent, 0); + assertEquals(1, infoList.size()); + final ResolveInfo info = infoList.get(0); + assertNotNull(info); + assertNotNull(info.activityInfo); + assertTrue(info.activityInfo.enabled); + } + + @MediumTest + public void testGetDisabledReceiverInfo() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + try { + mPackageManager.getReceiverInfo(DISABLED_RECEIVER_COMPONENTNAME, 0); + fail("Attempt to get info on disabled component should fail."); + } catch (PackageManager.NameNotFoundException e) { + // expected + } + + final ActivityInfo activityInfo = + mPackageManager.getReceiverInfo(DISABLED_RECEIVER_COMPONENTNAME, + GET_DISABLED_COMPONENTS); + assertNotNull(activityInfo); + assertFalse(activityInfo.enabled); + } + + @MediumTest + public void testGetEnabledReceiverInfo() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + ActivityInfo activityInfo = + mPackageManager.getReceiverInfo(ENABLED_RECEIVER_COMPONENTNAME, 0); + assertNotNull(activityInfo); + assertTrue(activityInfo.enabled); + } + + @MediumTest + public void testEnableReceiver() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + try { + mPackageManager.getReceiverInfo(DISABLED_RECEIVER_COMPONENTNAME, 0); + fail("Attempt to get info on disabled component should fail."); + } catch (PackageManager.NameNotFoundException e) { + // expected + } + + mPackageManager.setComponentEnabledSetting(DISABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + ActivityInfo activityInfo = + mPackageManager.getReceiverInfo(DISABLED_RECEIVER_COMPONENTNAME, 0); + assertNotNull(activityInfo); + assertFalse(activityInfo.enabled); + } + + @MediumTest + public void testDisableReceiver() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + ActivityInfo activityInfo = + mPackageManager.getReceiverInfo(ENABLED_RECEIVER_COMPONENTNAME, 0); + assertNotNull(activityInfo); + assertTrue(activityInfo.enabled); + mPackageManager.setComponentEnabledSetting(DISABLED_RECEIVER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + try { + mPackageManager.getReceiverInfo(DISABLED_RECEIVER_COMPONENTNAME, 0); + fail("Attempt to get info on disabled component should fail."); + } catch (PackageManager.NameNotFoundException e) { + // expected + } + } + + @MediumTest + public void testResolveEnabledProvider() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + ProviderInfo providerInfo = + mPackageManager.resolveContentProvider(ENABLED_PROVIDER_NAME, 0); + assertNotNull(providerInfo); + assertTrue(providerInfo.enabled); + } + + @MediumTest + public void testResolveDisabledProvider() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + ProviderInfo providerInfo = + mPackageManager.resolveContentProvider(DISABLED_PROVIDER_NAME, 0); + assertNull(providerInfo); + ProviderInfo providerInfo2 = + mPackageManager.resolveContentProvider(DISABLED_PROVIDER_NAME, + GET_DISABLED_COMPONENTS); + assertNotNull(providerInfo2); + assertFalse(providerInfo2.enabled); + } + + @MediumTest + public void testEnableProvider() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + ProviderInfo providerInfo = + mPackageManager.resolveContentProvider(DISABLED_PROVIDER_NAME, 0); + assertNull(providerInfo); + + mPackageManager.setComponentEnabledSetting(DISABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + ProviderInfo providerInfo2 = + mPackageManager.resolveContentProvider(DISABLED_PROVIDER_NAME, 0); + assertNotNull(providerInfo2); + assertFalse(providerInfo2.enabled); + } + + @MediumTest + public void testDisableProvider() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + ProviderInfo providerInfo = + mPackageManager.resolveContentProvider(ENABLED_PROVIDER_NAME, 0); + assertNotNull(providerInfo); + assertTrue(providerInfo.enabled); + + mPackageManager.setComponentEnabledSetting(ENABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + ProviderInfo providerInfo2 = + mPackageManager.resolveContentProvider(ENABLED_PROVIDER_NAME, 0); + assertNull(providerInfo2); + } + + @MediumTest + public void testQueryEnabledProvider() throws Exception { + mPackageManager.setComponentEnabledSetting(ENABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + String enabledProviderProcessName = getComponentProcessName(ENABLED_PROVIDER_NAME); + PackageInfo pi = mPackageManager.getPackageInfo(ENABLED_PACKAGENAME, 0); + List<ProviderInfo> providerInfoList = + mPackageManager.queryContentProviders(enabledProviderProcessName, + pi.applicationInfo.uid, 0); + assertNotNull(providerInfoList); + assertEquals(1, providerInfoList.size()); + assertEquals(ENABLED_PROVIDER_CLASSNAME, + providerInfoList.get(0).name); + } + + @MediumTest + public void testQueryDisabledProvider() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_PROVIDER_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + PackageInfo pi = mPackageManager.getPackageInfo(ENABLED_PACKAGENAME, 0); + + String disabledProviderProcessName = getComponentProcessName(DISABLED_PROVIDER_NAME); + List<ProviderInfo> providerInfoList = + mPackageManager.queryContentProviders(disabledProviderProcessName, + pi.applicationInfo.uid, 0); + assertNull(providerInfoList); + + + List<ProviderInfo> providerInfoList2 = + mPackageManager.queryContentProviders(disabledProviderProcessName, + pi.applicationInfo.uid, GET_DISABLED_COMPONENTS); + assertNotNull(providerInfoList2); + assertEquals(1, providerInfoList2.size()); + assertEquals(DISABLED_PROVIDER_CLASSNAME, + providerInfoList2.get(0).name); + } + + private String getComponentProcessName(String componentNameStr) { + ComponentInfo providerInfo = + mPackageManager.resolveContentProvider(componentNameStr, + GET_DISABLED_COMPONENTS); + return providerInfo.processName; + } + + public void DISABLED_testResolveEnabledActivityInDisabledApp() throws Exception { + mPackageManager.setApplicationEnabledSetting(DISABLED_PACKAGENAME, + COMPONENT_ENABLED_STATE_DEFAULT, + 0); + mPackageManager.setComponentEnabledSetting(DISABLED_APP_ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = + mPackageManager.resolveActivity(mDisabledAppEnabledActivityIntent, 0); + assertNull(info); + + final ResolveInfo info2 = mPackageManager.resolveActivity( + mDisabledAppEnabledActivityIntent, GET_DISABLED_COMPONENTS); + assertNotNull(info2); + assertNotNull(info2.activityInfo); + assertTrue(info2.activityInfo.enabled); + } + + public void DISABLED_testEnableApplication() throws Exception { + mPackageManager.setApplicationEnabledSetting(DISABLED_PACKAGENAME, + COMPONENT_ENABLED_STATE_DEFAULT, + 0); + mPackageManager.setComponentEnabledSetting(DISABLED_APP_ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = + mPackageManager.resolveActivity(mDisabledAppEnabledActivityIntent, 0); + assertNull(info); + + mPackageManager.setApplicationEnabledSetting(DISABLED_PACKAGENAME, + COMPONENT_ENABLED_STATE_ENABLED, + 0); + final ResolveInfo info2 = mPackageManager.resolveActivity( + mDisabledAppEnabledActivityIntent, 0); + assertNotNull(info2); + assertNotNull(info2.activityInfo); + assertTrue(info2.activityInfo.enabled); + + } + + public void DISABLED_testDisableApplication() throws Exception { + mPackageManager.setApplicationEnabledSetting(ENABLED_PACKAGENAME, + COMPONENT_ENABLED_STATE_DEFAULT, + 0); + mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + final ResolveInfo info = mPackageManager.resolveActivity(mEnabledActivityIntent, 0); + assertNotNull(info); + assertNotNull(info.activityInfo); + assertTrue(info.activityInfo.enabled); + + mPackageManager.setApplicationEnabledSetting(ENABLED_PACKAGENAME, + COMPONENT_ENABLED_STATE_DISABLED, + 0); + final ResolveInfo info2 = mPackageManager.resolveActivity(mEnabledActivityIntent, 0); + assertNull(info2); + + // Clean up + mPackageManager.setApplicationEnabledSetting(ENABLED_PACKAGENAME, + COMPONENT_ENABLED_STATE_DEFAULT, + 0); + + } + + @MediumTest + public void testNonExplicitResolveAfterEnabling() throws Exception { + mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); + + Intent intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(TEST_CATEGORY); + + final List<ResolveInfo> launchables = + mPackageManager.queryIntentActivities(intent, 0); + + int numItems = launchables.size(); + assertEquals(0, numItems); + + mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME, + COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + + final List<ResolveInfo> launchables2 = + mPackageManager.queryIntentActivities(intent, 0); + + int numItems2 = launchables2.size(); + assertEquals(1, numItems2); + } +} diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index aec82af..c699c10 100755 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -1946,42 +1946,42 @@ public class PackageManagerTests extends AndroidTestCase { static final String BASE_PERMISSIONS_DEFINED[] = new String[] { PERM_PACKAGE, "com.android.unit_tests.install_decl_perm", PERM_DEFINED, - "com.android.unit_tests.NORMAL", - "com.android.unit_tests.DANGEROUS", - "com.android.unit_tests.SIGNATURE", + "com.android.frameworks.coretests.NORMAL", + "com.android.frameworks.coretests.DANGEROUS", + "com.android.frameworks.coretests.SIGNATURE", }; static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] { - PERM_PACKAGE, "com.android.unit_tests.install_decl_perm", + PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm", PERM_UNDEFINED, - "com.android.unit_tests.NORMAL", - "com.android.unit_tests.DANGEROUS", - "com.android.unit_tests.SIGNATURE", + "com.android.frameworks.coretests.NORMAL", + "com.android.frameworks.coretests.DANGEROUS", + "com.android.frameworks.coretests.SIGNATURE", }; static final String BASE_PERMISSIONS_USED[] = new String[] { - PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good", + PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", PERM_USED, - "com.android.unit_tests.NORMAL", - "com.android.unit_tests.DANGEROUS", - "com.android.unit_tests.SIGNATURE", + "com.android.frameworks.coretests.NORMAL", + "com.android.frameworks.coretests.DANGEROUS", + "com.android.frameworks.coretests.SIGNATURE", }; static final String BASE_PERMISSIONS_NOTUSED[] = new String[] { - PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good", + PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", PERM_NOTUSED, - "com.android.unit_tests.NORMAL", - "com.android.unit_tests.DANGEROUS", - "com.android.unit_tests.SIGNATURE", + "com.android.frameworks.coretests.NORMAL", + "com.android.frameworks.coretests.DANGEROUS", + "com.android.frameworks.coretests.SIGNATURE", }; static final String BASE_PERMISSIONS_SIGUSED[] = new String[] { - PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good", + PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", PERM_USED, - "com.android.unit_tests.SIGNATURE", + "com.android.frameworks.coretests.SIGNATURE", PERM_NOTUSED, - "com.android.unit_tests.NORMAL", - "com.android.unit_tests.DANGEROUS", + "com.android.frameworks.coretests.NORMAL", + "com.android.frameworks.coretests.DANGEROUS", }; /* diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java new file mode 100644 index 0000000..31cf515 --- /dev/null +++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2005 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.database; + +import junit.framework.TestSuite; + +public class NewDatabasePerformanceTestSuite extends TestSuite { + public static TestSuite suite() { + TestSuite suite = + new TestSuite(NewDatabasePerformanceTestSuite.class.getName()); + + suite.addTestSuite(NewDatabasePerformanceTests. + Insert1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InsertIndexed1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + Select100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectStringComparison100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectIndex100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InnerJoin100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InnerJoinOneSide100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InnerJoinNoIndex100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectSubQIndex100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectIndexStringComparison100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectInteger100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectString100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectIntegerIndex100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectIndexString100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectStringStartsWith100.class); + suite.addTestSuite(NewDatabasePerformanceTests. + DeleteIndexed1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + Delete1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + DeleteWhere1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + DeleteIndexWhere1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + UpdateIndexWhere1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + UpdateWhere1000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InsertInteger10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InsertIntegerIndex10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InsertString10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + InsertStringIndexed10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectStringStartsWith10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectStringIndexedStartsWith10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectInteger10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectIntegerIndexed10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectStringContains10000.class); + suite.addTestSuite(NewDatabasePerformanceTests. + SelectStringIndexedContains10000.class); + + return suite; + } +} diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java new file mode 100644 index 0000000..0dca90b --- /dev/null +++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java @@ -0,0 +1,1234 @@ +/* + * 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.database; + +import android.content.ContentValues; +import android.database.sqlite.SQLiteDatabase; +import android.test.PerformanceTestCase; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import java.io.File; +import java.util.Random; + +/** + * Database Performance Tests + * + */ + +public class NewDatabasePerformanceTests { + + // Edit this to change the test run times. The original is 100. + final static int kMultiplier = 1; + + public static class PerformanceBase extends TestCase + implements PerformanceTestCase { + protected static final int CURRENT_DATABASE_VERSION = 42; + protected SQLiteDatabase mDatabase; + protected File mDatabaseFile; + + public void setUp() { + mDatabaseFile = new File("/sdcard", "perf_database_test.db"); + if (mDatabaseFile.exists()) { + mDatabaseFile.delete(); + } + mDatabase = + SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), + null); + assertTrue(mDatabase != null); + mDatabase.setVersion(CURRENT_DATABASE_VERSION); + } + + public void tearDown() { + mDatabase.close(); + mDatabaseFile.delete(); + } + + public boolean isPerformanceOnly() { + return true; + } + + // These tests can only be run once. + public int startPerformance(Intermediates intermediates) { + return 0; + } + + public String numberName(int number) { + String result = ""; + + if (number >= 1000) { + result += numberName((number / 1000)) + " thousand"; + number = (number % 1000); + + if (number > 0) result += " "; + } + + if (number >= 100) { + result += ONES[(number / 100)] + " hundred"; + number = (number % 100); + + if (number > 0) result += " "; + } + + if (number >= 20) { + result += TENS[(number / 10)]; + number = (number % 10); + + if (number > 0) result += " "; + } + + if (number > 0) { + result += ONES[number]; + } + + return result; + } + } + + /** + * Test 1000 inserts. + */ + + public static class Insert1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + + private String[] statements = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + statements[i] = + "INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"; + } + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.execSQL(statements[i]); + } + } + } + + /** + * Test 1000 inserts into an indexed table. + */ + + public static class InsertIndexed1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + + private String[] statements = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + statements[i] = + "INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"; + } + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1c ON t1(c)"); + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.execSQL(statements[i]); + } + } + } + + /** + * 100 SELECTs without an index + */ + + public static class Select100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"count(*)", "avg(b)"}; + + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "b >= " + lower + " AND b < " + upper; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase + .query("t1", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 100 SELECTs on a string comparison + */ + + public static class SelectStringComparison100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"count(*)", "avg(b)"}; + + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + where[i] = "c LIKE '" + numberName(i) + "'"; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase + .query("t1", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 100 SELECTs with an index + */ + + public static class SelectIndex100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"count(*)", "avg(b)"}; + + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1b ON t1(b)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "b >= " + lower + " AND b < " + upper; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase + .query("t1", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * INNER JOIN without an index + */ + + public static class InnerJoin100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"t1.a"}; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase + .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + } + + public void testRun() { + mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null, + null, null, null, null); + } + } + + /** + * INNER JOIN without an index on one side + */ + + public static class InnerJoinOneSide100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"t1.a"}; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase + .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))"); + + mDatabase.execSQL("CREATE INDEX i1b ON t1(b)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + } + + public void testRun() { + mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null, + null, null, null, null); + } + } + + /** + * INNER JOIN without an index on one side + */ + + public static class InnerJoinNoIndex100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"t1.a"}; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase + .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))"); + + mDatabase.execSQL("CREATE INDEX i1b ON t1(b)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + } + + public void testRun() { + mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null, + null, null, null, null); + } + } + + /** + * 100 SELECTs with subqueries. Subquery is using an index + */ + + public static class SelectSubQIndex100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"t1.a"}; + + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase + .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))"); + + mDatabase.execSQL("CREATE INDEX i2b ON t2(b)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = + "t1.b IN (SELECT t2.b FROM t2 WHERE t2.b >= " + lower + + " AND t2.b < " + upper + ")"; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase + .query("t1", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 100 SELECTs on string comparison with Index + */ + + public static class SelectIndexStringComparison100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"count(*)", "avg(b)"}; + + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i3c ON t1(c)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + where[i] = "c LIKE '" + numberName(i) + "'"; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase + .query("t1", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 100 SELECTs on integer + */ + + public static class SelectInteger100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"b"}; + + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t1", COLUMNS, null, null, null, null, null); + } + } + } + + /** + * 100 SELECTs on String + */ + + public static class SelectString100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"c"}; + + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t1", COLUMNS, null, null, null, null, null); + } + } + } + + /** + * 100 SELECTs on integer with index + */ + + public static class SelectIntegerIndex100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"b"}; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1b on t1(b)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t1", COLUMNS, null, null, null, null, null); + } + } + } + + /** + * 100 SELECTs on String with index + */ + + public static class SelectIndexString100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"c"}; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1c ON t1(c)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t1", COLUMNS, null, null, null, null, null); + } + } + } + + /** + * 100 SELECTs on String with starts with + */ + + public static class SelectStringStartsWith100 extends PerformanceBase { + private static final int SIZE = 1 * kMultiplier; + private static final String[] COLUMNS = {"c"}; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1c ON t1(c)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + where[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'"; + + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase + .query("t1", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 1000 Deletes on an indexed table + */ + + public static class DeleteIndexed1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + private static final String[] COLUMNS = {"c"}; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i3c ON t1(c)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.delete("t1", null, null); + } + } + } + + /** + * 1000 Deletes + */ + + public static class Delete1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + private static final String[] COLUMNS = {"c"}; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.delete("t1", null, null); + } + } + } + + /** + * 1000 DELETE's without an index with where clause + */ + + public static class DeleteWhere1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "b >= " + lower + " AND b < " + upper; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.delete("t1", where[i], null); + } + } + } + + /** + * 1000 DELETE's with an index with where clause + */ + + public static class DeleteIndexWhere1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1b ON t1(b)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "b >= " + lower + " AND b < " + upper; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.delete("t1", where[i], null); + } + } + } + + /** + * 1000 update's with an index with where clause + */ + + public static class UpdateIndexWhere1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + private String[] where = new String[SIZE]; + ContentValues[] mValues = new ContentValues[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1b ON t1(b)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "b >= " + lower + " AND b < " + upper; + ContentValues b = new ContentValues(1); + b.put("b", upper); + mValues[i] = b; + + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.update("t1", mValues[i], where[i], null); + } + } + } + + /** + * 1000 update's without an index with where clause + */ + + public static class UpdateWhere1000 extends PerformanceBase { + private static final int SIZE = 10 * kMultiplier; + private String[] where = new String[SIZE]; + ContentValues[] mValues = new ContentValues[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "b >= " + lower + " AND b < " + upper; + ContentValues b = new ContentValues(1); + b.put("b", upper); + mValues[i] = b; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.update("t1", mValues[i], where[i], null); + } + } + } + + /** + * 10000 inserts for an integer + */ + + public static class InsertInteger10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + ContentValues[] mValues = new ContentValues[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + ContentValues b = new ContentValues(1); + b.put("a", r); + mValues[i] = b; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.insert("t1", null, mValues[i]); + } + } + } + + /** + * 10000 inserts for an integer -indexed table + */ + + public static class InsertIntegerIndex10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + ContentValues[] mValues = new ContentValues[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a INTEGER)"); + mDatabase.execSQL("CREATE INDEX i1a ON t1(a)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + ContentValues b = new ContentValues(1); + b.put("a", r); + mValues[i] = b; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.insert("t1", null, mValues[i]); + } + } + } + + /** + * 10000 inserts for a String + */ + + public static class InsertString10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + ContentValues[] mValues = new ContentValues[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + ContentValues b = new ContentValues(1); + b.put("a", numberName(r)); + mValues[i] = b; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.insert("t1", null, mValues[i]); + } + } + } + + /** + * 10000 inserts for a String - indexed table + */ + + public static class InsertStringIndexed10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + ContentValues[] mValues = new ContentValues[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t1(a VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i1a ON t1(a)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + ContentValues b = new ContentValues(1); + b.put("a", numberName(r)); + mValues[i] = b; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.insert("t1", null, mValues[i]); + } + } + } + + + /** + * 10000 selects for a String -starts with + */ + + public static class SelectStringStartsWith10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + private static final String[] COLUMNS = {"t3.a"}; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t3(a VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t3 VALUES('" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'"; + + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t3", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 10000 selects for a String - indexed table -starts with + */ + + public static class SelectStringIndexedStartsWith10000 extends + PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + private static final String[] COLUMNS = {"t3.a"}; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t3(a VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i3a ON t3(a)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t3 VALUES('" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'"; + + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t3", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 10000 selects for an integer - + */ + + public static class SelectInteger10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + private static final String[] COLUMNS = {"t4.a"}; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t4(a INTEGER)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")"); + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "a >= " + lower + " AND a < " + upper; + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t4", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 10000 selects for an integer -indexed table + */ + + public static class SelectIntegerIndexed10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + private static final String[] COLUMNS = {"t4.a"}; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t4(a INTEGER)"); + mDatabase.execSQL("CREATE INDEX i4a ON t4(a)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")"); + + int lower = i * 100; + int upper = (i + 10) * 100; + where[i] = "a >= " + lower + " AND a < " + upper; + } + + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t4", COLUMNS, where[i], null, null, null, null); + } + } + } + + + /** + * 10000 selects for a String - contains 'e' + */ + + public static class SelectStringContains10000 extends PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + private static final String[] COLUMNS = {"t3.a"}; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t3(a VARCHAR(100))"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t3 VALUES('" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + where[i] = "a LIKE '*e*'"; + + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t3", COLUMNS, where[i], null, null, null, null); + } + } + } + + /** + * 10000 selects for a String - contains 'e'-indexed table + */ + + public static class SelectStringIndexedContains10000 extends + PerformanceBase { + private static final int SIZE = 100 * kMultiplier; + private static final String[] COLUMNS = {"t3.a"}; + private String[] where = new String[SIZE]; + + @Override + public void setUp() { + super.setUp(); + Random random = new Random(42); + + mDatabase + .execSQL("CREATE TABLE t3(a VARCHAR(100))"); + mDatabase.execSQL("CREATE INDEX i3a ON t3(a)"); + + for (int i = 0; i < SIZE; i++) { + int r = random.nextInt(100000); + mDatabase.execSQL("INSERT INTO t3 VALUES('" + + numberName(r) + "')"); + } + + for (int i = 0; i < SIZE; i++) { + where[i] = "a LIKE '*e*'"; + + } + } + + public void testRun() { + for (int i = 0; i < SIZE; i++) { + mDatabase.query("t3", COLUMNS, where[i], null, null, null, null); + } + } + } + + public static final String[] ONES = + {"zero", "one", "two", "three", "four", "five", "six", "seven", + "eight", "nine", "ten", "eleven", "twelve", "thirteen", + "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", + "nineteen"}; + + public static final String[] TENS = + {"", "ten", "twenty", "thirty", "forty", "fifty", "sixty", + "seventy", "eighty", "ninety"}; +} diff --git a/core/tests/coretests/src/android/text/HtmlTest.java b/core/tests/coretests/src/android/text/HtmlTest.java index a79b93e..c07d212 100644 --- a/core/tests/coretests/src/android/text/HtmlTest.java +++ b/core/tests/coretests/src/android/text/HtmlTest.java @@ -16,14 +16,25 @@ package android.text; -import android.test.InstrumentationTestCase; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.graphics.Typeface; import android.test.suitebuilder.annotation.MediumTest; -import android.text.Html; -import android.text.Spanned; +import android.test.suitebuilder.annotation.SmallTest; +import android.text.style.ForegroundColorSpan; +import android.text.style.QuoteSpan; +import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; -import android.graphics.Typeface; +import android.text.style.SubscriptSpan; +import android.text.style.SuperscriptSpan; +import android.text.style.TextAppearanceSpan; +import android.text.style.TypefaceSpan; +import android.text.style.URLSpan; +import android.text.style.UnderlineSpan; -public class HtmlTest extends InstrumentationTestCase { +import junit.framework.TestCase; + +public class HtmlTest extends TestCase { @MediumTest public void testSingleTagOnWhileString() { @@ -63,4 +74,175 @@ public class HtmlTest extends InstrumentationTestCase { String spanned = Html.fromHtml("© > <").toString(); assertEquals("\u00a9 > <", spanned); } + + @MediumTest + public void testColor() throws Exception { + Spanned s; + ForegroundColorSpan[] colors; + + s = Html.fromHtml("<font color=\"#00FF00\">something</font>"); + colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); + assertEquals(1, colors.length); + assertEquals(0xFF00FF00, colors[0].getForegroundColor()); + + s = Html.fromHtml("<font color=\"navy\">something</font>"); + colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); + assertEquals(1, colors.length); + assertEquals(0xFF000080, colors[0].getForegroundColor()); + + s = Html.fromHtml("<font color=\"gibberish\">something</font>"); + colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); + assertEquals(0, colors.length); + } + + @MediumTest + public void testResourceColor() throws Exception { + ColorStateList c = + Resources.getSystem().getColorStateList(android.R.color.primary_text_dark); + Spanned s; + TextAppearanceSpan[] colors; + + s = Html.fromHtml("<font color=\"@android:color/primary_text_dark\">something</font>"); + colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); + assertEquals(1, colors.length); + assertEquals(c.toString(), colors[0].getTextColor().toString()); + + s = Html.fromHtml("<font color=\"@android:primary_text_dark\">something</font>"); + colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); + assertEquals(1, colors.length); + assertEquals(c.toString(), colors[0].getTextColor().toString()); + + s = Html.fromHtml("<font color=\"@color/primary_text_dark\">something</font>"); + colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); + assertEquals(1, colors.length); + assertEquals(c.toString(), colors[0].getTextColor().toString()); + + s = Html.fromHtml("<font color=\"@primary_text_dark\">something</font>"); + colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); + assertEquals(1, colors.length); + assertEquals(c.toString(), colors[0].getTextColor().toString()); + + s = Html.fromHtml("<font color=\"@" + android.R.color.primary_text_dark + + "\">something</font>"); + colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); + assertEquals(1, colors.length); + assertEquals(c.toString(), colors[0].getTextColor().toString()); + + s = Html.fromHtml("<font color=\"gibberish\">something</font>"); + colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); + assertEquals(colors.length, 0); + } + + @SmallTest + public void testParagraphs() throws Exception { + SpannableString s; + + s = new SpannableString("Hello world"); + assertEquals(Html.toHtml(s), "<p>Hello world</p>\n"); + + s = new SpannableString("Hello world\nor something"); + assertEquals(Html.toHtml(s), "<p>Hello world<br>\nor something</p>\n"); + + s = new SpannableString("Hello world\n\nor something"); + assertEquals(Html.toHtml(s), "<p>Hello world</p>\n<p>or something</p>\n"); + + s = new SpannableString("Hello world\n\n\nor something"); + assertEquals(Html.toHtml(s), "<p>Hello world<br></p>\n<p>or something</p>\n"); + + assertEquals("foo\nbar", Html.fromHtml("foo<br>bar").toString()); + assertEquals("foo\nbar", Html.fromHtml("foo<br>\nbar").toString()); + assertEquals("foo\nbar", Html.fromHtml("foo<br>\n \nbar").toString()); + } + + @SmallTest + public void testBlockquote() throws Exception { + SpannableString s; + + s = new SpannableString("Hello world"); + s.setSpan(new QuoteSpan(), 0, s.length(), Spannable.SPAN_PARAGRAPH); + assertEquals(Html.toHtml(s), "<blockquote><p>Hello world</p>\n</blockquote>\n"); + + s = new SpannableString("Hello\n\nworld"); + s.setSpan(new QuoteSpan(), 0, 7, Spannable.SPAN_PARAGRAPH); + assertEquals(Html.toHtml(s), "<blockquote><p>Hello</p>\n</blockquote>\n<p>world</p>\n"); + } + + @SmallTest + public void testEntities() throws Exception { + SpannableString s; + + s = new SpannableString("Hello <&> world"); + assertEquals(Html.toHtml(s), "<p>Hello <&> world</p>\n"); + + s = new SpannableString("Hello \u03D5 world"); + assertEquals(Html.toHtml(s), "<p>Hello ϕ world</p>\n"); + + s = new SpannableString("Hello world"); + assertEquals(Html.toHtml(s), "<p>Hello world</p>\n"); + } + + @SmallTest + public void testMarkup() throws Exception { + SpannableString s; + + s = new SpannableString("Hello bold world"); + s.setSpan(new StyleSpan(Typeface.BOLD), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), "<p>Hello <b>bold</b> world</p>\n"); + + s = new SpannableString("Hello italic world"); + s.setSpan(new StyleSpan(Typeface.ITALIC), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), "<p>Hello <i>italic</i> world</p>\n"); + + s = new SpannableString("Hello monospace world"); + s.setSpan(new TypefaceSpan("monospace"), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), "<p>Hello <tt>monospace</tt> world</p>\n"); + + s = new SpannableString("Hello superscript world"); + s.setSpan(new SuperscriptSpan(), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), "<p>Hello <sup>superscript</sup> world</p>\n"); + + s = new SpannableString("Hello subscript world"); + s.setSpan(new SubscriptSpan(), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), "<p>Hello <sub>subscript</sub> world</p>\n"); + + s = new SpannableString("Hello underline world"); + s.setSpan(new UnderlineSpan(), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), "<p>Hello <u>underline</u> world</p>\n"); + + s = new SpannableString("Hello struck world"); + s.setSpan(new StrikethroughSpan(), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), "<p>Hello <strike>struck</strike> world</p>\n"); + + s = new SpannableString("Hello linky world"); + s.setSpan(new URLSpan("http://www.google.com"), 6, s.length() - 6, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + assertEquals(Html.toHtml(s), + "<p>Hello <a href=\"http://www.google.com\">linky</a> world</p>\n"); + } + + @SmallTest + public void testImg() throws Exception { + Spanned s; + + s = Html.fromHtml("yes<img src=\"http://example.com/foo.gif\">no"); + + assertEquals("<p>yes<img src=\"http://example.com/foo.gif\">no</p>\n", + Html.toHtml(s)); + } + + @SmallTest + public void testUtf8() throws Exception { + Spanned s; + + s = Html.fromHtml("<p>\u0124\u00eb\u0142\u0142o, world!</p>"); + assertEquals("<p>Ĥëłło, world!</p>\n", Html.toHtml(s)); + } + } diff --git a/core/tests/coretests/src/android/text/util/LinkifyTest.java b/core/tests/coretests/src/android/text/util/LinkifyTest.java new file mode 100644 index 0000000..99c6501 --- /dev/null +++ b/core/tests/coretests/src/android/text/util/LinkifyTest.java @@ -0,0 +1,66 @@ +/* + * 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.text.util; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.text.method.LinkMovementMethod; +import android.text.util.Linkify; +import android.widget.TextView; + +/** + * LinkifyTest tests {@link Linkify}. + */ +public class LinkifyTest extends AndroidTestCase { + + @SmallTest + public void testNothing() throws Exception { + TextView tv; + + tv = new TextView(getContext()); + tv.setText("Hey, foo@google.com, call 415-555-1212."); + + assertFalse(tv.getMovementMethod() instanceof LinkMovementMethod); + assertTrue(tv.getUrls().length == 0); + } + + @MediumTest + public void testNormal() throws Exception { + TextView tv; + + tv = new TextView(getContext()); + tv.setAutoLinkMask(Linkify.ALL); + tv.setText("Hey, foo@google.com, call 415-555-1212."); + + assertTrue(tv.getMovementMethod() instanceof LinkMovementMethod); + assertTrue(tv.getUrls().length == 2); + } + + @SmallTest + public void testUnclickable() throws Exception { + TextView tv; + + tv = new TextView(getContext()); + tv.setAutoLinkMask(Linkify.ALL); + tv.setLinksClickable(false); + tv.setText("Hey, foo@google.com, call 415-555-1212."); + + assertFalse(tv.getMovementMethod() instanceof LinkMovementMethod); + assertTrue(tv.getUrls().length == 2); + } +} diff --git a/core/tests/coretests/src/android/util/PatternsTest.java b/core/tests/coretests/src/android/util/PatternsTest.java new file mode 100644 index 0000000..957c593 --- /dev/null +++ b/core/tests/coretests/src/android/util/PatternsTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.util; + +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Patterns; + +import java.util.regex.Matcher; + +import junit.framework.TestCase; + +public class PatternsTest extends TestCase { + + @SmallTest + public void testTldPattern() throws Exception { + boolean t; + + t = Patterns.TOP_LEVEL_DOMAIN.matcher("com").matches(); + assertTrue("Missed valid TLD", t); + + // One of the new top level domain. + t = Patterns.TOP_LEVEL_DOMAIN.matcher("me").matches(); + assertTrue("Missed valid TLD", t); + + // One of the new top level test domain. + t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn--0zwm56d").matches(); + assertTrue("Missed valid TLD", t); + + t = Patterns.TOP_LEVEL_DOMAIN.matcher("mem").matches(); + assertFalse("Matched invalid TLD!", t); + + t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn").matches(); + assertFalse("Matched invalid TLD!", t); + + t = Patterns.TOP_LEVEL_DOMAIN.matcher("xer").matches(); + assertFalse("Matched invalid TLD!", t); + } + + @SmallTest + public void testUrlPattern() throws Exception { + boolean t; + + t = Patterns.WEB_URL.matcher("http://www.google.com").matches(); + assertTrue("Valid URL", t); + + // Google in one of the new top level domain. + t = Patterns.WEB_URL.matcher("http://www.google.me").matches(); + assertTrue("Valid URL", t); + t = Patterns.WEB_URL.matcher("google.me").matches(); + assertTrue("Valid URL", t); + + // Test url in Chinese: http://xn--fsqu00a.xn--0zwm56d + t = Patterns.WEB_URL.matcher("http://xn--fsqu00a.xn--0zwm56d").matches(); + assertTrue("Valid URL", t); + t = Patterns.WEB_URL.matcher("xn--fsqu00a.xn--0zwm56d").matches(); + assertTrue("Valid URL", t); + + // Internationalized URL. + t = Patterns.WEB_URL.matcher("http://\uD604\uAE08\uC601\uC218\uC99D.kr").matches(); + assertTrue("Valid URL", t); + t = Patterns.WEB_URL.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches(); + assertTrue("Valid URL", t); + + t = Patterns.WEB_URL.matcher("ftp://www.example.com").matches(); + assertFalse("Matched invalid protocol", t); + + t = Patterns.WEB_URL.matcher("http://www.example.com:8080").matches(); + assertTrue("Didn't match valid URL with port", t); + + t = Patterns.WEB_URL.matcher("http://www.example.com:8080/?foo=bar").matches(); + assertTrue("Didn't match valid URL with port and query args", t); + + t = Patterns.WEB_URL.matcher("http://www.example.com:8080/~user/?foo=bar").matches(); + assertTrue("Didn't match valid URL with ~", t); + } + + @SmallTest + public void testIpPattern() throws Exception { + boolean t; + + t = Patterns.IP_ADDRESS.matcher("172.29.86.3").matches(); + assertTrue("Valid IP", t); + + t = Patterns.IP_ADDRESS.matcher("1234.4321.9.9").matches(); + assertFalse("Invalid IP", t); + } + + @SmallTest + public void testDomainPattern() throws Exception { + boolean t; + + t = Patterns.DOMAIN_NAME.matcher("mail.example.com").matches(); + assertTrue("Valid domain", t); + + t = Patterns.WEB_URL.matcher("google.me").matches(); + assertTrue("Valid domain", t); + + // Internationalized domains. + t = Patterns.DOMAIN_NAME.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches(); + assertTrue("Valid domain", t); + + t = Patterns.DOMAIN_NAME.matcher("__+&42.xer").matches(); + assertFalse("Invalid domain", t); + } + + @SmallTest + public void testPhonePattern() throws Exception { + boolean t; + + t = Patterns.PHONE.matcher("(919) 555-1212").matches(); + assertTrue("Valid phone", t); + + t = Patterns.PHONE.matcher("2334 9323/54321").matches(); + assertFalse("Invalid phone", t); + + String[] tests = { + "Me: 16505551212 this\n", + "Me: 6505551212 this\n", + "Me: 5551212 this\n", + + "Me: 1-650-555-1212 this\n", + "Me: (650) 555-1212 this\n", + "Me: +1 (650) 555-1212 this\n", + "Me: +1-650-555-1212 this\n", + "Me: 650-555-1212 this\n", + "Me: 555-1212 this\n", + + "Me: 1.650.555.1212 this\n", + "Me: (650) 555.1212 this\n", + "Me: +1 (650) 555.1212 this\n", + "Me: +1.650.555.1212 this\n", + "Me: 650.555.1212 this\n", + "Me: 555.1212 this\n", + + "Me: 1 650 555 1212 this\n", + "Me: (650) 555 1212 this\n", + "Me: +1 (650) 555 1212 this\n", + "Me: +1 650 555 1212 this\n", + "Me: 650 555 1212 this\n", + "Me: 555 1212 this\n", + }; + + for (String test : tests) { + Matcher m = Patterns.PHONE.matcher(test); + + assertTrue("Valid phone " + test, m.find()); + } + } +} diff --git a/core/tests/coretests/src/com/android/internal/net/DNParserTest.java b/core/tests/coretests/src/com/android/internal/net/DNParserTest.java new file mode 100644 index 0000000..9b490a3 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/net/DNParserTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.net; + +import com.android.internal.net.DNParser; + +import javax.security.auth.x500.X500Principal; + +import junit.framework.TestCase; + +public class DNParserTest extends TestCase { + public void testFind() { + checkFind("", "cn", null); + checkFind("ou=xxx", "cn", null); + checkFind("ou=xxx,cn=xxx", "cn", "xxx"); + checkFind("ou=xxx+cn=yyy,cn=zzz+cn=abc", "cn", "yyy"); + checkFind("2.5.4.3=a,ou=xxx", "cn", "a"); // OID + checkFind("cn=a,cn=b", "cn", "a"); + checkFind("ou=Cc,ou=Bb,ou=Aa", "ou", "Cc"); + checkFind("cn=imap.gmail.com", "cn", "imap.gmail.com"); + + // Quoted string (see http://www.ietf.org/rfc/rfc2253.txt) + checkFind("o=\"\\\" a ,=<>#;\"", "o", "\" a ,=<>#;"); + checkFind("o=abc\\,def", "o", "abc,def"); + + // UTF-8 (example in rfc 2253) + checkFind("cn=Lu\\C4\\8Di\\C4\\87", "cn", "\u004c\u0075\u010d\u0069\u0107"); + + // whitespaces + checkFind("ou=a, o= a b ,cn=x", "o", "a b"); + checkFind("o=\" a b \" ,cn=x", "o", " a b "); + } + + private void checkFind(String dn, String attrType, String expected) { + String actual = new DNParser(new X500Principal(dn)).find(attrType); + assertEquals("dn:" + dn + " attr:" + attrType, expected, actual); + } +} diff --git a/core/tests/coretests/src/com/android/internal/net/DomainNameValidatorTest.java b/core/tests/coretests/src/com/android/internal/net/DomainNameValidatorTest.java new file mode 100644 index 0000000..f0d581e --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/net/DomainNameValidatorTest.java @@ -0,0 +1,401 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.net; + +import com.android.internal.net.DomainNameValidator; +import com.android.frameworks.coretests.R; +import com.android.frameworks.coretests.R.raw; + +import android.test.AndroidTestCase; + +import java.io.InputStream; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateFactory; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +public class DomainNameValidatorTest extends AndroidTestCase { + private static final int ALT_UNKNOWN = 0; + private static final int ALT_DNS_NAME = 2; + private static final int ALT_IPA_NAME = 7; + + /** + * Tests {@link DomainNameValidator#match}, using a simple {@link X509Certificate} + * implementation. + */ + public void testMatch() { + checkMatch("11", new StubX509Certificate("cn=imap.g.com"), "imap.g.com", true); + checkMatch("12", new StubX509Certificate("cn=imap2.g.com"), "imap.g.com", false); + checkMatch("13", new StubX509Certificate("cn=sub.imap.g.com"), "imap.g.com", false); + + // If a subjectAltName extension of type dNSName is present, that MUST + // be used as the identity + checkMatch("21", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com") + , "imap.g.com", false); + checkMatch("22", new StubX509Certificate("cn=imap.g.com") // This cn should be ignored + .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com") + , "imap.g.com", false); + checkMatch("23", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") + , "imap.g.com", true); + + // With wildcards + checkMatch("24", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_DNS_NAME, "*.g.com") + , "imap.g.com", true); + + // host name is ip address + checkMatch("31", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4") + , "1.2.3.4", true); + checkMatch("32", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4") + , "1.2.3.5", false); + checkMatch("32", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4") + .addSubjectAlternativeName(ALT_IPA_NAME, "192.168.100.1") + , "192.168.100.1", true); + + // Has unknown subject alternative names + checkMatch("41", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") + .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") + .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") + .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") + .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") + , "imap.g.com", true); + + checkMatch("42", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") + .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") + .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") + .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") + .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") + , "2.33.44.55", true); + + checkMatch("43", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") + .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") + .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") + .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") + .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") + , "g.com", false); + + checkMatch("44", new StubX509Certificate("") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") + .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") + .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") + .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") + .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") + .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") + , "2.33.44.1", false); + } + + private void checkMatch(String message, X509Certificate certificate, String thisDomain, + boolean expected) { + Boolean actual = DomainNameValidator.match(certificate, thisDomain); + assertEquals(message, (Object) expected, (Object) actual); + } + + /** + * Tests {@link DomainNameValidator#matchDns} + */ + public void testMatchDns() { + checkMatchDns("11", "a.b.c.d", "a.b.c.d", true); + checkMatchDns("12", "a.b.c.d", "*.b.c.d", true); + checkMatchDns("13", "b.c.d", "*.b.c.d", true); + checkMatchDns("14", "b.c.d", "b*.c.d", true); + + checkMatchDns("15", "a.b.c.d", "*.*.c.d", false); + checkMatchDns("16", "a.b.c.d", "*.c.d", false); + + checkMatchDns("21", "imap.google.com", "imap.google.com", true); + checkMatchDns("22", "imap2.google.com", "imap.google.com", false); + checkMatchDns("23", "imap.google.com", "*.google.com", true); + checkMatchDns("24", "imap2.google.com", "*.google.com", true); + checkMatchDns("25", "imap.google.com", "*.googl.com", false); + checkMatchDns("26", "imap2.google2.com", "*.google3.com", false); + checkMatchDns("27", "imap.google.com", "ima*.google.com", true); + checkMatchDns("28", "imap.google.com", "imap*.google.com", true); + checkMatchDns("29", "imap.google.com", "*.imap.google.com", true); + + checkMatchDns("41", "imap.google.com", "a*.google.com", false); + checkMatchDns("42", "imap.google.com", "ix*.google.com", false); + + checkMatchDns("51", "imap.google.com", "iMap.Google.Com", true); + } + + private void checkMatchDns(String message, String thisDomain, String thatDomain, + boolean expected) { + boolean actual = DomainNameValidator.matchDns(thisDomain, thatDomain); + assertEquals(message, expected, actual); + } + + /** + * Test {@link DomainNameValidator#match} with actual certificates. + */ + public void testWithActualCert() throws Exception { + // subject_only + // + // subject: C=JP, CN=www.example.com + // subject alt names: n/a + checkWithActualCert("11", R.raw.subject_only, "www.example.com", true); + checkWithActualCert("12", R.raw.subject_only, "www2.example.com", false); + + // subject_alt_only + // + // subject: C=JP (no CN) + // subject alt names: DNS:www.example.com + checkWithActualCert("21", R.raw.subject_alt_only, "www.example.com", true); + checkWithActualCert("22", R.raw.subject_alt_only, "www2.example.com", false); + + // subject_with_alt_names + // + // subject: C=JP, CN=www.example.com + // subject alt names: DNS:www2.example.com, DNS:www3.example.com + // * Subject should be ignored, because it has subject alt names. + checkWithActualCert("31", R.raw.subject_with_alt_names, "www.example.com", false); + checkWithActualCert("32", R.raw.subject_with_alt_names, "www2.example.com", true); + checkWithActualCert("33", R.raw.subject_with_alt_names, "www3.example.com", true); + checkWithActualCert("34", R.raw.subject_with_alt_names, "www4.example.com", false); + + // subject_with_wild_alt_name + // + // subject: C=JP, CN=www.example.com + // subject alt names: DNS:*.example2.com + // * Subject should be ignored, because it has subject alt names. + checkWithActualCert("41", R.raw.subject_with_wild_alt_name, "www.example.com", false); + checkWithActualCert("42", R.raw.subject_with_wild_alt_name, "www2.example.com", false); + checkWithActualCert("43", R.raw.subject_with_wild_alt_name, "www.example2.com", true); + checkWithActualCert("44", R.raw.subject_with_wild_alt_name, "abc.example2.com", true); + checkWithActualCert("45", R.raw.subject_with_wild_alt_name, "www.example3.com", false); + + // wild_alt_name_only + // + // subject: C=JP + // subject alt names: DNS:*.example.com + checkWithActualCert("51", R.raw.wild_alt_name_only, "www.example.com", true); + checkWithActualCert("52", R.raw.wild_alt_name_only, "www2.example.com", true); + checkWithActualCert("53", R.raw.wild_alt_name_only, "www.example2.com", false); + + // wild_alt_name_only + // + // subject: C=JP + // subject alt names: IP Address:192.168.10.1 + checkWithActualCert("61", R.raw.alt_ip_only, "192.168.10.1", true); + checkWithActualCert("61", R.raw.alt_ip_only, "192.168.10.2", false); + } + + private void checkWithActualCert(String message, int resId, String domain, + boolean expected) throws Exception { + CertificateFactory factory = CertificateFactory.getInstance("X509"); + InputStream certStream = getContext().getResources().openRawResource(resId); + X509Certificate certificate = (X509Certificate) factory.generateCertificate(certStream); + + checkMatch(message, certificate, domain, expected); + } + + /** + * Minimal {@link X509Certificate} implementation for {@link DomainNameValidator}. + */ + private static class StubX509Certificate extends X509Certificate { + private final X500Principal subjectX500Principal; + private Collection<List<?>> subjectAlternativeNames; + + public StubX509Certificate(String subjectDn) { + subjectX500Principal = new X500Principal(subjectDn); + subjectAlternativeNames = null; + } + + public StubX509Certificate addSubjectAlternativeName(int type, String name) { + if (subjectAlternativeNames == null) { + subjectAlternativeNames = new ArrayList<List<?>>(); + } + LinkedList<Object> entry = new LinkedList<Object>(); + entry.add(type); + entry.add(name); + subjectAlternativeNames.add(entry); + return this; + } + + @Override + public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException { + return subjectAlternativeNames; + } + + @Override + public X500Principal getSubjectX500Principal() { + return subjectX500Principal; + } + + @Override + public void checkValidity() throws CertificateExpiredException, + CertificateNotYetValidException { + throw new RuntimeException("Method not implemented"); + } + + @Override + public void checkValidity(Date date) throws CertificateExpiredException, + CertificateNotYetValidException { + throw new RuntimeException("Method not implemented"); + } + + @Override + public int getBasicConstraints() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public Principal getIssuerDN() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public boolean[] getIssuerUniqueID() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public boolean[] getKeyUsage() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public Date getNotAfter() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public Date getNotBefore() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public BigInteger getSerialNumber() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public String getSigAlgName() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public String getSigAlgOID() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public byte[] getSigAlgParams() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public byte[] getSignature() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public Principal getSubjectDN() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public boolean[] getSubjectUniqueID() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public byte[] getTBSCertificate() throws CertificateEncodingException { + throw new RuntimeException("Method not implemented"); + } + + @Override + public int getVersion() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public byte[] getEncoded() throws CertificateEncodingException { + throw new RuntimeException("Method not implemented"); + } + + @Override + public PublicKey getPublicKey() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public String toString() { + throw new RuntimeException("Method not implemented"); + } + + @Override + public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, SignatureException { + throw new RuntimeException("Method not implemented"); + } + + @Override + public void verify(PublicKey key, String sigProvider) throws CertificateException, + NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, + SignatureException { + throw new RuntimeException("Method not implemented"); + } + + public Set<String> getCriticalExtensionOIDs() { + throw new RuntimeException("Method not implemented"); + } + + public byte[] getExtensionValue(String oid) { + throw new RuntimeException("Method not implemented"); + } + + public Set<String> getNonCriticalExtensionOIDs() { + throw new RuntimeException("Method not implemented"); + } + + public boolean hasUnsupportedCriticalExtension() { + throw new RuntimeException("Method not implemented"); + } + } +} diff --git a/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java b/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java new file mode 100644 index 0000000..36dee70 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util; + +import java.text.Collator; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Locale; + +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +import com.android.internal.util.HanziToPinyin; +import com.android.internal.util.HanziToPinyin.Token; + +import junit.framework.TestCase; + +public class HanziToPinyinTest extends TestCase { + private final static String ONE_HANZI = "\u675C"; + private final static String TWO_HANZI = "\u675C\u9D51"; + private final static String ASSIC = "test"; + private final static String ONE_UNKNOWN = "\uFF71"; + private final static String MISC = "test\u675C Test with space\uFF71\uFF71\u675C"; + + @SmallTest + public void testGetToken() throws Exception { + if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) { + return; + } + ArrayList<Token> tokens = HanziToPinyin.getInstance().get(ONE_HANZI); + assertEquals(tokens.size(), 1); + assertEquals(tokens.get(0).type, Token.PINYIN); + assertTrue(tokens.get(0).target.equalsIgnoreCase("DU")); + + tokens = HanziToPinyin.getInstance().get(TWO_HANZI); + assertEquals(tokens.size(), 2); + assertEquals(tokens.get(0).type, Token.PINYIN); + assertEquals(tokens.get(1).type, Token.PINYIN); + assertTrue(tokens.get(0).target.equalsIgnoreCase("DU")); + assertTrue(tokens.get(1).target.equalsIgnoreCase("JUAN")); + + tokens = HanziToPinyin.getInstance().get(ASSIC); + assertEquals(tokens.size(), 1); + assertEquals(tokens.get(0).type, Token.LATIN); + + tokens = HanziToPinyin.getInstance().get(ONE_UNKNOWN); + assertEquals(tokens.size(), 1); + assertEquals(tokens.get(0).type, Token.UNKNOWN); + + tokens = HanziToPinyin.getInstance().get(MISC); + assertEquals(tokens.size(), 7); + assertEquals(tokens.get(0).type, Token.LATIN); + assertEquals(tokens.get(1).type, Token.PINYIN); + assertEquals(tokens.get(2).type, Token.LATIN); + assertEquals(tokens.get(3).type, Token.LATIN); + assertEquals(tokens.get(4).type, Token.LATIN); + assertEquals(tokens.get(5).type, Token.UNKNOWN); + assertEquals(tokens.get(6).type, Token.PINYIN); + } +} |