Introduce 'Home' settings

Bug 9958444

Change-Id: I868f5b7aa6ae9273b725cb96e80821a82569e7e0
This commit is contained in:
Christopher Tate
2013-08-27 14:21:46 -07:00
parent 8b4cdbebcf
commit e238a47f5e
9 changed files with 425 additions and 9 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -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>

View File

@@ -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] -->

View File

@@ -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>

View File

@@ -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"

View File

@@ -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();
}
}
}
}

View File

@@ -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();