summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/xml/settings.xml14
-rw-r--r--src/com/android/settings/IconPreferenceScreen.java23
-rw-r--r--src/com/android/settings/Settings.java8
-rw-r--r--src/com/android/settings/Utils.java113
-rw-r--r--tests/AndroidManifest.xml21
-rwxr-xr-xtests/res/drawable/ic_settings_applications.pngbin0 -> 1723 bytes
-rw-r--r--tests/res/layout/manufacturer_main.xml22
-rw-r--r--tests/res/layout/operator_main.xml22
-rw-r--r--tests/res/values/strings.xml6
-rw-r--r--tests/src/com/android/settings/SettingsHookTests.java137
-rw-r--r--tests/src/com/android/settings/tests/Manufacturer.java29
-rw-r--r--tests/src/com/android/settings/tests/Operator.java30
12 files changed, 424 insertions, 1 deletions
diff --git a/res/xml/settings.xml b/res/xml/settings.xml
index 22f2523..add38da 100644
--- a/res/xml/settings.xml
+++ b/res/xml/settings.xml
@@ -20,6 +20,20 @@
android:title="@string/settings_label"
android:key="parent">
+ <!-- Operator hook -->
+
+ <com.android.settings.IconPreferenceScreen
+ android:key="operator_settings">
+ <intent android:action="com.android.settings.OPERATOR_APPLICATION_SETTING" />
+ </com.android.settings.IconPreferenceScreen>
+
+ <!-- Manufacturer hook -->
+
+ <com.android.settings.IconPreferenceScreen
+ android:key="manufacturer_settings">
+ <intent android:action="com.android.settings.MANUFACTURER_APPLICATION_SETTING" />
+ </com.android.settings.IconPreferenceScreen>
+
<com.android.settings.IconPreferenceScreen
android:title="@string/radio_controls_title"
settings:icon="@drawable/ic_settings_wireless">
diff --git a/src/com/android/settings/IconPreferenceScreen.java b/src/com/android/settings/IconPreferenceScreen.java
index c7c5303..31abf0a 100644
--- a/src/com/android/settings/IconPreferenceScreen.java
+++ b/src/com/android/settings/IconPreferenceScreen.java
@@ -22,6 +22,7 @@ import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.ImageView;
public class IconPreferenceScreen extends Preference {
@@ -48,4 +49,26 @@ public class IconPreferenceScreen extends Preference {
imageView.setImageDrawable(mIcon);
}
}
+
+ /**
+ * Sets the icon for this Preference with a Drawable.
+ *
+ * @param icon The icon for this Preference
+ */
+ public void setIcon(Drawable icon) {
+ if ((icon == null && mIcon != null) || (icon != null && !icon.equals(mIcon))) {
+ mIcon = icon;
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Returns the icon of this Preference.
+ *
+ * @return The icon.
+ * @see #setIcon(Drawable)
+ */
+ public Drawable getIcon() {
+ return mIcon;
+ }
}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 5309cf5..c53c2fa 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -30,6 +30,9 @@ public class Settings extends PreferenceActivity {
private static final String KEY_SEARCH_SETTINGS = "search_settings";
private static final String KEY_DOCK_SETTINGS = "dock_settings";
+ private static final String KEY_OPERATOR_SETTINGS = "operator_settings";
+ private static final String KEY_MANUFACTURER_SETTINGS = "manufacturer_settings";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -46,6 +49,11 @@ public class Settings extends PreferenceActivity {
if (getResources().getBoolean(R.bool.has_dock_settings) == false && dockSettings != null) {
parent.removePreference(dockSettings);
}
+
+ Utils.updatePreferenceToSpecificActivityFromMetaDataOrRemove(this, parent,
+ KEY_OPERATOR_SETTINGS);
+ Utils.updatePreferenceToSpecificActivityFromMetaDataOrRemove(this, parent,
+ KEY_MANUFACTURER_SETTINGS);
}
@Override
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index d4f1f11..b29ec06 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -22,8 +22,14 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.SystemProperties;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceGroup;
+import android.text.TextUtils;
import java.util.List;
@@ -35,6 +41,24 @@ public class Utils {
public static final int UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY = 1;
/**
+ * Name of the meta-data item that should be set in the AndroidManifest.xml
+ * to specify the icon that should be displayed for the preference.
+ */
+ private static final String META_DATA_PREFERENCE_ICON = "com.android.settings.icon";
+
+ /**
+ * Name of the meta-data item that should be set in the AndroidManifest.xml
+ * to specify the title that should be displayed for the preference.
+ */
+ private static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+
+ /**
+ * Name of the meta-data item that should be set in the AndroidManifest.xml
+ * to specify the summary text that should be displayed for the preference.
+ */
+ private static final String META_DATA_PREFERENCE_SUMMARY = "com.android.settings.summary";
+
+ /**
* Finds a matching activity for a preference's intent. If a matching
* activity is not found, it will remove the preference.
*
@@ -90,10 +114,97 @@ public class Utils {
}
/**
+ * Finds a matching activity for a preference's intent. If a matching
+ * activity is not found, it will remove the preference. The icon, title and
+ * summary of the preference will also be updated with the values retrieved
+ * from the activity's meta-data elements. If no meta-data elements are
+ * specified then the preference title will be set to match the label of the
+ * activity, an icon and summary text will not be displayed.
+ *
+ * @param context The context.
+ * @param parentPreferenceGroup The preference group that contains the
+ * preference whose intent is being resolved.
+ * @param preferenceKey The key of the preference whose intent is being
+ * resolved.
+ *
+ * @return Whether an activity was found. If false, the preference was
+ * removed.
+ *
+ * @see {@link #META_DATA_PREFERENCE_ICON}
+ * {@link #META_DATA_PREFERENCE_TITLE}
+ * {@link #META_DATA_PREFERENCE_SUMMARY}
+ */
+ public static boolean updatePreferenceToSpecificActivityFromMetaDataOrRemove(Context context,
+ PreferenceGroup parentPreferenceGroup, String preferenceKey) {
+
+ IconPreferenceScreen preference = (IconPreferenceScreen)parentPreferenceGroup
+ .findPreference(preferenceKey);
+ if (preference == null) {
+ return false;
+ }
+
+ Intent intent = preference.getIntent();
+ if (intent != null) {
+ // Find the activity that is in the system image
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> list = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
+ int listSize = list.size();
+ for (int i = 0; i < listSize; i++) {
+ ResolveInfo resolveInfo = list.get(i);
+ if ((resolveInfo.activityInfo.applicationInfo.flags
+ & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ Drawable icon = null;
+ String title = null;
+ String summary = null;
+
+ // Get the activity's meta-data
+ try {
+ Resources res = pm
+ .getResourcesForApplication(resolveInfo.activityInfo.packageName);
+ Bundle metaData = resolveInfo.activityInfo.metaData;
+
+ if (res != null && metaData != null) {
+ icon = res.getDrawable(metaData.getInt(META_DATA_PREFERENCE_ICON));
+ title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
+ summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
+ }
+ } catch (NameNotFoundException e) {
+ // Ignore
+ } catch (NotFoundException e) {
+ // Ignore
+ }
+
+ // Set the preference title to the activity's label if no
+ // meta-data is found
+ if (TextUtils.isEmpty(title)) {
+ title = resolveInfo.loadLabel(pm).toString();
+ }
+
+ // Set icon, title and summary for the preference
+ preference.setIcon(icon);
+ preference.setTitle(title);
+ preference.setSummary(summary);
+
+ // Replace the intent with this specific activity
+ preference.setIntent(new Intent().setClassName(
+ resolveInfo.activityInfo.packageName,
+ resolveInfo.activityInfo.name));
+
+ return true;
+ }
+ }
+ }
+
+ // Did not find a matching activity, so remove the preference
+ parentPreferenceGroup.removePreference(preference);
+
+ return false;
+ }
+
+ /**
* Returns true if Monkey is running.
*/
public static boolean isMonkeyRunning() {
return SystemProperties.getBoolean("ro.monkey", false);
}
-
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 8a0ce21..fe4dd95 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -29,8 +29,29 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:name="Operator" android:label="Operator Hook Test" >
+ <intent-filter>
+ <action android:name="com.android.settings.OPERATOR_APPLICATION_SETTING" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.title" android:resource="@string/operator_settings_title" />
+ <meta-data android:name="com.android.settings.summary" android:resource="@string/operator_settings_summary" />
+ <meta-data android:name="com.android.settings.icon" android:resource="@drawable/ic_settings_applications" />
+ </activity>
+ <activity android:name="Manufacturer" android:label="Manufacturer Hook Test" >
+ <intent-filter>
+ <action android:name="com.android.settings.MANUFACTURER_APPLICATION_SETTING" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.title" android:resource="@string/manufacturer_settings_title" />
+ <meta-data android:name="com.android.settings.summary" android:resource="@string/manufacturer_settings_summary" />
+ <meta-data android:name="com.android.settings.icon" android:resource="@drawable/ic_settings_applications" />
+ </activity>
</application>
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.settings"
+ android:label="Settings App Tests">
+ </instrumentation>
+
<instrumentation android:name="SettingsLaunchPerformance"
android:targetPackage="com.android.settings"
android:label="Settings Launch Performance">
diff --git a/tests/res/drawable/ic_settings_applications.png b/tests/res/drawable/ic_settings_applications.png
new file mode 100755
index 0000000..5cea33f
--- /dev/null
+++ b/tests/res/drawable/ic_settings_applications.png
Binary files differ
diff --git a/tests/res/layout/manufacturer_main.xml b/tests/res/layout/manufacturer_main.xml
new file mode 100644
index 0000000..8f8c48f
--- /dev/null
+++ b/tests/res/layout/manufacturer_main.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <TextView android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="@string/manufacturer_hello" />
+</LinearLayout>
diff --git a/tests/res/layout/operator_main.xml b/tests/res/layout/operator_main.xml
new file mode 100644
index 0000000..3cf8e00
--- /dev/null
+++ b/tests/res/layout/operator_main.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <TextView android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="@string/operator_hello" />
+</LinearLayout>
diff --git a/tests/res/values/strings.xml b/tests/res/values/strings.xml
index b06782f..cd94a2d 100644
--- a/tests/res/values/strings.xml
+++ b/tests/res/values/strings.xml
@@ -20,4 +20,10 @@
<!-- Test only. Do not translate. -->
<string name="enable">Enable</string>
<string name="discoverable">Discoverable</string>
+ <string name="operator_hello">Hello Operator!</string>
+ <string name="operator_settings_title">Operator</string>
+ <string name="operator_settings_summary">Operator hook that can be used to start activity of choice</string>
+ <string name="manufacturer_hello">Hello Manufacturer!</string>
+ <string name="manufacturer_settings_title">Manufacturer</string>
+ <string name="manufacturer_settings_summary">Manufacturer hook that can be used to start activity of choice</string>
</resources>
diff --git a/tests/src/com/android/settings/SettingsHookTests.java b/tests/src/com/android/settings/SettingsHookTests.java
new file mode 100644
index 0000000..b14e5bc
--- /dev/null
+++ b/tests/src/com/android/settings/SettingsHookTests.java
@@ -0,0 +1,137 @@
+/*
+ * 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.settings;
+
+import com.android.settings.tests.Manufacturer;
+import com.android.settings.tests.Operator;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceGroup;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.util.List;
+
+/**
+ * Tests for the Settings operator/manufacturer hook.
+ *
+ * Running all tests:
+ *
+ * make SettingsTests
+ * adb push SettingsTests.apk /system/app/SettingsTests.apk
+ * adb shell am instrument \
+ * -w com.android.settings.tests/android.test.InstrumentationTestRunner
+ */
+public class SettingsHookTests extends ActivityInstrumentationTestCase2<Settings> {
+
+ private static final String PACKAGE_NAME = "com.android.settings.tests";
+
+ private static final String KEY_SETTINGS_ROOT = "parent";
+ private static final String KEY_SETTINGS_OPERATOR = "operator_settings";
+ private static final String KEY_SETTINGS_MANUFACTURER = "manufacturer_settings";
+
+ private static final String INTENT_OPERATOR_HOOK = "com.android.settings.OPERATOR_APPLICATION_SETTING";
+ private static final String INTENT_MANUFACTURER_HOOK = "com.android.settings.MANUFACTURER_APPLICATION_SETTING";
+
+ private Settings mSettings;
+
+ public SettingsHookTests() {
+ super("com.android.settings", Settings.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mSettings = getActivity();
+ }
+
+ /**
+ * Test that the operator/manufacturer settings hook test application is
+ * available and that it's installed in the device's system image.
+ */
+ public void testSettingsHookTestAppAvailable() throws Exception {
+ Context context = mSettings.getApplicationContext();
+ PackageManager pm = context.getPackageManager();
+ ApplicationInfo applicationInfo = pm.getApplicationInfo(PACKAGE_NAME, 0);
+ assertTrue((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
+ }
+
+ /**
+ * Test that the operator test activity has registered an intent-filter for
+ * an action named 'android.settings.OPERATOR_APPLICATION_SETTING'.
+ */
+ public void testOperatorIntentFilter() {
+ boolean result = false;
+ Context context = mSettings.getApplicationContext();
+ PackageManager pm = context.getPackageManager();
+ Intent intent = new Intent(INTENT_OPERATOR_HOOK);
+ List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
+ for (ResolveInfo resolveInfo : list) {
+ if (resolveInfo.activityInfo.packageName.equals(PACKAGE_NAME)) {
+ result = true;
+ }
+ }
+ assertTrue("Intent-filer not found", result);
+ }
+
+ /**
+ * Test that the manufacturer test activity has registered an intent-filter
+ * for an action named 'android.settings.MANUFACTURER_APPLICATION_SETTING'.
+ */
+ public void testManufacturerIntentFilter() {
+ boolean result = false;
+ Context context = mSettings.getApplicationContext();
+ PackageManager pm = context.getPackageManager();
+ Intent intent = new Intent(INTENT_MANUFACTURER_HOOK);
+ List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
+ for (ResolveInfo resolveInfo : list) {
+ if (resolveInfo.activityInfo.packageName.equals(PACKAGE_NAME)) {
+ result = true;
+ }
+ }
+ assertTrue("Intent-filer not found", result);
+ }
+
+ /**
+ * Test that the operator preference is available in the Settings
+ * application.
+ */
+ public void testOperatorPreferenceAvailable() {
+ PreferenceGroup root = (PreferenceGroup)mSettings.findPreference(KEY_SETTINGS_ROOT);
+ Preference operatorPreference = root.findPreference(KEY_SETTINGS_OPERATOR);
+ assertNotNull(operatorPreference);
+ }
+
+ /**
+ * Test that the manufacturer preference is available in the Settings
+ * application.
+ */
+ public void testManufacturerPreferenceAvailable() {
+ PreferenceGroup root = (PreferenceGroup)mSettings.findPreference(KEY_SETTINGS_ROOT);
+ Preference manufacturerHook = root.findPreference(KEY_SETTINGS_MANUFACTURER);
+ assertNotNull(manufacturerHook);
+ }
+
+}
diff --git a/tests/src/com/android/settings/tests/Manufacturer.java b/tests/src/com/android/settings/tests/Manufacturer.java
new file mode 100644
index 0000000..692e6a8
--- /dev/null
+++ b/tests/src/com/android/settings/tests/Manufacturer.java
@@ -0,0 +1,29 @@
+/*
+ * 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.settings.tests;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Manufacturer extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.manufacturer_main);
+ }
+}
diff --git a/tests/src/com/android/settings/tests/Operator.java b/tests/src/com/android/settings/tests/Operator.java
new file mode 100644
index 0000000..8a34363
--- /dev/null
+++ b/tests/src/com/android/settings/tests/Operator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.settings.tests;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Operator extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.operator_main);
+ }
+
+}