1/*
2 * Copyright (C) 2014 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
17package com.android.tv.settings.device.display.daydream;
18
19// This setting controls when we will start dreaming
20import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
21// This setting controls when we'll turn the output off and go to sleep
22import static android.provider.Settings.Secure.SLEEP_TIMEOUT;
23
24import com.android.tv.settings.R;
25import com.android.tv.settings.dialog.old.Action;
26import com.android.tv.settings.dialog.old.ActionAdapter;
27import com.android.tv.settings.dialog.old.ActionFragment;
28import com.android.tv.settings.dialog.old.ContentFragment;
29import com.android.tv.settings.dialog.old.DialogActivity;
30
31import android.content.Context;
32import android.content.Intent;
33import android.content.SharedPreferences;
34import android.os.Bundle;
35import android.preference.PreferenceManager;
36import android.provider.Settings;
37import android.util.Log;
38
39import java.util.ArrayList;
40import java.util.Collections;
41import java.util.HashMap;
42import java.util.List;
43
44/**
45 * Activity that allows the setting of daydreams.
46 */
47public class DaydreamActivity extends DialogActivity implements ActionAdapter.Listener {
48
49    enum ActionType {
50        SELECT, LIST_DREAM_TIMEOUT, LIST_SYSTEM_SLEEP_TIMEOUT, SET_DREAM_TIMEOUT, SET_SYSTEM_SLEEP_TIMEOUT, TEST;
51    }
52
53    /** If there is no setting in the provider, use this. */
54    private static final int DREAM_SETTINGS_REQUEST = 1;
55    private static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 1800000;
56    private static final String EXTRA_LIST_VALUE = "list_value";
57    private static final int CHECK_SET_ID = 1;
58
59    private static final int DEFAULT_SLEEP_TIMEOUT_MS = 3 * 60 * 60 * 1000;
60
61    private DreamBackend mDreamBackend;
62    private ContentFragment mContentFragment;
63    private ActionFragment mActionFragment;
64
65    @Override
66    protected void onCreate(Bundle savedInstanceState) {
67        super.onCreate(savedInstanceState);
68
69        mDreamBackend = new DreamBackend(this);
70        mDreamBackend.initDreamInfoActions();
71        mContentFragment = createMainMenuContentFragment();
72        mActionFragment = ActionFragment.newInstance(getMainActions());
73        setContentAndActionFragments(mContentFragment, mActionFragment);
74    }
75
76    @Override
77    protected void onActivityResult(final int requestCode, final int resultCode,
78            final Intent data) {
79        if (requestCode == DREAM_SETTINGS_REQUEST) {
80            goToMainScreen();
81        }
82    }
83
84    @Override
85    public void onActionClicked(Action action) {
86        if (action instanceof DreamInfoAction) {
87            DreamInfoAction dreamInfoAction = (DreamInfoAction) action;
88            dreamInfoAction.setDream(mDreamBackend);
89
90            /**
91             * If this day dream has settings, launch the activity to set its
92             * settings before returning to main menu. Otherwise just return to
93             * main menu.
94             */
95            Intent settingsIntent = dreamInfoAction.getSettingsIntent();
96            if (settingsIntent != null) {
97                startActivityForResult(settingsIntent, DREAM_SETTINGS_REQUEST);
98            } else {
99                goToMainScreen();
100            }
101        } else {
102            ActionType type = ActionType.valueOf(action.getKey());
103            switch (type) {
104                case SELECT:
105                    onSelect();
106                    break;
107                case LIST_DREAM_TIMEOUT:
108                    onListDreamTimeouts();
109                    break;
110                case LIST_SYSTEM_SLEEP_TIMEOUT:
111                    onListSystemSleepTimeouts();
112                    break;
113                case SET_DREAM_TIMEOUT:
114                    onSetDreamTimeout(action);
115                    break;
116                case SET_SYSTEM_SLEEP_TIMEOUT:
117                    onSetSystemSleepTimeout(action);
118                    break;
119                case TEST:
120                    onTest();
121                    break;
122                default:
123                    break;
124            }
125        }
126    }
127
128    private void onSelect() {
129        setContentAndActionFragments(
130                createSubMenuContentFragment(getString(R.string.device_daydreams_select), null),
131                ActionFragment.newInstance(mDreamBackend.getDreamInfoActions()));
132    }
133
134    private void onListDreamTimeouts() {
135        setContentAndActionFragments(createSubMenuContentFragment(
136                getString(R.string.device_daydreams_sleep),
137                getString(R.string.device_daydreams_sleep_description)),
138                ActionFragment.newInstance(getListActions(ActionType.SET_DREAM_TIMEOUT.name(),
139                        R.array.sleep_timeout_values, R.array.sleep_timeout_entries,
140                        getDreamTimeoutValue())));
141    }
142
143    private void onListSystemSleepTimeouts() {
144        setContentAndActionFragments(createSubMenuContentFragment(
145                getString(R.string.device_daydreams_screen_off),
146                getString(R.string.device_daydreams_screen_off_description)),
147                ActionFragment.newInstance(getListActions(ActionType.SET_SYSTEM_SLEEP_TIMEOUT.name(),
148                        R.array.screen_off_timeout_values, R.array.screen_off_timeout_entries,
149                        getSystemSleepTimeout())));
150    }
151
152    private void onSetDreamTimeout(Action action) {
153        long sleepValue = action.getIntent().getLongExtra(EXTRA_LIST_VALUE, 0);
154        Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, (int) sleepValue);
155        goToMainScreen();
156    }
157
158    private void onSetSystemSleepTimeout(Action action) {
159        int screenOffValue = (int) action.getIntent().getLongExtra(EXTRA_LIST_VALUE, 0);
160        setSystemSleepTimeout(screenOffValue);
161        goToMainScreen();
162    }
163
164    private void onTest() {
165        mDreamBackend.startDreaming();
166    }
167
168    private void goToMainScreen() {
169        updateMainScreen();
170        getFragmentManager().popBackStack(null, 0);
171    }
172
173    private ArrayList<Action> getMainActions() {
174        ArrayList<Action> actions = new ArrayList<Action>();
175        actions.add(new Action.Builder().key(ActionType.SELECT.name())
176                .title(getString(R.string.device_daydreams_select))
177                .description(mDreamBackend.getActiveDreamTitle()).build());
178        actions.add(new Action.Builder()
179                .key(ActionType.LIST_DREAM_TIMEOUT.name())
180                .title(getString(R.string.device_daydreams_sleep))
181                .description((getString(R.string.device_daydreams_sleep_summary,
182                        getEntry(R.array.sleep_timeout_values, R.array.sleep_timeout_entries,
183                                getDreamTimeoutValue()))))
184                .build());
185
186        String[] screenOffEntries = getResources().getStringArray(
187                R.array.screen_off_timeout_entries);
188        int systemSleepTimeout = getSystemSleepTimeout();
189        // Only add the summary text if the value is not "Never"
190        String screenOffDescription = systemSleepTimeout > 0 ? getString(
191                R.string.device_daydreams_sleep_summary,
192                getEntry(R.array.screen_off_timeout_values, R.array.screen_off_timeout_entries,
193                        systemSleepTimeout)) : screenOffEntries[screenOffEntries.length - 1];
194        actions.add(new Action.Builder()
195                .key(ActionType.LIST_SYSTEM_SLEEP_TIMEOUT.name())
196                .title(getString(R.string.device_daydreams_screen_off))
197                .description(screenOffDescription)
198                .build());
199        actions.add(new Action.Builder().key(ActionType.TEST.name())
200                .title(getString(R.string.device_daydreams_test)).enabled(mDreamBackend.isEnabled())
201                .build());
202        return actions;
203    }
204
205    private ContentFragment createSubMenuContentFragment(String title, String description) {
206        return ContentFragment.newInstance(title, getString(R.string.device_daydream), description,
207                R.drawable.ic_settings_daydream, getResources().getColor(R.color.icon_background));
208    }
209
210    private ContentFragment createMainMenuContentFragment() {
211        return ContentFragment.newInstance(
212                getString(R.string.device_daydream), getString(R.string.device_display),
213                null, R.drawable.ic_settings_daydream,
214                getResources().getColor(R.color.icon_background));
215    }
216
217    private void updateMainScreen() {
218        ((ActionAdapter) mActionFragment.getAdapter()).setActions(getMainActions());
219    }
220
221    private ArrayList<Action> getListActions(String key, int valuesResId, int entriesResId,
222            long value) {
223        String[] sleepOptionValues = getResources().getStringArray(valuesResId);
224        String[] sleepOptionEntries = getResources().getStringArray(entriesResId);
225
226        ArrayList<Action> actions = new ArrayList<Action>();
227        for (int index = 0; index < sleepOptionValues.length; ++index) {
228            long loopValue = Long.parseLong(sleepOptionValues[index]);
229            Action sleepAction = new Action.Builder().key(key)
230                    .title(sleepOptionEntries[index])
231                    .checked(loopValue == value)
232                    .intent(new Intent().putExtra(EXTRA_LIST_VALUE, loopValue))
233                    .checkSetId(CHECK_SET_ID).build();
234            actions.add(sleepAction);
235        }
236        return actions;
237    }
238
239    private int getDreamTimeoutValue() {
240        return Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT,
241                FALLBACK_SCREEN_TIMEOUT_VALUE);
242    }
243
244    private String getEntry(int valuesResId, int entriesResId, long value) {
245        String[] sleepOptionValues = getResources().getStringArray(valuesResId);
246        String[] sleepOptionEntries = getResources().getStringArray(entriesResId);
247        long sleepValue = getDreamTimeoutValue();
248        for (int index = 0; index < sleepOptionValues.length; ++index) {
249            long loopValue = Long.parseLong(sleepOptionValues[index]);
250            if (loopValue == value) {
251                return sleepOptionEntries[index];
252            }
253        }
254        return null;
255    }
256
257    private int getSystemSleepTimeout() {
258        return Settings.Secure.getInt(getContentResolver(), SLEEP_TIMEOUT,
259                DEFAULT_SLEEP_TIMEOUT_MS);
260    }
261
262    private void setSystemSleepTimeout(int valueMs) {
263        Settings.Secure.putInt(getContentResolver(), SLEEP_TIMEOUT, valueMs);
264    }
265}
266