From e238a47f5ea6de128cf76eca8ad2b852cb12f4a0 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 27 Aug 2013 14:21:46 -0700 Subject: [PATCH] Introduce 'Home' settings Bug 9958444 Change-Id: I868f5b7aa6ae9273b725cb96e80821a82569e7e0 --- res/drawable-hdpi/ic_settings_home.png | Bin 0 -> 1370 bytes res/drawable-mdpi/ic_settings_home.png | Bin 0 -> 788 bytes res/drawable-xhdpi/ic_settings_home.png | Bin 0 -> 1888 bytes res/layout/preference_home_app.xml | 80 +++++++ res/values/strings.xml | 4 + res/xml/home_selection.xml | 23 ++ res/xml/settings_headers.xml | 7 + src/com/android/settings/HomeSettings.java | 243 +++++++++++++++++++++ src/com/android/settings/Settings.java | 77 ++++++- 9 files changed, 425 insertions(+), 9 deletions(-) create mode 100644 res/drawable-hdpi/ic_settings_home.png create mode 100644 res/drawable-mdpi/ic_settings_home.png create mode 100644 res/drawable-xhdpi/ic_settings_home.png create mode 100644 res/layout/preference_home_app.xml create mode 100644 res/xml/home_selection.xml create mode 100644 src/com/android/settings/HomeSettings.java diff --git a/res/drawable-hdpi/ic_settings_home.png b/res/drawable-hdpi/ic_settings_home.png new file mode 100644 index 0000000000000000000000000000000000000000..42354cd7c2fc25cfd5e05081c4fb615aadae3445 GIT binary patch literal 1370 zcmV-g1*Q6lP)1{Oe(dAv=t0-08KF%V@QlTQlm%{6Cq3t0|!_WjWY)( zCXhHVac086IB=lB|Hj&cNSdevY=S|s3RtSr5)oUJ*C+R$^Eo*C-oE?ZyRY{J4HMSn zBxmonzO}#gXRpnh@BqhMxM9d@>*BK06)jw7>((x*PAVVFIcc(N#}?oI!(cR1`9ZA(Nz=U z&0zhko6P~r~4*bKl>_)5< z@J#{6ao9@6>(ST4vbvC3P5xJ#QdEAfY-xVgnPQ|Z@j9#1SH(Xl-oG|xe6t|`eWvja zCnxPTk0s>QtWfOSRfy3chbGKP@`T_*VgK z@No-{c@a0MJ?FwKiu!u}qSGPG;-ry!e0feuE=@sw zBRjgL?TwN=5Lt?RBgt)%dW~MMbv()EF5PLfg4t+P8eex@QyNEbeMy9C@gh=Yh{`~X zecp@5&{dlORO4J~wMK%^JFl4(&p~}3+H1wjy++l8k5u@Goqp%{J@jQ{LepmpJ#CUx z*%2A!&v~+^WwN^`=+Pu!U3=+Y4xpba9!WAvm*ip&M0S?}tj_w~pU$Zqo?f{eL>;*y zXOgsOliU}1Pm-@}^fMyM8LXY{ww&y$J|2zd9WAlpLpY4zvWB6t$;QPQcgdDCHIWC) zZ2C%W&d-v(b;j^pZFA}_N>%C{OL8%7&L#QDoa5oPBC#)jn9Qgjo%aDU{~N8=IpAKM zMW=jwUiJU`BXE1q*t(1{G1`XmoAL(Be*vwQv1QBIc`N_`03~!qSaf7zbY(hYa%Ew3 zWdJfTF)=MLGA%GOR53Ik4UOiAAEE)4(M`_JqL@;D1TB8wRq zxP?HN@zUM8KOn)f0>^Y9tpLXDzvj$kU|{^|>EamTas29(y?Mfc0#7v_fJJlBq6LeWGPp3BbXKw{S$bTUWaD;8QOdjU&*HzoHTLYjceL8q zdGgMy=jIl_dvj*y#C3aTrkQ_@KD1Dcqx962r+(V2x6C|da%gUl=cMbtk-jFYtC&5{ zKjdh3&M7(|Io(I1=%9I3i2$GTM-PEK!Rj*|5*MDTPng8G|AkV{1f_OqnfQk9ISGQ+ z4lYhkTwfxc8M#_Ebl81hdHA7YcTXdaM`y!gn^lJF?Kjk)wOr@ucPx>3#=;=@LFD1A zd*&Uw$M(41(GOlLyyO7u_Gjhw!4*filirEc-*jLw+|d4k_1v_-=T&U4mH(Xrbz;+|318?E?1*WcY1Zc#SC~bbEyH z(bUwn>%M5c|Cn`HAu8tLYB7!XKTq$eaFsuo8D6xeb)J!iXn;(AMR1VHfsZ!7=I5^Q zJ)X!Hmz5mrv0d`>I+38lXTn8u4m&$#P59JwNb#Ma3b)rzBOmvt29`E_-Nzpa%x^e< zFmaX2ZFaj2osK!5ITW}3;E;LL{5VECvR_k>x$Nh`hFCujiH|u?omK`|xU@5$lQ2v? z)e$^z^SwQn!t}42ZdLUa^)}k%>;1KU{a4jlr=E9}*6n@EZ}3kg{nhlj(!kUpQsNp> z;#`!PSdy8arx22vo62CJZ>(=<=(ePn9Vo8~l21u2NwrD_DN1E9GB7mMHL%b%unaLY zure~TGPcw;Ft;)=&}gyrLeY?$pOTqYiCaVD&Bkv)4Kg4bg7ec#$`gxH85~pclTsDj gGK*5n^NX^J6`X@j3%5Qt1FB>2boFyt=akR{05r5Tx&QzG literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/ic_settings_home.png b/res/drawable-xhdpi/ic_settings_home.png new file mode 100644 index 0000000000000000000000000000000000000000..687025d5f900721ea952e680de81bcd5bbd92b95 GIT binary patch literal 1888 zcmV-m2cP(fP)ht(u000JPNklif%^vrZPro7no zWhVRVy}z~A_g|N9t#5OhPSgK8mGPzpMJiQ$qbW_sVmFooS(=+6P8o;c#Mt61jq_d8 zg0b5Z<1A$?ib#oU&y!iA7jtE#$`B~0PJES;nfyJ;t69iG=9By^CG{y+AiYsXewbu2 zNt5JAk^|Y^d-8g$Up}3r)Bb%USLJY$Po8oG`r@z5;dIkYlO`|cvdDdD^1YsKjGoz> zz4U*4@lrC82ay8h^t!TdbT2 zimvpYj)g(r`*&nE-E`aVYjRaY-kkX)H%F=wGkYulSngiB9vA*9a$oCuJ^!E0`iQK{ z-Xxzj!VM!Ob$*cKK;F{hGM)))joW=tqqcz@cpew50B$9|uTgvy-PfoiS3{uaT5QL> z8Q&Um-Lz(A=clB~1o=RcmvT9&2YCEA zNpee@Lmo`>Qg#f6;z}l{@EI|$(~j=Q0BhO=&pggFJ%C|_eWL3Yy&U=o-e}99+|ddY z9W!<+Ci|BYn3j3s-t$LjXKza$^~VJ%_tA3aFMN6chXAZ zW_PuoF>hXN3Pr8kV)M8?xYRZ&>;qd31nWu&u-S&CkXnTrx7%s~jV|i;YNyLk>H0mU zT?qbd0h=?BTvk|N;atmd)<_Iuv#UWzr&Yc7ZGUtRCb0`#T;Q<7ILAp92sT%+gEdp`7uj{tIuEIf2gLAFNtbxY18pTtv*E5!t z7bDjHkh|NrrcCQvuvDl#t%w=d;W3Y?qfJM>8e&xwG-|JSRHLKYj*JlhjE^{=620I$ zX0E@A9wP5|j>f~SIo=AMb5aF*tGHKXO5Ki8rdY73wCvX5STA;pe(imm36-C>=GcM5 zo*PWXE1eHC_^q#akF+J#b;=1!Y_zew&~^gTIBITyc^BXGl5;(TnDI{R^Nf?nSB6JP z$#?tx!13~AA=i*PHThJMUD>qMnhedaQble~C&@2|TiDeDZRu&jm;FOM;FLwzq)mN$ zZp4ujvPWg2^%rhZ<1efs6}N_Ml(y=x9B`**sJDz>ClE<*k2_?cb;;IVrO{DZWp6;o zZw$rOiU^d}nc9Z7t8%~ZEW?0pmNNVnz2sFd=OHSw)79cByVj_{Fq`(>FWEhyLctY^ zMil2`Um5LQQQT@;@hctGpbgfv8y2nBM|{qFKZ_N-tt~?*T#UU&E6^yeS6OtQ@s0)u z&W7$8iiU395s~vUm*mD3+w+ob`BCoARLV-HC~Hxnq|S7HH`Jit5#(J-j%8Dv*l!Gk zI)93MK9IdM2ffLaR;oNVk#W!u{lXuzA80pd)%qfZOid%T`b;> z2S-=Yy<4S084vwoI7=p?pBFnx?#lMOoaDC1#OrZRSW+^b2l@w<^LakWi@9j|@yn@G zp^jXdXOqllA&Xf|a&LS8R4XuWTzNzG_rr02wxx`7SUpBk7&xxq;c^j`C+r@N;s5f% zq8cjLio9-LOh$aNN$HOF$>ubjrqlFaY#-e;WM5B00000bbVXQnWMOn=I%9HWVRU5x zGB7bQEif}JF*Z~&HaajiIyEpYFgH3dFe$2pEdT%jC3HntbYx+4WjbwdWNBu305UK! zF)c7NEipD!F*Z6dHaayhEigAaFfds6JdpqZ02y>eSaefwW^{L9a%BKPWN%_+AW3au aXJt}lVPtu6$z?nM0000 + + + + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 8ffa17f34e1..ad3e5be7d9e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1732,6 +1732,7 @@ + Home Display Sound @@ -4667,6 +4668,9 @@ Expand settings for application + + Uninstall this application + This setting affects all users on this tablet. diff --git a/res/xml/home_selection.xml b/res/xml/home_selection.xml new file mode 100644 index 00000000000..a348f9d3ffe --- /dev/null +++ b/res/xml/home_selection.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml index 6aa6691c022..55b3bca036a 100644 --- a/res/xml/settings_headers.xml +++ b/res/xml/settings_headers.xml @@ -62,6 +62,13 @@
+ +
+
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 homeActivities = new ArrayList(); + ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); + + Context context = getActivity(); + mCurrentHome = null; + mPrefGroup.removeAll(); + mPrefs = new ArrayList(); + 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 e754f986d39..bcfffcb59ac 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 homeApps = new ArrayList(); + 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();