diff options
-rw-r--r-- | res/drawable-hdpi/ic_settings_home.png | bin | 0 -> 1370 bytes | |||
-rw-r--r-- | res/drawable-mdpi/ic_settings_home.png | bin | 0 -> 788 bytes | |||
-rw-r--r-- | res/drawable-xhdpi/ic_settings_home.png | bin | 0 -> 1888 bytes | |||
-rw-r--r-- | res/layout/preference_home_app.xml | 80 | ||||
-rw-r--r-- | res/values/strings.xml | 4 | ||||
-rw-r--r-- | res/xml/home_selection.xml | 23 | ||||
-rw-r--r-- | res/xml/settings_headers.xml | 7 | ||||
-rw-r--r-- | src/com/android/settings/HomeSettings.java | 243 | ||||
-rw-r--r-- | src/com/android/settings/Settings.java | 77 |
9 files changed, 425 insertions, 9 deletions
diff --git a/res/drawable-hdpi/ic_settings_home.png b/res/drawable-hdpi/ic_settings_home.png Binary files differnew file mode 100644 index 0000000..42354cd --- /dev/null +++ b/res/drawable-hdpi/ic_settings_home.png diff --git a/res/drawable-mdpi/ic_settings_home.png b/res/drawable-mdpi/ic_settings_home.png Binary files differnew file mode 100644 index 0000000..8064773 --- /dev/null +++ b/res/drawable-mdpi/ic_settings_home.png diff --git a/res/drawable-xhdpi/ic_settings_home.png b/res/drawable-xhdpi/ic_settings_home.png Binary files differnew file mode 100644 index 0000000..687025d --- /dev/null +++ b/res/drawable-xhdpi/ic_settings_home.png diff --git a/res/layout/preference_home_app.xml b/res/layout/preference_home_app.xml new file mode 100644 index 0000000..8418161 --- /dev/null +++ b/res/layout/preference_home_app.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 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:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeight" + android:gravity="center_vertical" + android:paddingStart="@*android:dimen/preference_item_padding_side"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_weight="1" + android:id="@+id/home_app_pref" + android:focusable="true" + android:clickable="true" + android:gravity="center_vertical" + android:background="?android:attr/selectableItemBackground" > + <RadioButton + android:id="@+id/home_radio" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_marginStart="10dip" + android:layout_marginEnd="4dip" + android:layout_gravity="center_vertical" + android:orientation="vertical" + android:clickable="false" + android:focusable="false" /> + <ImageView + android:id="@+android:id/icon" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_gravity="center" + android:minWidth="48dp" + android:scaleType="centerInside" + android:layout_marginEnd="@*android:dimen/preference_item_padding_inner" + /> + <TextView + android:id="@+android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:layout_weight="1" + android:textAppearance="?android:attr/textAppearanceMedium" + android:ellipsize="end" /> + </LinearLayout> + <View + android:id="@+id/home_divider" + android:layout_width="2dip" + android:layout_height="match_parent" + android:layout_marginTop="5dip" + android:layout_marginBottom="5dip" + android:background="@android:drawable/divider_horizontal_dark" /> + <ImageView + android:id="@+id/home_app_uninstall" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:paddingStart="12dip" + android:paddingEnd="12dp" + android:src="@drawable/ic_menu_delete_holo_dark" + android:contentDescription="@string/home_app_uninstall_button" + android:layout_gravity="center" + android:clickable="true" + android:focusable="true" + android:background="?android:attr/selectableItemBackground" /> +</LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index 8ffa17f..ad3e5be 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1732,6 +1732,7 @@ <!-- Sound and alerts settings --> <skip/> <!-- Main Settings screen setting option name to go into the display settings screen --> + <string name="home_settings">Home</string> <string name="display_settings_title">Display</string> <!-- Sound settings screen heading --> <string name="sound_settings">Sound</string> @@ -4667,6 +4668,9 @@ <!-- Applicaitons with restrictions - settings button [CHAR LIMIT=30] --> <string name="apps_with_restrictions_settings_button">Expand settings for application</string> + <!-- Home application selection - uninstall button [CHAR LIMIT=80] --> + <string name="home_app_uninstall_button">Uninstall this application</string> + <!-- Warning message when changing a global setting for a tablet.[CHAR LIMIT=none] --> <string name="global_change_warning" product="tablet">This setting affects all users on this tablet.</string> <!-- Warning message when changing a global setting for a phone.[CHAR LIMIT=none] --> diff --git a/res/xml/home_selection.xml b/res/xml/home_selection.xml new file mode 100644 index 0000000..a348f9d --- /dev/null +++ b/res/xml/home_selection.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 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. +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:title="@string/home_settings" + xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" + android:key="home" + android:order="0"> + +</PreferenceScreen> diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml index 6aa6691..55b3bca 100644 --- a/res/xml/settings_headers.xml +++ b/res/xml/settings_headers.xml @@ -62,6 +62,13 @@ <header android:id="@+id/device_section" android:title="@string/header_category_device" /> + <!-- Home --> + <header + android:id="@+id/home_settings" + android:icon="@drawable/ic_settings_home" + android:fragment="com.android.settings.HomeSettings" + android:title="@string/home_settings" /> + <!-- Sound --> <header android:id="@+id/sound_settings" diff --git a/src/com/android/settings/HomeSettings.java b/src/com/android/settings/HomeSettings.java new file mode 100644 index 0000000..6d937fd --- /dev/null +++ b/src/com/android/settings/HomeSettings.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2013 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 java.util.ArrayList; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.preference.Preference; +import android.preference.PreferenceGroup; +import android.util.Log; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; +import android.widget.RadioButton; + +public class HomeSettings extends SettingsPreferenceFragment { + static final String TAG = "HomeSettings"; + + static final int REQUESTING_UNINSTALL = 10; + + public static final String CURRENT_HOME = "current_home"; + + PreferenceGroup mPrefGroup; + + PackageManager mPm; + ComponentName[] mHomeComponentSet; + ArrayList<HomeAppPreference> mPrefs; + HomeAppPreference mCurrentHome = null; + final IntentFilter mHomeFilter; + + public HomeSettings() { + mHomeFilter = new IntentFilter(Intent.ACTION_MAIN); + mHomeFilter.addCategory(Intent.CATEGORY_HOME); + mHomeFilter.addCategory(Intent.CATEGORY_DEFAULT); + } + + OnClickListener mHomeClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + int index = (Integer)v.getTag(); + HomeAppPreference pref = mPrefs.get(index); + if (!pref.isChecked) { + makeCurrentHome(pref); + } + } + }; + + OnClickListener mDeleteClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + int index = (Integer)v.getTag(); + uninstallApp(mPrefs.get(index)); + } + }; + + void makeCurrentHome(HomeAppPreference newHome) { + if (mCurrentHome != null) { + mCurrentHome.setChecked(false); + } + newHome.setChecked(true); + mCurrentHome = newHome; + + mPm.replacePreferredActivity(mHomeFilter, IntentFilter.MATCH_CATEGORY_EMPTY, + mHomeComponentSet, newHome.activityName); + } + + void uninstallApp(HomeAppPreference pref) { + // Uninstallation is done by asking the OS to do it + Uri packageURI = Uri.parse("package:" + pref.activityName.getPackageName()); + Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI); + uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); + int requestCode = REQUESTING_UNINSTALL + (pref.isChecked ? 1 : 0); + startActivityForResult(uninstallIntent, requestCode); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + // Rebuild the list now that we might have nuked something + buildHomeActivitiesList(); + + // if the previous home app is now gone, fall back to the system one + if (requestCode > REQUESTING_UNINSTALL) { + // if mCurrentHome has gone null, it means we didn't find the previously- + // default home app when rebuilding the list, i.e. it was the one we + // just uninstalled. When that happens we make the system-bundled + // home app the active default. + if (mCurrentHome == null) { + for (int i = 0; i < mPrefs.size(); i++) { + HomeAppPreference pref = mPrefs.get(i); + if (pref.isSystem) { + makeCurrentHome(pref); + break; + } + } + } + } + } + + void buildHomeActivitiesList() { + ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); + ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); + + Context context = getActivity(); + mCurrentHome = null; + mPrefGroup.removeAll(); + mPrefs = new ArrayList<HomeAppPreference>(); + mHomeComponentSet = new ComponentName[homeActivities.size()]; + int prefIndex = 0; + for (int i = 0; i < homeActivities.size(); i++) { + final ResolveInfo candidate = homeActivities.get(i); + final ActivityInfo info = candidate.activityInfo; + ComponentName activityName = new ComponentName(info.packageName, info.name); + mHomeComponentSet[i] = activityName; + try { + Drawable icon = info.loadIcon(mPm); + CharSequence name = info.loadLabel(mPm); + boolean isSystem = (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + HomeAppPreference pref = new HomeAppPreference(context, activityName, prefIndex, + icon, name, this, isSystem); + mPrefs.add(pref); + mPrefGroup.addPreference(pref); + pref.setEnabled(true); + if (activityName.equals(currentDefaultHome)) { + mCurrentHome = pref; + } + prefIndex++; + } catch (Exception e) { + Log.v(TAG, "Problem dealing with activity " + activityName, e); + } + } + + if (mCurrentHome != null) { + new Handler().post(new Runnable() { + public void run() { + mCurrentHome.setChecked(true); + } + }); + } + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.home_selection); + + mPm = getPackageManager(); + mPrefGroup = (PreferenceGroup) findPreference("home"); + } + + @Override + public void onResume() { + super.onResume(); + buildHomeActivitiesList(); + } + + class HomeAppPreference extends Preference { + ComponentName activityName; + int index; + boolean isSystem; + HomeSettings fragment; + final ColorFilter grayscaleFilter; + boolean isChecked; + + public HomeAppPreference(Context context, ComponentName activity, + int i, Drawable icon, CharSequence title, + HomeSettings parent, boolean sys) { + super(context); + setLayoutResource(R.layout.preference_home_app); + setIcon(icon); + setTitle(title); + activityName = activity; + fragment = parent; + index = i; + isSystem = sys; + + ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.setSaturation(0f); + float[] matrix = colorMatrix.getArray(); + matrix[18] = 0.5f; + grayscaleFilter = new ColorMatrixColorFilter(colorMatrix); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + + RadioButton radio = (RadioButton) view.findViewById(R.id.home_radio); + radio.setChecked(isChecked); + + Integer indexObj = new Integer(index); + + ImageView icon = (ImageView) view.findViewById(R.id.home_app_uninstall); + if (isSystem) { + icon.setEnabled(false); + icon.setColorFilter(grayscaleFilter); + } else { + icon.setOnClickListener(mDeleteClickListener); + icon.setTag(indexObj); + } + + View v = view.findViewById(R.id.home_app_pref); + v.setOnClickListener(mHomeClickListener); + v.setTag(indexObj); + } + + void setChecked(boolean state) { + if (state != isChecked) { + isChecked = state; + notifyChanged(); + } + } + } +} diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index e754f98..bcfffcb 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -26,8 +26,10 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.INetworkManagementService; @@ -144,7 +146,8 @@ public class Settings extends PreferenceActivity R.id.about_settings, R.id.accessibility_settings, R.id.print_settings, - R.id.nfc_payment_settings + R.id.nfc_payment_settings, + R.id.home_settings }; private SharedPreferences mDevelopmentPreferences; @@ -558,6 +561,8 @@ public class Settings extends PreferenceActivity } else if (id == R.id.account_settings) { int headerIndex = i + 1; i = insertAccountsHeaders(target, headerIndex); + } else if (id == R.id.home_settings) { + updateHomeSettingHeaders(header); } else if (id == R.id.user_settings) { if (!UserHandle.MU_ENABLED || !UserManager.supportsMultipleUsers() @@ -658,6 +663,51 @@ public class Settings extends PreferenceActivity return headerIndex; } + private boolean isSystemApp(ResolveInfo ri) { + return ((ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); + } + + private void updateHomeSettingHeaders(Header header) { + final PackageManager pm = getPackageManager(); + final ArrayList<ResolveInfo> homeApps = new ArrayList<ResolveInfo>(); + try { + ComponentName currentHome = pm.getHomeActivities(homeApps); + ResolveInfo iconSource = null; + if (currentHome == null) { + // no current default, so find the system home app and use that + for (int which = 0; which < homeApps.size(); which++) { + ResolveInfo ri = homeApps.get(which); + if (isSystemApp(ri)) { + iconSource = ri; + break; + } + } + } else { + // find the current-home entry in the returned set + for (int which = 0; which < homeApps.size(); which++) { + ResolveInfo ri = homeApps.get(which); + ComponentName riName = new ComponentName(ri.activityInfo.packageName, + ri.activityInfo.name); + if (riName.equals(currentHome)) { + iconSource = ri; + break; + } + } + } + if (iconSource != null) { + if (header.extras == null) { + header.extras = new Bundle(); + } + header.extras.putParcelable(HomeSettings.CURRENT_HOME, iconSource.activityInfo); + } else { + Log.v(LOG_TAG, "No home app icon found"); + } + } catch (Exception e) { + // Can't look up the home activity; bail on configuring the icon + Log.w(LOG_TAG, "Problem looking up home activity!", e); + } + } + private void getMetaData() { try { ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(), @@ -820,17 +870,17 @@ public class Settings extends PreferenceActivity //$FALL-THROUGH$ case HEADER_TYPE_NORMAL: - if (header.extras != null - && header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) { + if (header.extras != null && + header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) { String accType = header.extras.getString( ManageAccountsSettings.KEY_ACCOUNT_TYPE); - ViewGroup.LayoutParams lp = holder.icon.getLayoutParams(); - lp.width = getContext().getResources().getDimensionPixelSize( - R.dimen.header_icon_width); - lp.height = lp.width; - holder.icon.setLayoutParams(lp); Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType); - holder.icon.setImageDrawable(icon); + setHeaderIcon(holder, icon); + } else if (header.extras != null && + header.extras.containsKey(HomeSettings.CURRENT_HOME)) { + ActivityInfo ai = header.extras.getParcelable(HomeSettings.CURRENT_HOME); + Drawable icon = ai.loadIcon(getContext().getPackageManager()); + setHeaderIcon(holder, icon); } else { holder.icon.setImageResource(header.iconRes); } @@ -848,6 +898,15 @@ public class Settings extends PreferenceActivity return view; } + private void setHeaderIcon(HeaderViewHolder holder, Drawable icon) { + ViewGroup.LayoutParams lp = holder.icon.getLayoutParams(); + lp.width = getContext().getResources().getDimensionPixelSize( + R.dimen.header_icon_width); + lp.height = lp.width; + holder.icon.setLayoutParams(lp); + holder.icon.setImageDrawable(icon); + } + public void resume() { mWifiEnabler.resume(); mBluetoothEnabler.resume(); |