• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings;
18 
19 import android.app.ActionBar;
20 import android.app.Activity;
21 import android.app.AlertDialog;
22 import android.app.Dialog;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.os.Bundle;
29 import android.preference.PreferenceActivity;
30 import android.util.Log;
31 import android.view.Gravity;
32 import android.view.LayoutInflater;
33 import android.view.Menu;
34 import android.view.MenuInflater;
35 import android.view.MenuItem;
36 import android.view.MenuItem.OnMenuItemClickListener;
37 import android.view.MotionEvent;
38 import android.view.View;
39 import android.view.View.OnClickListener;
40 import android.view.View.OnTouchListener;
41 import android.view.ViewGroup;
42 import android.widget.ArrayAdapter;
43 import android.widget.CompoundButton;
44 import android.widget.CompoundButton.OnCheckedChangeListener;
45 import android.widget.ImageView;
46 import android.widget.ListView;
47 import android.widget.RadioButton;
48 import android.widget.Switch;
49 import android.widget.TextView;
50 
51 import com.android.settings.DreamBackend.DreamInfo;
52 
53 import java.util.List;
54 
55 public class DreamSettings extends SettingsPreferenceFragment {
56     private static final String TAG = DreamSettings.class.getSimpleName();
57     static final boolean DEBUG = false;
58     private static final int DIALOG_WHEN_TO_DREAM = 1;
59     private static final String PACKAGE_SCHEME = "package";
60 
61     private final PackageReceiver mPackageReceiver = new PackageReceiver();
62 
63     private Context mContext;
64     private DreamBackend mBackend;
65     private DreamInfoAdapter mAdapter;
66     private Switch mSwitch;
67     private MenuItem[] mMenuItemsWhenEnabled;
68     private boolean mRefreshing;
69 
70     @Override
getHelpResource()71     public int getHelpResource() {
72         return R.string.help_url_dreams;
73     }
74 
75     @Override
onAttach(Activity activity)76     public void onAttach(Activity activity) {
77         logd("onAttach(%s)", activity.getClass().getSimpleName());
78         super.onAttach(activity);
79         mContext = activity;
80     }
81 
82     @Override
onCreate(Bundle icicle)83     public void onCreate(Bundle icicle) {
84         logd("onCreate(%s)", icicle);
85         super.onCreate(icicle);
86         Activity activity = getActivity();
87 
88         mBackend = new DreamBackend(activity);
89         mSwitch = new Switch(activity);
90         mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
91             @Override
92             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
93                 if (!mRefreshing) {
94                     mBackend.setEnabled(isChecked);
95                     refreshFromBackend();
96                 }
97             }
98         });
99 
100         final int padding = activity.getResources().getDimensionPixelSize(
101                 R.dimen.action_bar_switch_padding);
102         mSwitch.setPaddingRelative(0, 0, padding, 0);
103         activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
104                 ActionBar.DISPLAY_SHOW_CUSTOM);
105         activity.getActionBar().setCustomView(mSwitch, new ActionBar.LayoutParams(
106                 ActionBar.LayoutParams.WRAP_CONTENT,
107                 ActionBar.LayoutParams.WRAP_CONTENT,
108                 Gravity.CENTER_VERTICAL | Gravity.END));
109 
110         setHasOptionsMenu(true);
111     }
112 
113     @Override
onDestroyView()114     public void onDestroyView() {
115         getActivity().getActionBar().setCustomView(null);
116         super.onDestroyView();
117     }
118 
119     @Override
onActivityCreated(Bundle savedInstanceState)120     public void onActivityCreated(Bundle savedInstanceState) {
121         logd("onActivityCreated(%s)", savedInstanceState);
122         super.onActivityCreated(savedInstanceState);
123 
124         ListView listView = getListView();
125 
126         listView.setItemsCanFocus(true);
127 
128         TextView emptyView = (TextView) getView().findViewById(android.R.id.empty);
129         emptyView.setText(R.string.screensaver_settings_disabled_prompt);
130         listView.setEmptyView(emptyView);
131 
132         mAdapter = new DreamInfoAdapter(mContext);
133         listView.setAdapter(mAdapter);
134     }
135 
136     @Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)137     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
138         logd("onCreateOptionsMenu()");
139 
140         boolean isEnabled = mBackend.isEnabled();
141 
142         // create "start" action
143         MenuItem start = createMenuItem(menu, R.string.screensaver_settings_dream_start,
144                 MenuItem.SHOW_AS_ACTION_ALWAYS,
145                 isEnabled, new Runnable(){
146                     @Override
147                     public void run() {
148                         mBackend.startDreaming();
149                     }});
150 
151         // create "when to dream" overflow menu item
152         MenuItem whenToDream = createMenuItem(menu,
153                 R.string.screensaver_settings_when_to_dream,
154                 MenuItem.SHOW_AS_ACTION_IF_ROOM,
155                 isEnabled,
156                 new Runnable() {
157                     @Override
158                     public void run() {
159                         showDialog(DIALOG_WHEN_TO_DREAM);
160                     }});
161 
162         // create "help" overflow menu item (make sure it appears last)
163         super.onCreateOptionsMenu(menu, inflater);
164 
165         mMenuItemsWhenEnabled = new MenuItem[] { start, whenToDream };
166     }
167 
createMenuItem(Menu menu, int titleRes, int actionEnum, boolean isEnabled, final Runnable onClick)168     private MenuItem createMenuItem(Menu menu,
169             int titleRes, int actionEnum, boolean isEnabled, final Runnable onClick) {
170         MenuItem item = menu.add(titleRes);
171         item.setShowAsAction(actionEnum);
172         item.setEnabled(isEnabled);
173         item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
174             @Override
175             public boolean onMenuItemClick(MenuItem item) {
176                 onClick.run();
177                 return true;
178             }
179         });
180         return item;
181     }
182 
183     @Override
onCreateDialog(int dialogId)184     public Dialog onCreateDialog(int dialogId) {
185         logd("onCreateDialog(%s)", dialogId);
186         if (dialogId == DIALOG_WHEN_TO_DREAM)
187             return createWhenToDreamDialog();
188         return super.onCreateDialog(dialogId);
189     }
190 
createWhenToDreamDialog()191     private Dialog createWhenToDreamDialog() {
192         final CharSequence[] items = {
193                 mContext.getString(R.string.screensaver_settings_summary_dock),
194                 mContext.getString(R.string.screensaver_settings_summary_sleep),
195                 mContext.getString(R.string.screensaver_settings_summary_either_short)
196         };
197 
198         int initialSelection = mBackend.isActivatedOnDock() && mBackend.isActivatedOnSleep() ? 2
199                 : mBackend.isActivatedOnDock() ? 0
200                 : mBackend.isActivatedOnSleep() ? 1
201                 : -1;
202 
203         return new AlertDialog.Builder(mContext)
204                 .setTitle(R.string.screensaver_settings_when_to_dream)
205                 .setSingleChoiceItems(items, initialSelection, new DialogInterface.OnClickListener() {
206                     public void onClick(DialogInterface dialog, int item) {
207                         mBackend.setActivatedOnDock(item == 0 || item == 2);
208                         mBackend.setActivatedOnSleep(item == 1 || item == 2);
209                     }
210                 })
211                 .create();
212     }
213 
214     @Override
215     public void onPause() {
216         logd("onPause()");
217         super.onPause();
218         mContext.unregisterReceiver(mPackageReceiver);
219     }
220 
221     @Override
222     public void onResume() {
223         logd("onResume()");
224         super.onResume();
225         refreshFromBackend();
226 
227         // listen for package changes
228         IntentFilter filter = new IntentFilter();
229         filter.addAction(Intent.ACTION_PACKAGE_ADDED);
230         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
231         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
232         filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
233         filter.addDataScheme(PACKAGE_SCHEME);
234         mContext.registerReceiver(mPackageReceiver , filter);
235     }
236 
237     public static int getSummaryResource(Context context) {
238         DreamBackend backend = new DreamBackend(context);
239         boolean isEnabled = backend.isEnabled();
240         boolean activatedOnSleep = backend.isActivatedOnSleep();
241         boolean activatedOnDock = backend.isActivatedOnDock();
242         boolean activatedOnEither = activatedOnSleep && activatedOnDock;
243         return !isEnabled ? R.string.screensaver_settings_summary_off
244                 : activatedOnEither ? R.string.screensaver_settings_summary_either_long
245                 : activatedOnSleep ? R.string.screensaver_settings_summary_sleep
246                 : activatedOnDock ? R.string.screensaver_settings_summary_dock
247                 : 0;
248     }
249 
250     public static CharSequence getSummaryTextWithDreamName(Context context) {
251         DreamBackend backend = new DreamBackend(context);
252         boolean isEnabled = backend.isEnabled();
253         if (!isEnabled) {
254             return context.getString(R.string.screensaver_settings_summary_off);
255         } else {
256             return backend.getActiveDreamName();
257         }
258     }
259 
260     private void refreshFromBackend() {
261         logd("refreshFromBackend()");
262         mRefreshing = true;
263         boolean dreamsEnabled = mBackend.isEnabled();
264         if (mSwitch.isChecked() != dreamsEnabled)
265             mSwitch.setChecked(dreamsEnabled);
266 
267         mAdapter.clear();
268         if (dreamsEnabled) {
269             List<DreamInfo> dreamInfos = mBackend.getDreamInfos();
270             mAdapter.addAll(dreamInfos);
271         }
272         if (mMenuItemsWhenEnabled != null)
273             for (MenuItem menuItem : mMenuItemsWhenEnabled)
274                 menuItem.setEnabled(dreamsEnabled);
275         mRefreshing = false;
276     }
277 
278     private static void logd(String msg, Object... args) {
279         if (DEBUG)
280             Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
281     }
282 
283     private class DreamInfoAdapter extends ArrayAdapter<DreamInfo> {
284         private final LayoutInflater mInflater;
285 
286         public DreamInfoAdapter(Context context) {
287             super(context, 0);
288             mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
289         }
290 
291         @Override
292         public View getView(int position, View convertView, ViewGroup parent) {
293             DreamInfo dreamInfo = getItem(position);
294             logd("getView(%s)", dreamInfo.caption);
295             final View row = convertView != null ? convertView : createDreamInfoRow(parent);
296             row.setTag(dreamInfo);
297 
298             // bind icon
299             ((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(dreamInfo.icon);
300 
301             // bind caption
302             ((TextView) row.findViewById(android.R.id.title)).setText(dreamInfo.caption);
303 
304             // bind radio button
305             RadioButton radioButton = (RadioButton) row.findViewById(android.R.id.button1);
306             radioButton.setChecked(dreamInfo.isActive);
307             radioButton.setOnTouchListener(new OnTouchListener() {
308                 @Override
309                 public boolean onTouch(View v, MotionEvent event) {
310                     row.onTouchEvent(event);
311                     return false;
312                 }});
313 
314             // bind settings button + divider
315             boolean showSettings = dreamInfo.settingsComponentName != null;
316             View settingsDivider = row.findViewById(R.id.divider);
317             settingsDivider.setVisibility(showSettings ? View.VISIBLE : View.INVISIBLE);
318 
319             ImageView settingsButton = (ImageView) row.findViewById(android.R.id.button2);
320             settingsButton.setVisibility(showSettings ? View.VISIBLE : View.INVISIBLE);
321             settingsButton.setAlpha(dreamInfo.isActive ? 1f : Utils.DISABLED_ALPHA);
322             settingsButton.setEnabled(dreamInfo.isActive);
323             settingsButton.setFocusable(dreamInfo.isActive);
324             settingsButton.setOnClickListener(new OnClickListener(){
325                 @Override
326                 public void onClick(View v) {
327                     mBackend.launchSettings((DreamInfo) row.getTag());
328                 }});
329 
330             return row;
331         }
332 
333         private View createDreamInfoRow(ViewGroup parent) {
334             final View row =  mInflater.inflate(R.layout.dream_info_row, parent, false);
335             final View header = row.findViewById(android.R.id.widget_frame);
336             header.setOnClickListener(new OnClickListener(){
337                 @Override
338                 public void onClick(View v) {
339                     v.setPressed(true);
340                     activate((DreamInfo) row.getTag());
341                 }});
342             return row;
343         }
344 
345         private DreamInfo getCurrentSelection() {
346             for (int i = 0; i < getCount(); i++) {
347                 DreamInfo dreamInfo = getItem(i);
348                 if (dreamInfo.isActive)
349                     return dreamInfo;
350             }
351             return null;
352         }
353         private void activate(DreamInfo dreamInfo) {
354             if (dreamInfo.equals(getCurrentSelection()))
355                 return;
356             for (int i = 0; i < getCount(); i++) {
357                 getItem(i).isActive = false;
358             }
359             dreamInfo.isActive = true;
360             mBackend.setActiveDream(dreamInfo.componentName);
361             notifyDataSetChanged();
362         }
363     }
364 
365     private class PackageReceiver extends BroadcastReceiver {
366         @Override
367         public void onReceive(Context context, Intent intent) {
368             logd("PackageReceiver.onReceive");
369             refreshFromBackend();
370         }
371     }
372 }
373