Tests for "feature" split APKs.
Adds a new "feature" split APK which contains code, new manifest
components, and its own set of split resources. Verify that code
and resources from both base and feature coexist, and that they can
interact with each other.
Bug: 16947729
Change-Id: I8cc1a6c3402ce994aacd9c103338393fb3d145f2
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index c8d84da..33531c8 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -34,6 +34,7 @@
CtsSplitApp_mips \
CtsSplitAppDiffVersion \
CtsSplitAppDiffCert \
+ CtsSplitAppFeature \
CtsTargetInstrumentationApp \
CtsUsePermissionDiffCert \
CtsWriteExternalStorageApp \
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
index 21a76bb..b9bc768 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
@@ -67,6 +67,9 @@
private static final String APK_DIFF_VERSION_v7 = "CtsSplitAppDiffVersion_v7.apk";
private static final String APK_DIFF_CERT_v7 = "CtsSplitAppDiffCert_v7.apk";
+ private static final String APK_FEATURE = "CtsSplitAppFeature.apk";
+ private static final String APK_FEATURE_v7 = "CtsSplitAppFeature_v7.apk";
+
private static final HashMap<String, String> ABI_TO_APK = new HashMap<>();
static {
@@ -238,8 +241,14 @@
new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
}
- public void testInheritNewSplit() throws Exception {
- // TODO: flesh out this test
+ public void testFeatureBase() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_FEATURE).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testFeatureBase");
+ }
+
+ public void testFeatureApi() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_FEATURE).addApk(APK_FEATURE_v7).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testFeatureApi");
}
public void testInheritUpdatedBase() throws Exception {
@@ -250,10 +259,6 @@
// TODO: flesh out this test
}
- public void testSplitOrdering() throws Exception {
- // TODO: flesh out this test
- }
-
class InstallMultiple {
private List<String> mArgs = new ArrayList<>();
private List<File> mApks = new ArrayList<>();
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
index fc24aee..bc3acaf 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
@@ -22,7 +22,7 @@
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsSplitApp
LOCAL_PACKAGE_SPLITS := mdpi-v4 hdpi-v4 xhdpi-v4 xxhdpi-v4 v7 fr de
@@ -47,7 +47,7 @@
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsSplitAppDiffVersion
LOCAL_PACKAGE_SPLITS := v7
@@ -70,7 +70,7 @@
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsSplitAppDiffCert
LOCAL_PACKAGE_SPLITS := v7
@@ -85,5 +85,5 @@
ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call all-makefiles-under,$(LOCAL_PATH)/libs)
+include $(LOCAL_PATH)/libs/Android.mk $(LOCAL_PATH)/feature/Android.mk
endif
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
new file mode 100644
index 0000000..9965f60
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2014 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := CtsSplitAppFeature
+LOCAL_PACKAGE_SPLITS := v7
+
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --version-name OneHundred --replace-version -c mdpi
+
+LOCAL_MODULE_TAGS := tests
+
+featureOf := CtsSplitApp
+featureOfApk := $(call intermediates-dir-for,APPS,$(featureOf))/package.apk
+localRStamp := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src/R.stamp
+$(localRStamp): $(featureOfApk)
+
+LOCAL_AAPT_FLAGS += --feature-of $(featureOfApk)
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/feature/AndroidManifest.xml
new file mode 100644
index 0000000..8ba3c2f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.cts.splitapp"
+ featureName="feature">
+
+ <!-- New permission should be ignored -->
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <!-- New application flag should be ignored -->
+ <application android:largeHeap="true">
+ <activity android:name=".FeatureActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ <meta-data android:name="android.service.wallpaper" android:resource="@xml/my_activity_meta" />
+ </activity>
+ <receiver android:name=".FeatureReceiver"
+ android:enabled="@bool/feature_receiver_enabled">
+ <intent-filter>
+ <action android:name="android.intent.action.DATE_CHANGED" />
+ </intent-filter>
+ </receiver>
+ <service android:name=".FeatureService">
+ <intent-filter>
+ <action android:name="com.android.cts.splitapp.service" />
+ </intent-filter>
+ </service>
+ <provider android:name=".FeatureProvider" android:authorities="com.android.cts.splitapp.provider" />
+ </application>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/dir/dirfile2.txt b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/dir/dirfile2.txt
new file mode 100644
index 0000000..c4a2fff
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/dir/dirfile2.txt
@@ -0,0 +1 @@
+DIRFILE2
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/file2.txt b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/file2.txt
new file mode 100644
index 0000000..d77231c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/file2.txt
@@ -0,0 +1 @@
+FILE2
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values-v7/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values-v7/values.xml
new file mode 100644
index 0000000..8d91234
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values-v7/values.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources>
+ <bool name="feature_receiver_enabled">false</bool>
+ <integer name="feature_integer">321</integer>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values/values.xml
new file mode 100644
index 0000000..7d670cf
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values/values.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources>
+ <bool name="feature_receiver_enabled">true</bool>
+ <string name="feature_string">red</string>
+ <integer name="feature_integer">123</integer>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureActivity.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureActivity.java
new file mode 100644
index 0000000..a4df004
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 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.cts.splitapp;
+
+import android.app.Activity;
+
+public class FeatureActivity extends Activity {
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureLogic.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureLogic.java
new file mode 100644
index 0000000..0481546
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureLogic.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.cts.splitapp;
+
+import android.util.Log;
+
+public class FeatureLogic {
+ private static final String TAG = "FeatureLogic";
+
+ public static int mult(int a, int b) {
+ Log.d(TAG, "FeatureLogic.mult(" + a + ", " + b + ")");
+ return a * b;
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureProvider.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureProvider.java
new file mode 100644
index 0000000..087aeb7
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureProvider.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 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.cts.splitapp;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+
+public class FeatureProvider extends ContentProvider {
+ private static final String TAG = "FeatureProvider";
+
+ public static boolean sCreated = false;
+
+ @Override
+ public boolean onCreate() {
+ Log.d(TAG, "FeatureProvider.onCreate()");
+
+ sCreated = true;
+
+ try {
+ // Just reach out and touch
+ final Class<?> test = Class.forName("com.android.cts.splitapp.SplitAppTest");
+ final Field touched = test.getDeclaredField("sFeatureTouched");
+ touched.set(null, true);
+
+ // Also make sure we can read a resource from the base; we just
+ // stash the value we saw over on the test for them to verify.
+ final Class<?> baseR = Class.forName("com.android.cts.splitapp.BaseR");
+ final int stringId = (int) baseR.getDeclaredField("my_string1").get(null);
+ final Field value = test.getDeclaredField("sFeatureValue");
+ value.set(null, getContext().getResources().getString(stringId));
+
+ } catch (Throwable t) {
+ // We're okay if anything above fails, since the test later verifies
+ // that we actually touched the boolean.
+ Log.e(TAG, "Failed to communicate back to base", t);
+ }
+
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureR.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureR.java
new file mode 100644
index 0000000..3dbd83b
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureR.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014 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.cts.splitapp;
+
+public class FeatureR {
+ public static final int feature_receiver_enabled = R.bool.feature_receiver_enabled;
+ public static final int feature_integer = R.integer.feature_integer;
+ public static final int feature_string = R.string.feature_string;
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureReceiver.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureReceiver.java
new file mode 100644
index 0000000..49559f3
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureReceiver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.cts.splitapp;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class FeatureReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Ignored
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureService.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureService.java
new file mode 100644
index 0000000..b07297f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureService.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 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.cts.splitapp;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+public class FeatureService extends IntentService {
+ public FeatureService() {
+ super("Feature1Service");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // Ignored
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseR.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseR.java
new file mode 100644
index 0000000..ecf6975
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseR.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014 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.cts.splitapp;
+
+public class BaseR {
+ public static final int my_string1 = R.string.my_string1;
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
index 9eb17cd..277a1a2 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
@@ -20,7 +20,9 @@
import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -37,11 +39,17 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.List;
import java.util.Locale;
public class SplitAppTest extends AndroidTestCase {
private static final String TAG = "SplitAppTest";
+ private static final String PKG = "com.android.cts.splitapp";
+
+ public static boolean sFeatureTouched = false;
+ public static String sFeatureValue = null;
public void testSingleBase() throws Exception {
final Resources r = getContext().getResources();
@@ -78,7 +86,7 @@
// Should only have base manifest items
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
- intent.setPackage("com.android.cts.splitapp");
+ intent.setPackage(PKG);
List<ResolveInfo> result = pm.queryIntentActivities(intent, 0);
assertEquals(1, result.size());
@@ -86,7 +94,7 @@
// Receiver disabled by default in base
intent = new Intent(Intent.ACTION_DATE_CHANGED);
- intent.setPackage("com.android.cts.splitapp");
+ intent.setPackage(PKG);
result = pm.queryBroadcastReceivers(intent, 0);
assertEquals(0, result.size());
@@ -157,7 +165,7 @@
// Receiver should be enabled now
Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
- intent.setPackage("com.android.cts.splitapp");
+ intent.setPackage(PKG);
List<ResolveInfo> result = pm.queryBroadcastReceivers(intent, 0);
assertEquals(1, result.size());
@@ -187,6 +195,121 @@
assertEquals(11642, Native.add(4933, 6709));
}
+ public void testFeatureBase() throws Exception {
+ final Resources r = getContext().getResources();
+ final PackageManager pm = getContext().getPackageManager();
+
+ // Should have untouched resources from base
+ assertEquals(false, r.getBoolean(R.bool.my_receiver_enabled));
+
+ assertEquals("blue", r.getString(R.string.my_string1));
+ assertEquals("purple", r.getString(R.string.my_string2));
+
+ assertEquals(0xff00ff00, r.getColor(R.color.my_color));
+ assertEquals(123, r.getInteger(R.integer.my_integer));
+
+ assertEquals("base", getXmlTestValue(r.getXml(R.xml.my_activity_meta)));
+
+ // And that we can access resources from feature
+ // TODO: enable these once 17924027 is fixed
+// assertEquals("red", r.getString(r.getIdentifier("feature_string", "string", PKG)));
+// assertEquals(123, r.getInteger(r.getIdentifier("feature_integer", "integer", PKG)));
+
+ final Class<?> featR = Class.forName("com.android.cts.splitapp.FeatureR");
+ final int boolId = (int) featR.getDeclaredField("feature_receiver_enabled").get(null);
+ final int intId = (int) featR.getDeclaredField("feature_integer").get(null);
+ final int stringId = (int) featR.getDeclaredField("feature_string").get(null);
+ assertEquals(true, r.getBoolean(boolId));
+ assertEquals(123, r.getInteger(intId));
+ assertEquals("red", r.getString(stringId));
+
+ // Should have both base and feature assets
+ assertAssetContents(r, "file1.txt", "FILE1");
+ assertAssetContents(r, "file2.txt", "FILE2");
+ assertAssetContents(r, "dir/dirfile1.txt", "DIRFILE1");
+ assertAssetContents(r, "dir/dirfile2.txt", "DIRFILE2");
+
+ // Should have both base and feature components
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setPackage(PKG);
+ List<ResolveInfo> result = pm.queryIntentActivities(intent, 0);
+ assertEquals(2, result.size());
+ assertEquals("com.android.cts.splitapp.MyActivity", result.get(0).activityInfo.name);
+ assertEquals("com.android.cts.splitapp.FeatureActivity", result.get(1).activityInfo.name);
+
+ // Receiver only enabled in feature
+ intent = new Intent(Intent.ACTION_DATE_CHANGED);
+ intent.setPackage(PKG);
+ result = pm.queryBroadcastReceivers(intent, 0);
+ assertEquals(1, result.size());
+ assertEquals("com.android.cts.splitapp.FeatureReceiver", result.get(0).activityInfo.name);
+
+ // And we should have a service
+ intent = new Intent("com.android.cts.splitapp.service");
+ intent.setPackage(PKG);
+ result = pm.queryIntentServices(intent, 0);
+ assertEquals(1, result.size());
+ assertEquals("com.android.cts.splitapp.FeatureService", result.get(0).serviceInfo.name);
+
+ // And a provider too
+ ProviderInfo info = pm.resolveContentProvider("com.android.cts.splitapp.provider", 0);
+ assertEquals("com.android.cts.splitapp.FeatureProvider", info.name);
+
+ // And assert that we spun up the provider in this process
+ final Class<?> provider = Class.forName("com.android.cts.splitapp.FeatureProvider");
+ final Field field = provider.getDeclaredField("sCreated");
+ assertTrue("Expected provider to have been created", (boolean) field.get(null));
+ assertTrue("Expected provider to have touched us", sFeatureTouched);
+ assertEquals(r.getString(R.string.my_string1), sFeatureValue);
+
+ // Finally ensure that we can execute some code from split
+ final Class<?> logic = Class.forName("com.android.cts.splitapp.FeatureLogic");
+ final Method method = logic.getDeclaredMethod("mult", new Class[] {
+ Integer.TYPE, Integer.TYPE });
+ assertEquals(72, (int) method.invoke(null, 12, 6));
+
+ // Make sure we didn't get an extra flag from feature split
+ assertTrue("Someone parsed application flag!",
+ (getContext().getApplicationInfo().flags & ApplicationInfo.FLAG_LARGE_HEAP) == 0);
+
+ // Make sure we have permission from base APK
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.CAMERA, null);
+
+ try {
+ // But no new permissions from the feature APK
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, null);
+ fail("Whaaa, we somehow gained permission from feature?");
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testFeatureApi() throws Exception {
+ final Resources r = getContext().getResources();
+ final PackageManager pm = getContext().getPackageManager();
+
+ // Should have untouched resources from base
+ assertEquals(false, r.getBoolean(R.bool.my_receiver_enabled));
+
+ // And that we can access resources from feature
+ // TODO: enable these once 17924027 is fixed
+// assertEquals(321, r.getInteger(r.getIdentifier("feature_integer", "integer", PKG)));
+
+ final Class<?> featR = Class.forName("com.android.cts.splitapp.FeatureR");
+ final int boolId = (int) featR.getDeclaredField("feature_receiver_enabled").get(null);
+ final int intId = (int) featR.getDeclaredField("feature_integer").get(null);
+ final int stringId = (int) featR.getDeclaredField("feature_string").get(null);
+ assertEquals(false, r.getBoolean(boolId));
+ assertEquals(321, r.getInteger(intId));
+ assertEquals("red", r.getString(stringId));
+
+ // And now both receivers should be disabled
+ Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
+ intent.setPackage(PKG);
+ List<ResolveInfo> result = pm.queryBroadcastReceivers(intent, 0);
+ assertEquals(0, result.size());
+ }
+
private static void updateDpi(Resources r, int densityDpi) {
final Configuration c = new Configuration(r.getConfiguration());
c.densityDpi = densityDpi;