blob: b177d7e0e019599bae5f5ed26bcf50a7366e463d [file] [log] [blame]
John Spurlockc23929c2014-02-07 14:47:47 -05001/*
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.example.android.demomodecontroller;
18
19import android.app.Activity;
20import android.content.Context;
21import android.content.Intent;
22import android.graphics.Color;
23import android.graphics.PointF;
24import android.os.Bundle;
25import android.os.Handler;
26import android.os.HandlerThread;
27import android.os.SystemClock;
28import android.util.Log;
29import android.view.MotionEvent;
30import android.view.View;
31import android.view.View.OnTouchListener;
32import android.view.ViewConfiguration;
33import android.view.WindowManager;
34import android.widget.Toast;
35
36public class DemoModeController extends Activity implements OnTouchListener {
37 private static final String TAG = DemoModeController.class.getSimpleName();
38 private static final boolean DEBUG = false;
39
40 private final Context mContext = this;
41 private final Handler mHandler = new Handler();
42 private final PointF mLastDown = new PointF();
43
44 private View mContent;
45 private Handler mBackground;
46 private int mTouchSlop;
47 private long mLastDownTime;
48 private boolean mControllingColor;
49 private Toast mToast;
50
51 @Override
52 protected void onCreate(Bundle savedInstanceState) {
53 super.onCreate(savedInstanceState);
54 getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
55 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS // so WM gives us enough room
56 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
57 getActionBar().hide();
58 mContent = new View(mContext);
59 mContent.setBackgroundColor(0xff33b5e5);
60 mContent.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
61 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
62 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
63 mContent.setOnTouchListener(this);
64 setContentView(mContent);
65 mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
66
67 final HandlerThread background = new HandlerThread("background");
68 background.start();
69 mBackground = new Handler(background.getLooper());
70 updateMode();
71 }
72
73 @Override
74 protected void onPause() {
75 super.onPause();
76 exitDemoMode();
77 }
78
79 @Override
80 protected void onResume() {
81 super.onResume();
82 exitDemoMode();
83 mToast = Toast.makeText(mContext, R.string.help_text, Toast.LENGTH_LONG);
84 mToast.show();
85 }
86
87 @Override
88 public boolean onTouch(View v, MotionEvent event) {
89 if (mToast != null) {
90 mToast.cancel();
91 mToast = null;
92 }
93 final int action = event.getAction();
94 if (action == MotionEvent.ACTION_DOWN) {
95 if (DEBUG) Log.d(TAG, "down");
96 mHandler.postDelayed(mLongPressCheck, 500);
97 final long now = SystemClock.uptimeMillis();
98 if (now - mLastDownTime < 200) {
99 toggleMode();
100 }
101 mLastDownTime = now;
102 mLastDown.x = event.getX();
103 mLastDown.y = event.getY();
104 return true;
105 }
106 if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
107 if (DEBUG) Log.d(TAG, "upOrCancel");
108 mControllingColor = false;
109 mHandler.removeCallbacks(mLongPressCheck);
110 }
111 if (action != MotionEvent.ACTION_MOVE) return false;
112
113 float x = event.getX();
114 float y = event.getY();
115 if (Math.abs(mLastDown.x - x) > mTouchSlop || Math.abs(mLastDown.y - y) > mTouchSlop) {
116 mHandler.removeCallbacks(mLongPressCheck);
117 }
118 x = Math.max(x, 0);
119 y = Math.max(y, 0);
120 final int h = mContent.getMeasuredHeight();
121 final int w = mContent.getMeasuredWidth();
122 x = Math.min(x, w);
123 y = Math.min(y, h);
124
125 y = h - y;
126 x = w - x;
127
128 if (mControllingColor) {
129 final float hue = y / (h / 360);
130 final float sat = 1 - (x / (float)w);
131 final float val = x / (float)w;
132 final int color = Color.HSVToColor(new float[]{hue, sat, val});
133 if (DEBUG) Log.d(TAG, String.format("hsv=(%s,%s,%s) argb=#%08x", hue, sat, val, color));
134 mContent.setBackgroundColor(color);
135 return true;
136 }
137
138 final int hh = (int)x / (w / 12);
139 if (hh != mHH) {
140 mHH = hh;
141 mBackground.removeCallbacks(mUpdateClock);
142 mBackground.post(mUpdateClock);
143 }
144
145 final int mm = (int)y / (h / 60);
146 if (mm != mMM) {
147 mMM = mm;
148 mBackground.removeCallbacks(mUpdateClock);
149 mBackground.post(mUpdateClock);
150 }
151
152 final int batteryLevel = (int)y / (h / 101);
153 if (batteryLevel != mBatteryLevel) {
154 mBatteryLevel = batteryLevel;
155 mBackground.removeCallbacks(mUpdateBattery);
156 mBackground.post(mUpdateBattery);
157 }
158
159 final boolean batteryPlugged = x >= w / 2;
160 if (batteryPlugged != mBatteryPlugged) {
161 mBatteryPlugged = batteryPlugged;
162 mBackground.removeCallbacks(mUpdateBattery);
163 mBackground.post(mUpdateBattery);
164 }
165
166 final int mobileLevel = (int)y / (h / 10);
167 if (mobileLevel != mMobileLevel) {
168 mMobileLevel = mobileLevel;
169 mBackground.removeCallbacks(mUpdateMobile);
170 mBackground.post(mUpdateMobile);
171 }
172
173 final int wifiLevel = (int)y / (h / 10);
174 if (wifiLevel != mWifiLevel) {
175 mWifiLevel = wifiLevel;
176 mBackground.removeCallbacks(mUpdateWifi);
177 mBackground.post(mUpdateWifi);
178 }
179
180 final int statusSlots = (int)x / (w / 13);
181 if (statusSlots != mStatusSlots) {
182 mStatusSlots = statusSlots;
183 mBackground.removeCallbacks(mUpdateStatus);
184 mBackground.post(mUpdateStatus);
185 }
186
187 final int networkIcons = (int)x / (w / 4);
188 if (networkIcons != mNetworkIcons) {
189 mNetworkIcons = networkIcons;
190 mBackground.removeCallbacks(mUpdateNetwork);
191 mBackground.post(mUpdateNetwork);
192 }
193
194 final int mobileDataType = (int)y / (h / 9);
195 if (mobileDataType != mMobileDataType) {
196 mMobileDataType = mobileDataType;
197 mBackground.removeCallbacks(mUpdateMobile);
198 mBackground.post(mUpdateMobile);
199 }
200 return true;
201 }
202
203 private void toggleMode() {
204 if (DEBUG) Log.d(TAG, "toggleMode");
205 mBarMode = (mBarMode + 1) % 3;
206 updateMode();
207 }
208
209 private void updateMode() {
210 mBackground.removeCallbacks(mUpdateBarMode);
211 mBackground.post(mUpdateBarMode);
212 }
213
214 private final Runnable mLongPressCheck = new Runnable() {
215 @Override
216 public void run() {
217 if (DEBUG) Log.d(TAG, "mControllingColor = true");
218 mControllingColor = true;
219
220 }
221 };
222
223 private void exitDemoMode() {
224 if (DEBUG) Log.d(TAG, "exitDemoMode");
225 final Intent intent = new Intent("com.android.systemui.demo");
226 intent.putExtra("command", "exit");
227 mContext.sendBroadcast(intent);
228 }
229
230 private int mStatusSlots; // 0 - 12
231 private final Runnable mUpdateStatus = new Runnable() {
232 @Override
233 public void run() {
234 final Intent intent = new Intent("com.android.systemui.demo");
235 intent.putExtra("command", "status");
236 intent.putExtra("volume", mStatusSlots < 1 ? "hide"
237 : mStatusSlots < 2 ? "silent" : "vibrate");
238 intent.putExtra("bluetooth", mStatusSlots < 3 ? "hide"
239 : mStatusSlots < 4 ? "disconnected" : "connected");
240 intent.putExtra("location", mStatusSlots < 5 ? "hide" : "show");
241 intent.putExtra("alarm", mStatusSlots < 6 ? "hide" : "show");
242 intent.putExtra("sync", mStatusSlots < 7 ? "hide" : "show");
243 intent.putExtra("tty", mStatusSlots < 8 ? "hide" : "show");
244 intent.putExtra("eri", mStatusSlots < 9 ? "hide" : "show");
245 intent.putExtra("secure", mStatusSlots < 10 ? "hide" : "show");
246 intent.putExtra("mute", mStatusSlots < 11 ? "hide" : "show");
247 intent.putExtra("speakerphone", mStatusSlots < 12 ? "hide" : "show");
248 mContext.sendBroadcast(intent);
249 }
250 };
251
252 private int mNetworkIcons; // 0:airplane 1:mobile 2:airplane+wifi 3:mobile+wifi
253 private final Runnable mUpdateNetwork = new Runnable() {
254 @Override
255 public void run() {
256 final Intent intent = new Intent("com.android.systemui.demo");
257 intent.putExtra("command", "network");
258 intent.putExtra("airplane", mNetworkIcons % 2 == 0 ? "show" : "hide");
259 intent.putExtra("wifi", mNetworkIcons >= 2 ? "show" : "hide");
260 intent.putExtra("mobile", mNetworkIcons % 2 == 1 ? "show" : "hide");
261 mContext.sendBroadcast(intent);
262 }
263 };
264
265 private int mWifiLevel; // 0 - 4, 5 - 9, fully
266 private final Runnable mUpdateWifi = new Runnable() {
267 @Override
268 public void run() {
269 final Intent intent = new Intent("com.android.systemui.demo");
270 intent.putExtra("command", "network");
271 intent.putExtra("wifi", mNetworkIcons >= 2 ? "show" : "hide");
272 intent.putExtra("level", Integer.toString(mWifiLevel % 5));
273 intent.putExtra("fully", Boolean.toString(mWifiLevel > 4));
274 mContext.sendBroadcast(intent);
275 }
276 };
277
278 private int mMobileLevel; // 0 - 4, 5 - 9, fully
279 private int mMobileDataType; // 0 - 8
280 private static final String getDataType(int dataType) {
281 if (dataType == 1) return "1x";
282 if (dataType == 2) return "3g";
283 if (dataType == 3) return "4g";
284 if (dataType == 4) return "e";
285 if (dataType == 5) return "g";
286 if (dataType == 6) return "h";
287 if (dataType == 7) return "lte";
288 if (dataType == 8) return "roam";
289 return "";
290 }
291 private final Runnable mUpdateMobile = new Runnable() {
292 @Override
293 public void run() {
294 final Intent intent = new Intent("com.android.systemui.demo");
295 intent.putExtra("command", "network");
296 intent.putExtra("mobile", mNetworkIcons % 2 == 1 ? "show" : "hide");
297 intent.putExtra("level", Integer.toString(mMobileLevel % 5));
298 intent.putExtra("fully", Boolean.toString(mMobileLevel > 4));
299 intent.putExtra("datatype", getDataType(mMobileDataType));
300 mContext.sendBroadcast(intent);
301 }
302 };
303
304 private boolean mBatteryPlugged;
305 private int mBatteryLevel; // 0 - 100
306 private final Runnable mUpdateBattery = new Runnable() {
307 @Override
308 public void run() {
309 final Intent intent = new Intent("com.android.systemui.demo");
310 intent.putExtra("command", "battery");
311 intent.putExtra("level", Integer.toString(mBatteryLevel));
312 intent.putExtra("plugged", Boolean.toString(mBatteryPlugged));
313 mContext.sendBroadcast(intent);
314 }
315 };
316
317 private int mHH; // 0 - 11
318 private int mMM; // 0 - 59
319 private final Runnable mUpdateClock = new Runnable() {
320 @Override
321 public void run() {
322 final Intent intent = new Intent("com.android.systemui.demo");
323 intent.putExtra("command", "clock");
324 intent.putExtra("hhmm", String.format("%02d%02d", mHH + 1, mMM));
325 mContext.sendBroadcast(intent);
326 }
327 };
328
329 private int mBarMode; // 0 - 2 (opaque, semi-transparent, translucent)
330 private final Runnable mUpdateBarMode = new Runnable() {
331 @Override
332 public void run() {
333 final Intent intent = new Intent("com.android.systemui.demo");
334 intent.putExtra("command", "bars");
335 intent.putExtra("mode", mBarMode == 1 ? "semi-transparent"
336 : mBarMode == 2 ? "translucent" : "opaque");
337 mContext.sendBroadcast(intent);
338 }
339 };
340}