Also a little tweak to the animations preference.
Change-Id: I3183ef21e687a3b120d02c79e7388300084b9202
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
+ <action android:name="android.settings.ACCESSIBILITY_SETTINGS" />
+ <!-- Wtf... this action is bogus! Can we remove it? -->
<action android:name="ACCESSIBILITY_FEEDBACK_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.VOICE_LAUNCH" />
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
- <TextView android:id="@+id/name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textStyle="bold"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:layout_marginBottom="2dip" />
<LinearLayout
android:orientation="horizontal"
+ android:baselineAlignedChildIndex="0"
android:layout_width="fill_parent"
- android:layout_height="wrap_content" >
- <TextView android:id="@+id/run_time"
- android:layout_marginTop="-4dip"
- android:layout_gravity="center_vertical|left"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="wrap_content">
+ <TextView android:id="@+id/name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_weight="1"
- android:paddingRight="4dip"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textStyle="bold"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:layout_marginBottom="2dip" />
<TextView android:id="@+id/size"
- android:layout_marginTop="-4dip"
android:layout_gravity="center_vertical|right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
+ <TextView android:id="@+id/description"
+ android:layout_marginTop="-4dip"
+ android:layout_gravity="center_vertical|left"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<item>yyyy-MM-dd</item>
</string-array>
+ <!-- Display settings. The type of animations to show. -->
+ <string-array name="animations_entries">
+ <item>Off</item>
+ <item>Some</item>
+ <item>All</item>
+ <item>Slow</item>
+ </string-array>
+
+ <!-- Display settings. Summary for each type of animation. -->
+ <string-array name="animations_summaries">
+ <item>No window animations are shown</item>
+ <item>Some window animations are shown</item>
+ <item>All window animations are shown</item>
+ <item>Slower window animations are shown</item>
+ </string-array>
+
+ <!-- Do not translate. -->
+ <string-array name="animations_values">
+ <!-- Do not translate. -->
+ <item>00</item>
+ <!-- Do not translate. -->
+ <item>01</item>
+ <!-- Do not translate. -->
+ <item>11</item>
+ <!-- Do not translate. -->
+ <item>22</item>
+ </string-array>
+
<!-- Display settings. The delay in inactivity before the screen is turned off. These are shown ain a list dialog. -->
<string-array name="screen_timeout_entries">
<item>15 seconds</item>
<string name="confirm_stop_stop">Stop</string>
<!-- Running services, button to cancel stopping of a service -->
<string name="confirm_stop_cancel">Cancel</string>
+ <!-- Running services, description for a service in the started state -->
+ <string name="service_started_by_app">Started by application</string>
+ <!-- Running services, description for a service in the started state -->
+ <string name="service_client_name"><xliff:g id="client_name">%1$s</xliff:g>: select to manage</string>
<!-- Language Settings --> <skip />
<!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings realted to locale and text -->
android:summaryOn="@string/accelerometer_summary_on"
android:summaryOff="@string/accelerometer_summary_off"/>
- <CheckBoxPreference
- android:key="animations"
- android:title="@string/animations_title"
- android:summaryOn="@string/animations_summary_on"
- android:summaryOff="@string/animations_summary_off" />
+ <ListPreference
+ android:key="animations"
+ android:title="@string/animations_title"
+ android:persistent="false"
+ android:entries="@array/animations_entries"
+ android:entryValues="@array/animations_values" />
<com.android.settings.BrightnessPreference
android:key="brightness"
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
+import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
PackageItemInfo mPackageInfo;
CharSequence mDisplayLabel;
String mLabel;
- String mName;
+ String mDescription;
int mCurSeq;
static class ServiceItem extends BaseItem {
ActivityManager.RunningServiceInfo mRunningService;
ServiceInfo mServiceInfo;
+ boolean mShownAsStarted;
}
static class ProcessItem extends BaseItem {
int mUid;
int mPid;
- boolean updateService(PackageManager pm,
+ boolean updateService(Context context,
ActivityManager.RunningServiceInfo service) {
+ final PackageManager pm = context.getPackageManager();
+
boolean changed = false;
ServiceItem si = mServices.get(service.service);
if (si == null) {
si.mActiveSince = activeSince;
changed = true;
}
+ if (service.clientPackage != null && service.clientLabel != 0) {
+ if (si.mShownAsStarted) {
+ si.mShownAsStarted = false;
+ changed = true;
+ }
+ try {
+ Resources clientr = pm.getResourcesForApplication(service.clientPackage);
+ String label = clientr.getString(service.clientLabel);
+ si.mDescription = context.getResources().getString(
+ R.string.service_client_name, label);
+ } catch (PackageManager.NameNotFoundException e) {
+ si.mDescription = null;
+ }
+ } else {
+ if (!si.mShownAsStarted) {
+ si.mShownAsStarted = true;
+ changed = true;
+ }
+ si.mDescription = context.getResources().getString(
+ R.string.service_started_by_app);
+ }
return changed;
}
final int NS = services.size();
for (int i=0; i<NS; i++) {
ActivityManager.RunningServiceInfo si = services.get(i);
- // We are not interested in non-started services, because
+ // We are not interested in services that have not been started
+ // and don't have a known client, because
// there is nothing the user can do about them.
- if (!si.started) {
+ if (!si.started && si.clientLabel == 0) {
continue;
}
// We likewise don't care about services running in a
changed = true;
proc = new ProcessItem();
proc.mIsProcess = true;
- proc.mName = si.process;
+ proc.mDescription = si.process;
proc.mUid = si.uid;
try {
ApplicationInfo ai = pm.getApplicationInfo(si.process, 0);
}
proc.mCurSeq = mSequence;
}
- changed |= proc.updateService(context.getPackageManager(), si);
+ changed |= proc.updateService(context, si);
if (proc.mLabel == null) {
// If we couldn't get information about the overall
ImageView separator;
ImageView icon;
TextView name;
- TextView runTime;
+ TextView description;
TextView size;
}
h.separator = (ImageView)v.findViewById(R.id.separator);
h.icon = (ImageView)v.findViewById(R.id.icon);
h.name = (TextView)v.findViewById(R.id.name);
- h.runTime = (TextView)v.findViewById(R.id.run_time);
+ h.description = (TextView)v.findViewById(R.id.description);
h.size = (TextView)v.findViewById(R.id.size);
v.setTag(h);
return v;
if (item.mIsProcess) {
view.setBackgroundColor(mProcessBgColor);
vh.icon.setImageDrawable(item.mPackageInfo.loadIcon(getPackageManager()));
- vh.runTime.setText(item.mName);
+ vh.description.setText(item.mDescription);
vh.size.setText(item.mSizeStr);
mActiveItems.remove(view);
} else {
view.setBackgroundDrawable(null);
vh.icon.setImageDrawable(null);
- vh.runTime.setText("");
+ vh.description.setText("");
ActiveItem ai = new ActiveItem();
ai.mRootView = view;
ai.mItem = item;
ai.mHolder = vh;
ai.mFirstRunTime = item.mActiveSince;
+ vh.description.setText(item.mDescription);
ai.updateTime(RunningServices.this);
mActiveItems.put(view, ai);
}
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_TIMES:
- for (ActiveItem ai : mActiveItems.values()) {
+ Iterator<ActiveItem> it = mActiveItems.values().iterator();
+ while (it.hasNext()) {
+ ActiveItem ai = it.next();
+ if (ai.mRootView.getWindowToken() == null) {
+ // Clean out any dead views, just in case.
+ it.remove();
+ continue;
+ }
ai.updateTime(RunningServices.this);
}
removeMessages(MSG_UPDATE_TIMES);
protected void onListItemClick(ListView l, View v, int position, long id) {
BaseItem bi = (BaseItem)l.getAdapter().getItem(position);
if (!bi.mIsProcess) {
- mCurSelected = bi;
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.confirm_stop_service);
- builder.setMessage(R.string.confirm_stop_service_msg);
- builder.setPositiveButton(R.string.confirm_stop_stop, this);
- builder.setNegativeButton(R.string.confirm_stop_cancel, null);
- builder.setCancelable(true);
- mCurDialog = builder.show();
+ ServiceItem si = (ServiceItem)bi;
+ if (si.mRunningService.clientLabel != 0) {
+ mCurSelected = null;
+ PendingIntent pi = mAm.getRunningServiceControlPanel(
+ si.mRunningService.service);
+ if (pi != null) {
+ try {
+ pi.send();
+ } catch (PendingIntent.CanceledException e) {
+ // whatever.
+ }
+ }
+ } else {
+ mCurSelected = bi;
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.confirm_stop_service);
+ builder.setMessage(R.string.confirm_stop_service_msg);
+ builder.setPositiveButton(R.string.confirm_stop_stop, this);
+ builder.setNegativeButton(R.string.confirm_stop_cancel, null);
+ builder.setCancelable(true);
+ mCurDialog = builder.show();
+ }
} else {
mCurSelected = null;
}
private CheckBoxPreference mVibrate;
private CheckBoxPreference mDtmfTone;
private CheckBoxPreference mSoundEffects;
- private CheckBoxPreference mAnimations;
+ private ListPreference mAnimations;
private CheckBoxPreference mAccelerometer;
private float[] mAnimationScales;
mSoundEffects.setPersistent(false);
mSoundEffects.setChecked(Settings.System.getInt(resolver,
Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0);
- mAnimations = (CheckBoxPreference) findPreference(KEY_ANIMATIONS);
- mAnimations.setPersistent(false);
+ mAnimations = (ListPreference) findPreference(KEY_ANIMATIONS);
+ mAnimations.setOnPreferenceChangeListener(this);
mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER);
mAccelerometer.setPersistent(false);
R.string.silent_mode_incl_alarm_summary :
R.string.silent_mode_summary);
- boolean animations = true;
+ int animations = 0;
try {
mAnimationScales = mWindowManager.getAnimationScales();
} catch (RemoteException e) {
}
if (mAnimationScales != null) {
- // We will leave the window animations alone (always set),
- // and only use this to change the transition animations.
- for (int i=1; i<mAnimationScales.length; i++) {
- if (mAnimationScales[i] == 0) {
- animations = false;
- break;
- }
+ if (mAnimationScales.length >= 1) {
+ animations = ((int)(mAnimationScales[0]+.5f)) % 10;
+ }
+ if (mAnimationScales.length >= 2) {
+ animations += (((int)(mAnimationScales[1]+.5f)) & 0x7) * 10;
}
}
- if (animations != mAnimations.isChecked() || force) {
- mAnimations.setChecked(animations);
+ int idx = 0;
+ int best = 0;
+ CharSequence[] aents = mAnimations.getEntryValues();
+ for (int i=0; i<aents.length; i++) {
+ int val = Integer.parseInt(aents[i].toString());
+ if (val <= animations && val > best) {
+ best = val;
+ idx = i;
+ }
}
+ mAnimations.setValueIndex(idx);
+ updateAnimationsSummary(mAnimations.getValue());
mAccelerometer.setChecked(Settings.System.getInt(
getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0) != 0);
}
+ private void updateAnimationsSummary(Object value) {
+ CharSequence[] summaries = getResources().getTextArray(R.array.animations_summaries);
+ CharSequence[] values = mAnimations.getEntryValues();
+ for (int i=0; i<values.length; i++) {
+ Log.i("foo", "Comparing entry "+ values[i] + " to current "
+ + mAnimations.getValue());
+ if (values[i].equals(value)) {
+ mAnimations.setSummary(summaries[i]);
+ break;
+ }
+ }
+ }
+
private void setRingerMode(boolean silent, boolean vibrate) {
if (silent) {
mAudioManager.setRingerMode(vibrate ? AudioManager.RINGER_MODE_VIBRATE :
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-
if (preference == mSilent || preference == mVibrate) {
setRingerMode(mSilent.isChecked(), mVibrate.isChecked());
if (preference == mSilent) updateState(false);
Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED,
mSoundEffects.isChecked() ? 1 : 0);
- } else if (preference == mAnimations) {
- if (mAnimationScales.length > 0) {
- // Window animations are always on.
- mAnimationScales[0] = 1;
- }
- for (int i=1; i<mAnimationScales.length; i++) {
- mAnimationScales[i] = mAnimations.isChecked() ? 1 : 0;
- }
- try {
- mWindowManager.setAnimationScales(mAnimationScales);
- } catch (RemoteException e) {
- }
-
} else if (preference == mAccelerometer) {
Settings.System.putInt(getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION,
}
public boolean onPreferenceChange(Preference preference, Object objValue) {
+ if (KEY_ANIMATIONS.equals(preference.getKey())) {
+ try {
+ int value = Integer.parseInt((String) objValue);
+ if (mAnimationScales.length >= 1) {
+ mAnimationScales[0] = value%10;
+ }
+ if (mAnimationScales.length >= 2) {
+ mAnimationScales[1] = (value/10)%10;
+ }
+ try {
+ mWindowManager.setAnimationScales(mAnimationScales);
+ } catch (RemoteException e) {
+ }
+ updateAnimationsSummary(objValue);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "could not persist animation setting", e);
+ }
+
+ }
if (KEY_SCREEN_TIMEOUT.equals(preference.getKey())) {
int value = Integer.parseInt((String) objValue);
try {