New dream settings - first cut

First draft implementation of mocks for dream settings.

Want to merge for the weekly build, so a few things remain, namely:
  - flat style for preview/settings buttons + dividers
  - animation between dream row expanded/collapsed state
  - wire up the help url
  - possibly ditch the non-standard style
  - add logging
  - refresh when packages are installed/uninstalled

Bug:7010260
Change-Id: I96e3ab944170925bd76edf7b8b1127adfffc6262
This commit is contained in:
John Spurlock
2012-08-22 09:21:58 -04:00
parent c6015d2f59
commit 6df18e2713
15 changed files with 579 additions and 449 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/dream_info_bg_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/dream_info_bg_unpressed" android:state_pressed="false"/>
</selector>

View File

@@ -0,0 +1,82 @@
<!--
Copyright (C) 2012 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:background="@drawable/dream_info_bg"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@android:id/icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="@android:dimen/app_icon_size"
android:layout_centerVertical="true"
android:layout_margin="8dp"
android:contentDescription="@null"
android:scaleType="fitCenter" />
<RadioButton
android:id="@android:id/button1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_margin="8dp"
android:duplicateParentState="true" />
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@android:id/button1"
android:layout_toRightOf="@android:id/icon"
android:ellipsize="end"
android:fontFamily="sans-serif-light"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
<RelativeLayout
android:id="@android:id/widget_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@android:id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/screensaver_settings_dream_settings" />
<Button
android:id="@android:id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/screensaver_settings_dream_preview" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2011, 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:paddingStart="2dip"
android:gravity="center_vertical">
<ImageView android:id="@+id/icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="@android:dimen/app_icon_size"
android:scaleType="fitCenter"
android:contentDescription="@null" />
<TextView android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingStart="6dip" />
</LinearLayout>

View File

@@ -1702,29 +1702,25 @@
<!-- Display settings screen, trigger for screen saver options -->
<string name="screensaver_settings_title">Dream</string>
<!-- Display settings screen, summary fragment for screen saver options, activated on sleep or docked -->
<string name="screensaver_settings_summary_both">When docked or asleep and charging</string>
<string name="screensaver_settings_summary_either_long">When docked or asleep and charging</string>
<!-- Dream settings screen, dialog option, activated on sleep or docked -->
<string name="screensaver_settings_summary_either_short">Either</string>
<!-- Display settings screen, summary fragment for screen saver options, activated on sleep -->
<string name="screensaver_settings_summary_sleep">When asleep and charging</string>
<string name="screensaver_settings_summary_sleep">While asleep and charging</string>
<!-- Display settings screen, summary fragment for screen saver options, activated when docked -->
<string name="screensaver_settings_summary_dock">When docked</string>
<string name="screensaver_settings_summary_dock">While docked</string>
<!-- Display settings screen, summary for screen saver options, screen saver is turned off -->
<string name="screensaver_settings_summary_off">Disabled</string>
<!-- Screen saver settings, setting option name to select a module -->
<string name="screensaver_component_title">Selected dream</string>
<!-- Screen saver settings, setting option name to change activation timeout -->
<string name="screensaver_timeout_title">When to activate</string>
<!-- Screen saver settings, setting option summary to change activation timeout -->
<string name="screensaver_timeout_summary">After <xliff:g id="timeout_description">%1$s</xliff:g> spent idle</string>
<!-- Screen saver settings, setting option summary to change activation timeout, shown when disabled -->
<string name="screensaver_timeout_zero_summary">Never</string>
<!-- Screen saver settings, button allowing the user to test/try the current module -->
<string name="screensaver_test">Try it!</string>
<!-- Screen saver settings, checkbox allowing the screen saver to activate automatically when
the device sleeps -->
<string name="screensaver_activate_on_sleep_title">Start on sleep</string>
<!-- Screen saver settings, checkbox allowing the screen saver to activate automatically when
the device is docked -->
<string name="screensaver_activate_on_dock_title">Start when docked</string>
<!-- Dream settings screen, caption for when dreams are disabled -->
<string name="screensaver_settings_disabled_prompt">To control what happens when the phone is docked and/or sleeping, turn Dreams on.</string>
<!-- Dream settings screen, action label, start dreaming -->
<string name="screensaver_settings_start_dreaming">Start dreaming now</string>
<!-- Dream settings screen, action label, when to dream -->
<string name="screensaver_settings_when_to_dream">When to dream</string>
<!-- Dream settings screen, button label to launch dream settings -->
<string name="screensaver_settings_dream_settings">Settings</string>
<!-- Dream settings screen, button label to preview dream -->
<string name="screensaver_settings_dream_preview">Preview</string>
<!-- Sound & display settings screen, setting option name to change whether the screen adjusts automatically based on lighting conditions -->
<string name="automatic_brightness">Automatic brightness</string>
<!-- [CHAR LIMIT=30] Sound & display settings screen, setting option name to change font size -->

View File

@@ -232,13 +232,11 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
}
private void updateScreenSaverSummary() {
boolean activatedOnSleep = DreamSettings.isScreenSaverActivatedOnSleep(getActivity());
boolean activatedOnDock = DreamSettings.isScreenSaverActivatedOnDock(getActivity());
mScreenSaverPreference.setSummary(
activatedOnSleep && activatedOnDock ? R.string.screensaver_settings_summary_both :
activatedOnSleep ? R.string.screensaver_settings_summary_sleep :
activatedOnDock ? R.string.screensaver_settings_summary_dock :
R.string.screensaver_settings_summary_off);
int summaryResId = DreamSettings.getSummaryResource(getActivity());
if (summaryResId > 0)
mScreenSaverPreference.setSummary(summaryResId);
else
mScreenSaverPreference.setSummary("");
}
private void updateAccelerometerRotationCheckbox() {

View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2012 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 static android.provider.Settings.Secure.SCREENSAVER_ENABLED;
import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK;
import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.service.dreams.Dream;
import android.service.dreams.IDreamManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class DreamBackend {
public static class DreamInfo {
CharSequence caption;
Drawable icon;
boolean isActive;
public ComponentName componentName;
public ComponentName settingsComponentName;
}
private final Context mContext;
private final IDreamManager mDreamManager;
private final DreamInfoComparator mComparator;
public DreamBackend(Context context) {
mContext = context;
mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
mComparator = new DreamInfoComparator(getDefaultDream());
}
public List<DreamInfo> getDreamInfos() {
ComponentName activeDream = getActiveDream();
PackageManager pm = mContext.getPackageManager();
Intent dreamIntent = new Intent(Intent.ACTION_MAIN)
.addCategory("android.intent.category.DREAM");
List<ResolveInfo> resolveInfos = pm.queryIntentServices(dreamIntent,
PackageManager.GET_META_DATA);
List<DreamInfo> dreamInfos = new ArrayList<DreamInfo>(resolveInfos.size());
for (ResolveInfo resolveInfo : resolveInfos) {
if (resolveInfo.serviceInfo == null)
continue;
DreamInfo dreamInfo = new DreamInfo();
dreamInfo.caption = resolveInfo.loadLabel(pm);
dreamInfo.icon = resolveInfo.loadIcon(pm);
dreamInfo.componentName = getDreamComponentName(resolveInfo);
dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);
dreamInfo.settingsComponentName = getSettingsComponentName(resolveInfo);
dreamInfos.add(dreamInfo);
}
Collections.sort(dreamInfos, mComparator);
return dreamInfos;
}
public ComponentName getDefaultDream() {
if (mDreamManager == null)
return null;
try {
return mDreamManager.getDefaultDreamComponent();
} catch (RemoteException e) {
return null;
}
}
public boolean isEnabled() {
return getBoolean(SCREENSAVER_ENABLED);
}
public void setEnabled(boolean value) {
setBoolean(SCREENSAVER_ENABLED, value);
}
public boolean isActivatedOnDock() {
return getBoolean(SCREENSAVER_ACTIVATE_ON_DOCK);
}
public void setActivatedOnDock(boolean value) {
setBoolean(SCREENSAVER_ACTIVATE_ON_DOCK, value);
}
public boolean isActivatedOnSleep() {
return getBoolean(SCREENSAVER_ACTIVATE_ON_SLEEP);
}
public void setActivatedOnSleep(boolean value) {
setBoolean(SCREENSAVER_ACTIVATE_ON_SLEEP, value);
}
private boolean getBoolean(String key) {
return Settings.Secure.getInt(mContext.getContentResolver(), key, 1) == 1;
}
private void setBoolean(String key, boolean value) {
Settings.Secure.putInt(mContext.getContentResolver(), key, value ? 1 : 0);
}
public void startDreamingNow() {
if (mDreamManager == null)
return;
try {
mDreamManager.dream();
} catch (RemoteException e) {
}
}
public void setActiveDream(ComponentName dream) {
if (mDreamManager == null)
return;
try {
ComponentName[] dreams = { dream };
mDreamManager.setDreamComponents(dream == null ? null : dreams);
} catch (RemoteException e) {
// noop
}
}
public ComponentName getActiveDream() {
if (mDreamManager == null)
return null;
try {
ComponentName[] dreams = mDreamManager.getDreamComponents();
return dreams != null && dreams.length > 0 ? dreams[0] : null;
} catch (RemoteException e) {
return null;
}
}
public void launchSettings(DreamInfo dreamInfo) {
if (dreamInfo == null || dreamInfo.settingsComponentName == null)
return;
mContext.startActivity(new Intent().setComponent(dreamInfo.settingsComponentName));
}
public void preview(DreamInfo dreamInfo) {
if (mDreamManager == null || dreamInfo == null || dreamInfo.componentName == null)
return;
try {
mDreamManager.testDream(dreamInfo.componentName);
} catch (RemoteException e) {
// noop
}
}
private static ComponentName getDreamComponentName(ResolveInfo ri) {
if (ri == null || ri.serviceInfo == null)
return null;
return new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
}
private static ComponentName getSettingsComponentName(ResolveInfo ri) {
if (ri == null || ri.serviceInfo == null || ri.serviceInfo.metaData == null)
return null;
String cn = ri.serviceInfo.metaData.getString(Dream.METADATA_NAME_CONFIG_ACTIVITY);
return cn == null ? null : ComponentName.unflattenFromString(cn);
}
private static class DreamInfoComparator implements Comparator<DreamInfo> {
private final ComponentName mDefaultDream;
public DreamInfoComparator(ComponentName defaultDream) {
mDefaultDream = defaultDream;
}
@Override
public int compare(DreamInfo lhs, DreamInfo rhs) {
return sortKey(lhs).compareTo(sortKey(rhs));
}
private String sortKey(DreamInfo di) {
StringBuilder sb = new StringBuilder();
sb.append(di.componentName.equals(mDefaultDream) ? '0' : '1');
sb.append(di.caption);
return sb.toString();
}
}
}

View File

@@ -1,241 +0,0 @@
/*
* Copyright (C) 2011 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 static android.provider.Settings.Secure.SCREENSAVER_COMPONENTS;
import android.app.AlertDialog;
import android.content.Context;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.preference.Preference;
import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class DreamComponentPreference extends Preference {
private static final String TAG = "DreamComponentPreference";
private static final boolean SHOW_DOCK_APPS = false;
private static final boolean SHOW_DREAM_SERVICES = true;
private static final boolean SHOW_DREAM_ACTIVITIES = false;
private final PackageManager pm;
private final ContentResolver resolver;
private final Collator sCollator = Collator.getInstance();
public DreamComponentPreference(Context context, AttributeSet attrs) {
super(context, attrs);
pm = getContext().getPackageManager();
resolver = getContext().getContentResolver();
refreshFromSettings();
}
private void refreshFromSettings() {
ComponentName cn = null;
IDreamManager dm = IDreamManager.Stub.asInterface(
ServiceManager.getService("dreams"));
try {
ComponentName[] dreams = dm.getDreamComponents();
if (dreams != null && dreams.length > 0)
cn = dreams[0];
} catch (RemoteException ex) { }
if (cn == null) {
setSummary("(unknown)");
return;
}
try {
setSummary(pm.getActivityInfo(cn, 0).loadLabel(pm));
} catch (PackageManager.NameNotFoundException ex) {
try {
setSummary(pm.getServiceInfo(cn, 0).loadLabel(pm));
} catch (PackageManager.NameNotFoundException ex2) {
setSummary("(unknown)");
}
}
}
// Group by package, then by name.
Comparator<ResolveInfo> sResolveInfoComparator = new Comparator<ResolveInfo>() {
@Override
public int compare(ResolveInfo a, ResolveInfo b) {
CharSequence sa, sb;
ApplicationInfo aia = a.activityInfo != null ? a.activityInfo.applicationInfo : a.serviceInfo.applicationInfo;
ApplicationInfo aib = b.activityInfo != null ? b.activityInfo.applicationInfo : b.serviceInfo.applicationInfo;
if (!aia.equals(aib)) {
sa = pm.getApplicationLabel(aia);
sb = pm.getApplicationLabel(aib);
} else {
sa = a.loadLabel(pm);
if (sa == null) {
sa = (a.activityInfo != null) ? a.activityInfo.name : a.serviceInfo.name;
}
sb = b.loadLabel(pm);
if (sb == null) {
sb = (b.activityInfo != null) ? b.activityInfo.name : b.serviceInfo.name;
}
}
return sCollator.compare(sa.toString(), sb.toString());
}
};
public class DreamListAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<ResolveInfo> results;
private final LayoutInflater inflater;
public DreamListAdapter(Context context) {
Intent choosy = new Intent(Intent.ACTION_MAIN)
.addCategory("android.intent.category.DREAM");
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
results = new ArrayList<ResolveInfo>();
if (SHOW_DREAM_ACTIVITIES) {
results.addAll(pm.queryIntentActivities(choosy, PackageManager.GET_META_DATA));
}
if (SHOW_DREAM_SERVICES) {
results.addAll(pm.queryIntentServices(choosy, PackageManager.GET_META_DATA));
}
// Group by package
Collections.sort(results, sResolveInfoComparator);
if (SHOW_DOCK_APPS) {
choosy = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_DESK_DOCK);
List<ResolveInfo> dockApps = pm.queryIntentActivities(choosy, 0);
for (ResolveInfo app : dockApps) {
// do not insert duplicate packages
int pos = Collections.binarySearch(results, app, sResolveInfoComparator);
if (pos < 0) {
results.add(-1-pos, app);
}
}
}
}
@Override
public int getCount() {
return results.size();
}
@Override
public Object getItem(int position) {
return results.get(position);
}
@Override
public long getItemId (int position) {
return (long) position;
}
private CharSequence loadDescription(ResolveInfo ri) {
CharSequence desc = null;
if (ri != null) {
Bundle metaData = (ri.activityInfo != null) ? ri.activityInfo.metaData : ri.serviceInfo.metaData;
Log.d(TAG, "loadDescription: ri=" + ri + " metaData=" + metaData);
if (metaData != null) {
desc = metaData.getCharSequence("android.screensaver.description");
Log.d(TAG, "loadDescription: desc=" + desc);
if (desc != null) {
desc = desc.toString().trim();
}
}
}
return desc;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = (convertView != null)
? convertView
: inflater.inflate(R.layout.dream_picker_row, parent, false);
ResolveInfo ri = results.get(position);
((TextView)row.findViewById(R.id.title)).setText(ri.loadLabel(pm));
((ImageView)row.findViewById(R.id.icon)).setImageDrawable(ri.loadIcon(pm));
return row;
}
}
@Override
protected void onClick() {
final DreamListAdapter list = new DreamListAdapter(getContext());
AlertDialog alert = new AlertDialog.Builder(getContext())
.setAdapter(
list,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ResolveInfo ri = (ResolveInfo)list.getItem(which);
String pn = (ri.activityInfo != null) ? ri.activityInfo.applicationInfo.packageName
: ri.serviceInfo.applicationInfo.packageName;
String n = (ri.activityInfo != null) ? ri.activityInfo.name : ri.serviceInfo.name;
ComponentName cn = new ComponentName(pn, n);
setSummary(ri.loadLabel(pm));
//getContext().startActivity(intent);
IDreamManager dm = IDreamManager.Stub.asInterface(
ServiceManager.getService("dreams"));
try {
ComponentName[] dreams = { cn };
dm.setDreamComponents(dreams);
} catch (RemoteException ex) {
// too bad, so sad, oh mom, oh dad
}
}
})
.create();
alert.show();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012 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.
@@ -16,136 +16,295 @@
package com.android.settings;
import static android.provider.Settings.Secure.SCREENSAVER_ENABLED;
import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK;
import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.content.ContentResolver;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.Switch;
import android.widget.TextView;
import java.util.ArrayList;
import com.android.settings.DreamBackend.DreamInfo;
import java.util.List;
public class DreamSettings extends SettingsPreferenceFragment {
private static final String TAG = "DreamSettings";
private static final int DIALOG_WHEN_TO_DREAM = 1;
private static final int DIVIDER_HEIGHT = 15;
private static final String KEY_ACTIVATE_ON_SLEEP = "activate_on_sleep";
private static final String KEY_ACTIVATE_ON_DOCK = "activate_on_dock";
private static final String KEY_COMPONENT = "screensaver_component";
private static final String KEY_TEST = "test";
private Context mContext;
private DreamBackend mBackend;
private DreamInfoAdapter mAdapter;
private Switch mSwitch;
private MenuItem[] mDependentMenuItems;
private boolean mRefreshing;
private static final int DEFAULT_SLEEP = 1;
private static final int DEFAULT_DOCK = 1;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
}
private ActivationSetting mActivateOnSleep;
private ActivationSetting mActivateOnDock;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Activity activity = getActivity();
private Preference mComponentPref;
private Preference mTestPref;
mBackend = new DreamBackend(activity);
mSwitch = new Switch(activity);
mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!mRefreshing) {
mBackend.setEnabled(isChecked);
refreshFromBackend();
}
}
});
if (activity instanceof PreferenceActivity) {
PreferenceActivity preferenceActivity = (PreferenceActivity) activity;
if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {
final int padding = activity.getResources().getDimensionPixelSize(
R.dimen.action_bar_switch_padding);
mSwitch.setPadding(0, 0, padding, 0);
activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_CUSTOM);
activity.getActionBar().setCustomView(mSwitch, new ActionBar.LayoutParams(
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_VERTICAL | Gravity.END));
}
}
setHasOptionsMenu(true);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
addPreferencesFromResource(R.xml.dream_settings);
ListView listView = getListView();
mComponentPref = findPreference(KEY_COMPONENT);
mTestPref = findPreference(KEY_TEST);
TextView emptyView = (TextView) getView().findViewById(android.R.id.empty);
emptyView.setText(R.string.screensaver_settings_disabled_prompt);
listView.setEmptyView(emptyView);
mActivateOnSleep = new ActivationSetting(getActivity(),
SCREENSAVER_ACTIVATE_ON_SLEEP, DEFAULT_SLEEP,
(CheckBoxPreference) findPreference(KEY_ACTIVATE_ON_SLEEP));
mActivateOnDock = new ActivationSetting(getActivity(),
SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK,
(CheckBoxPreference) findPreference(KEY_ACTIVATE_ON_DOCK));
mAdapter = new DreamInfoAdapter(mContext);
listView.setAdapter(mAdapter);
listView.setDivider(null);
listView.setDividerHeight(DIVIDER_HEIGHT);
listView.setBackgroundColor(Color.BLACK);
listView.setPadding(0, DIVIDER_HEIGHT, 0, DIVIDER_HEIGHT);
listView.setHeaderDividersEnabled(true);
}
public static boolean isScreenSaverActivatedOnSleep(Context context) {
return 0 != Settings.Secure.getInt(
context.getContentResolver(), SCREENSAVER_ACTIVATE_ON_SLEEP, DEFAULT_SLEEP);
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
boolean isEnabled = mBackend.isEnabled();
MenuItem whenToDream = createMenuItem(menu,
R.string.screensaver_settings_when_to_dream,
MenuItem.SHOW_AS_ACTION_NEVER,
isEnabled,
new Runnable() {
@Override
public void run() {
showDialog(DIALOG_WHEN_TO_DREAM);
}});
createMenuItem(menu,
R.string.help_label,
MenuItem.SHOW_AS_ACTION_NEVER,
true,
new Runnable() {
@Override
public void run() {
// TODO show help url
}});
MenuItem startDreaming = createMenuItem(menu,
R.string.screensaver_settings_start_dreaming,
MenuItem.SHOW_AS_ACTION_ALWAYS,
isEnabled,
new Runnable(){
@Override
public void run() {
mBackend.startDreamingNow();
}});
mDependentMenuItems = new MenuItem[] { whenToDream, startDreaming };
}
public static boolean isScreenSaverActivatedOnDock(Context context) {
return 0 != Settings.Secure.getInt(
context.getContentResolver(), SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK);
private MenuItem createMenuItem(Menu menu,
int titleRes, int actionEnum, boolean isEnabled, final Runnable onClick) {
MenuItem item = menu.add(titleRes);
item.setShowAsAction(actionEnum);
item.setEnabled(isEnabled);
item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
onClick.run();
return true;
}
});
return item;
}
@Override
public Dialog onCreateDialog(int dialogId) {
if (dialogId == DIALOG_WHEN_TO_DREAM)
return createWhenToDreamDialog();
return super.onCreateDialog(dialogId);
}
private Dialog createWhenToDreamDialog() {
final CharSequence[] items = {
mContext.getString(R.string.screensaver_settings_summary_dock),
mContext.getString(R.string.screensaver_settings_summary_sleep),
mContext.getString(R.string.screensaver_settings_summary_either_short)
};
int initialSelection = mBackend.isActivatedOnDock() && mBackend.isActivatedOnSleep() ? 2
: mBackend.isActivatedOnDock() ? 0
: mBackend.isActivatedOnSleep() ? 1
: -1;
return new AlertDialog.Builder(mContext)
.setTitle(R.string.screensaver_settings_when_to_dream)
.setSingleChoiceItems(items, initialSelection, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
mBackend.setActivatedOnDock(item == 0 || item == 2);
mBackend.setActivatedOnSleep(item == 1 || item == 2);
}
})
.create();
}
@Override
public void onResume() {
mActivateOnSleep.onResume();
mActivateOnDock.onResume();
refreshDependents();
super.onResume();
refreshFromBackend();
}
public static int getSummaryResource(Context context) {
DreamBackend backend = new DreamBackend(context);
boolean isEnabled = backend.isEnabled();
boolean activatedOnSleep = backend.isActivatedOnSleep();
boolean activatedOnDock = backend.isActivatedOnDock();
boolean activatedOnEither = activatedOnSleep && activatedOnDock;
return !isEnabled ? R.string.screensaver_settings_summary_off
: activatedOnEither ? R.string.screensaver_settings_summary_either_long
: activatedOnSleep ? R.string.screensaver_settings_summary_sleep
: activatedOnDock ? R.string.screensaver_settings_summary_dock
: 0;
}
private void refreshFromBackend() {
mRefreshing = true;
boolean dreamsEnabled = mBackend.isEnabled();
if (mSwitch.isChecked() != dreamsEnabled)
mSwitch.setChecked(dreamsEnabled);
mAdapter.clear();
if (dreamsEnabled) {
List<DreamInfo> dreamInfos = mBackend.getDreamInfos();
mAdapter.addAll(dreamInfos);
}
if (mDependentMenuItems != null)
for (MenuItem item : mDependentMenuItems)
item.setEnabled(dreamsEnabled);
mRefreshing = false;
}
private class DreamInfoAdapter extends ArrayAdapter<DreamInfo> {
private final LayoutInflater mInflater;
public DreamInfoAdapter(Context context) {
super(context, 0);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
mActivateOnSleep.onClick(preference);
mActivateOnDock.onClick(preference);
public View getView(int position, View convertView, ViewGroup parent) {
DreamInfo dreamInfo = getItem(position);
final View row = convertView != null ? convertView : createDreamInfoRow(parent);
row.setTag(dreamInfo);
// FIXME: infer enabled (until the next rev of the dream settings ui)
boolean enabled = mActivateOnSleep.isSelected() || mActivateOnDock.isSelected();
Settings.Secure.putInt(getActivity().getContentResolver(),
SCREENSAVER_ENABLED,
enabled ? 1 : 0);
// bind icon
((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(dreamInfo.icon);
refreshDependents();
return super.onPreferenceTreeClick(preferenceScreen, preference);
// bind caption
((TextView) row.findViewById(android.R.id.text1)).setText(dreamInfo.caption);
// bind radio button
((RadioButton) row.findViewById(android.R.id.button1)).setChecked(dreamInfo.isActive);
((RadioButton) row.findViewById(android.R.id.button1)).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
row.onTouchEvent(event);
return false;
}});
// bind button container
row.findViewById(android.R.id.widget_frame).setVisibility(dreamInfo.isActive ? View.VISIBLE : View.GONE);
// bind settings button
((Button) row.findViewById(android.R.id.button2)).setEnabled(dreamInfo.settingsComponentName != null);
((Button) row.findViewById(android.R.id.button2)).setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
mBackend.launchSettings((DreamInfo)row.getTag());
}});
// bind preview button
((Button) row.findViewById(android.R.id.button3)).setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
mBackend.preview((DreamInfo)row.getTag());
}});
return row;
}
private void refreshDependents() {
boolean enabled = mActivateOnSleep.isSelected() || mActivateOnDock.isSelected();
mComponentPref.setEnabled(enabled);
mTestPref.setEnabled(enabled);
private View createDreamInfoRow(ViewGroup parent) {
final View row = mInflater.inflate(R.layout.dream_info_row, parent, false);
row.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
v.setPressed(true);
activate((DreamInfo) row.getTag());
}});
return row;
}
private static class ActivationSetting {
private final Context mContext;
private final String mName;
private final int mDefaultValue;
private final CheckBoxPreference mPref;
ActivationSetting(Context context, String name, int defaultValue, CheckBoxPreference pref) {
mContext = context;
mName = name;
mDefaultValue = defaultValue;
mPref = pref;
private void activate(DreamInfo dreamInfo) {
for (int i = 0; i < getCount(); i++) {
getItem(i).isActive = false;
}
public boolean isSelected() {
return mPref.isChecked();
}
void onClick(Preference preference) {
if (preference == mPref) {
Settings.Secure.putInt(mContext.getContentResolver(),
mName,
mPref.isChecked() ? 1 : 0);
dreamInfo.isActive = true;
mBackend.setActiveDream(dreamInfo.componentName);
notifyDataSetChanged();
}
}
void onResume() {
boolean currentActivated = 0 != Settings.Secure.getInt(mContext.getContentResolver(),
mName, mDefaultValue);
mPref.setChecked(currentActivated);
}
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright (C) 2011 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 android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.preference.Preference;
import android.service.dreams.IDreamManager;
import android.util.AttributeSet;
import android.util.Log;
public class DreamTesterPreference extends Preference {
private static final String TAG = "DreamTesterPreference";
public DreamTesterPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onClick() {
IDreamManager dm = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
try {
ComponentName[] dreams = dm.getDreamComponents();
if (dreams == null || dreams.length == 0)
return;
ComponentName cn = dreams[0];
Log.v(TAG, "DreamComponent cn=" + cn);
dm.testDream(cn);
} catch (RemoteException ex) {
Log.w(TAG, "error testing dream", ex);
// too bad, so sad, oh mom, oh dad
}
}
}