blob: 03738f5df1a89c9cf01bfe62c1a424062be188e1 [file] [log] [blame]
Dirk Vogt74af2bf2016-05-31 11:21:46 +02001/*
2 * Copyright (C) 2013 The CyanogenMod 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.fairphone.setupwizard.ui;
18
19import android.animation.Animator;
20import android.app.Activity;
21import android.app.WallpaperManager;
22import android.content.Context;
23import android.content.Intent;
24import android.content.pm.ActivityInfo;
25import android.content.res.Resources;
26import android.graphics.Bitmap;
27import android.graphics.Point;
28import android.os.AsyncTask;
29import android.os.Bundle;
30import android.os.Handler;
31import android.os.UserHandle;
32import android.provider.Settings;
33import android.view.MotionEvent;
34import android.view.View;
35import android.view.ViewAnimationUtils;
36import android.view.animation.Animation;
37import android.view.animation.AnimationUtils;
38import android.widget.Button;
39import android.widget.ImageView;
40import android.widget.ProgressBar;
41
42import com.fairphone.setupwizard.R;
43import com.fairphone.setupwizard.SetupWizardApp;
44import com.fairphone.setupwizard.setup.SetupWizard;
45import com.fairphone.setupwizard.setup.Page;
46import com.fairphone.setupwizard.setup.SetupDataCallbacks;
47import com.fairphone.setupwizard.util.EnableAccessibilityController;
48import com.fairphone.setupwizard.util.SetupWizardUtils;
49
50import java.util.ArrayList;
51
52
53public class SetupWizardActivity extends Activity implements SetupDataCallbacks {
54
55 private static final String TAG = SetupWizardActivity.class.getSimpleName();
56
57 private static final int UI_FLAGS = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
58 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
59 | View.SYSTEM_UI_FLAG_IMMERSIVE
60 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
61 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
62
63 private View mRootView;
64 private View mButtonBar;
65 private Button mNextButton;
66 private Button mPrevButton;
67 private ImageView mReveal;
68 private ProgressBar mFinishingProgressBar;
69
70 private EnableAccessibilityController mEnableAccessibilityController;
71
72 private SetupWizard mSetupData;
73
74 private final Handler mHandler = new Handler();
75
76 private volatile boolean mIsFinishing = false;
77
78 private static long sLaunchTime = 0;
79
80 private final ArrayList<Runnable> mFinishRunnables = new ArrayList<Runnable>();
81
82 public void onCreate(Bundle savedInstanceState) {
83 super.onCreate(savedInstanceState);
84 final boolean isOwner = SetupWizardUtils.isOwner();
85 if (!isOwner) {
86 finish();
87 }
88 final View decorView = getWindow().getDecorView();
89 decorView.setSystemUiVisibility(UI_FLAGS);
90 decorView.setOnSystemUiVisibilityChangeListener(
91 new View.OnSystemUiVisibilityChangeListener() {
92
93 @Override
94 public void onSystemUiVisibilityChange(int visibility) {
95 if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
96 decorView.setSystemUiVisibility(UI_FLAGS);
97 }
98 }
99 });
100 if (sLaunchTime == 0) {
101 sLaunchTime = System.nanoTime();
102 }
103 setContentView(R.layout.setup_main);
104 mRootView = findViewById(R.id.root);
105 mRootView.setSystemUiVisibility(UI_FLAGS);
106 mReveal = (ImageView)mRootView.findViewById(R.id.reveal);
107 mButtonBar = findViewById(R.id.button_bar);
108 mFinishingProgressBar = (ProgressBar)findViewById(R.id.finishing_bar);
109 ((SetupWizardApp)getApplicationContext()).disableStatusBar();
110 mSetupData = (SetupWizard)getLastNonConfigurationInstance();
111 if (mSetupData == null) {
112 mSetupData = new SetupWizard(getApplicationContext());
113 }
114 mNextButton = (Button) findViewById(R.id.next_button);
115 mPrevButton = (Button) findViewById(R.id.prev_button);
116 if (mSetupData.isFinished()) {
117 mNextButton.setVisibility(View.INVISIBLE);
118 mPrevButton.setVisibility(View.INVISIBLE);
119 }
120 mSetupData.registerListener(this);
121 mNextButton.setOnClickListener(new View.OnClickListener() {
122 @Override
123 public void onClick(View view) {
124 enableButtonBar(false);
125 mSetupData.onNextPage();
126 }
127 });
128 mPrevButton.setOnClickListener(new View.OnClickListener() {
129 @Override
130 public void onClick(View view) {
131 enableButtonBar(false);
132 mSetupData.onPreviousPage();
133 }
134 });
135 if (savedInstanceState == null) {
136 Page page = mSetupData.getCurrentPage();
137 page.doLoadAction(getFragmentManager(), Page.ACTION_NEXT);
138 }
139 if (savedInstanceState != null && savedInstanceState.containsKey("data")) {
140 mSetupData.load(savedInstanceState.getBundle("data"));
141 }
142 mEnableAccessibilityController =
143 EnableAccessibilityController.getInstance(getApplicationContext());
144 mRootView.setOnTouchListener(new View.OnTouchListener() {
145 @Override
146 public boolean onTouch(View v, MotionEvent event) {
147 boolean consumeIntercept = mEnableAccessibilityController.onInterceptTouchEvent(event);
148 boolean consumeTouch = mEnableAccessibilityController.onTouchEvent(event);
149 return consumeIntercept && consumeTouch;
150 }
151 });
152 registerReceiver(mSetupData, mSetupData.getIntentFilter());
153 }
154
155 @Override
156 protected void onResume() {
157 final View decorView = getWindow().getDecorView();
158 decorView.setSystemUiVisibility(UI_FLAGS);
159 super.onResume();
160 if (isFinishing()) {
161 return;
162 }
163 if (mSetupData.isFinished()) {
164 mHandler.postDelayed(new Runnable() {
165 @Override
166 public void run() {
167 finishSetup();
168 }
169 }, 500);
170 } else {
171 mSetupData.onResume();
172 onPageTreeChanged();
173 enableButtonBar(true);
174 }
175 }
176
177 @Override
178 protected void onPause() {
179 super.onPause();
180 if (mSetupData != null) {
181 mSetupData.onPause();
182 }
183 }
184
185 @Override
186 protected void onDestroy() {
187 super.onDestroy();
188 if (mSetupData != null) {
189 mSetupData.onDestroy();
190 mSetupData.unregisterListener(this);
191 unregisterReceiver(mSetupData);
192 }
193 }
194
195 @Override
196 public Object onRetainNonConfigurationInstance() {
197 return mSetupData;
198 }
199
200 @Override
201 protected void onSaveInstanceState(Bundle outState) {
202 super.onSaveInstanceState(outState);
203 outState.putBundle("data", mSetupData.save());
204 }
205
206 @Override
207 public void onBackPressed() {
208 if (!mSetupData.isFirstPage()) {
209 mSetupData.onPreviousPage();
210 }
211 }
212
213 @Override
214 public void onNextPage() {
215 Page page = mSetupData.getCurrentPage();
216 if (!isFinishing()) {
217 page.doLoadAction(getFragmentManager(), Page.ACTION_NEXT);
218 }
219 }
220
221 @Override
222 public void onPreviousPage() {
223 Page page = mSetupData.getCurrentPage();
224 if (!isFinishing()) {
225 page.doLoadAction(getFragmentManager(), Page.ACTION_PREVIOUS);
226 }
227 }
228
229 @Override
230 public void onPageLoaded(Page page) {
231 updateButtonBar();
232 enableButtonBar(true);
233 }
234
235 @Override
236 public void onPageTreeChanged() {
237 updateButtonBar();
238 }
239
240 private void enableButtonBar(boolean enabled) {
241 mNextButton.setEnabled(enabled);
242 mPrevButton.setEnabled(enabled);
243 }
244
245 private void updateButtonBar() {
246 Page page = mSetupData.getCurrentPage();
247 mNextButton.setText(page.getNextButtonTitleResId());
248 if (page.getPrevButtonTitleResId() != -1) {
249 mPrevButton.setText(page.getPrevButtonTitleResId());
250 } else {
251 mPrevButton.setText("");
252 }
253 if (mSetupData.isFirstPage()) {
254 mPrevButton.setCompoundDrawables(null, null, null, null);
255 mPrevButton.setVisibility(SetupWizardUtils.hasTelephony(this) ?
256 View.VISIBLE : View.INVISIBLE);
257 } else {
258 mPrevButton.setCompoundDrawablesWithIntrinsicBounds(
259 getDrawable(R.drawable.ic_chevron_left_dark),
260 null, null, null);
261 }
262 final Resources resources = getResources();
263 if (mSetupData.isLastPage()) {
264 mButtonBar.setBackgroundResource(R.color.primary);
265 mNextButton.setCompoundDrawablesWithIntrinsicBounds(null, null,
266 getDrawable(R.drawable.ic_chevron_right_wht), null);
267 mNextButton.setTextColor(resources.getColor(R.color.white));
268 mPrevButton.setCompoundDrawablesWithIntrinsicBounds(
269 getDrawable(R.drawable.ic_chevron_left_wht), null,
270 null, null);
271 mPrevButton.setTextColor(resources.getColor(R.color.white));
272 } else {
273 mButtonBar.setBackgroundResource(R.color.button_bar_background);
274 mNextButton.setCompoundDrawablesWithIntrinsicBounds(null, null,
275 getDrawable(R.drawable.ic_chevron_right_dark), null);
276 mNextButton.setTextColor(resources.getColorStateList(R.color.button_bar_text));
277 mPrevButton.setTextColor(resources.getColorStateList(R.color.button_bar_text));
278 }
279 }
280
281 @Override
282 public Page getPage(String key) {
283 return mSetupData.getPage(key);
284 }
285
286 @Override
287 public Page getPage(int key) {
288 return mSetupData.getPage(key);
289 }
290
291 @Override
292 public boolean isCurrentPage(Page page) {
293 return mSetupData.isCurrentPage(page);
294 }
295
296 @Override
297 public void addFinishRunnable(Runnable runnable) {
298 mFinishRunnables.add(runnable);
299 }
300
301 @Override
302 public void onFinish() {
303 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
304 Animation fadeOut = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
305 mNextButton.startAnimation(fadeOut);
306 mNextButton.setVisibility(View.INVISIBLE);
307 mPrevButton.startAnimation(fadeOut);
308 mPrevButton.setVisibility(View.INVISIBLE);
309 final SetupWizardApp setupWizardApp = (SetupWizardApp)getApplication();
310 setupWizardApp.enableStatusBar();
311 setupWizardApp.enableCaptivePortalDetection();
312 Animation fadeIn = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
313 mFinishingProgressBar.setVisibility(View.VISIBLE);
314 mFinishingProgressBar.setIndeterminate(true);
315 mFinishingProgressBar.startAnimation(fadeIn);
316 mSetupData.finishPages();
317 }
318
319 public void onFinish(boolean isSuccess) {
320 if (isResumed()) {
321 mHandler.post(new Runnable() {
322 @Override
323 public void run() {
324 finishSetup();
325 }
326 });
327 }
328 }
329
330 public void onProgress(int progress) {
331 if (progress > 0) {
332 mFinishingProgressBar.setIndeterminate(false);
333 mFinishingProgressBar.setProgress(progress);
334 }
335 }
336
337 @Override
338 public void finishSetup() {
339 if (!mIsFinishing) {
340 final SetupWizardApp setupWizardApp = (SetupWizardApp)getApplication();
341 setupWizardApp.sendStickyBroadcastAsUser(
342 new Intent(SetupWizardApp.ACTION_FINISHED),
343 UserHandle.getCallingUserHandle());
344 mIsFinishing = true;
345 setupRevealImage();
346 }
347 }
348
349 @Override
350 public void finish() {
351 super.finish();
352 overridePendingTransition(R.anim.translucent_enter, R.anim.translucent_exit);
353 }
354
355 private void setupRevealImage() {
356 mFinishingProgressBar.setProgress(100);
357 Animation fadeOut = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
358 mFinishingProgressBar.startAnimation(fadeOut);
359 mFinishingProgressBar.setVisibility(View.INVISIBLE);
360
361 final Point p = new Point();
362 getWindowManager().getDefaultDisplay().getRealSize(p);
363 final WallpaperManager wallpaperManager =
364 WallpaperManager.getInstance(SetupWizardActivity.this);
365 wallpaperManager.forgetLoadedWallpaper();
366 final Bitmap wallpaper = wallpaperManager.getBitmap();
367 Bitmap cropped = null;
368 if (wallpaper != null) {
369 cropped = Bitmap.createBitmap(wallpaper, 0,
370 0, Math.min(p.x, wallpaper.getWidth()),
371 Math.min(p.y, wallpaper.getHeight()));
372 }
373 if (cropped != null) {
374 mReveal.setScaleType(ImageView.ScaleType.CENTER_CROP);
375 mReveal.setImageBitmap(cropped);
376 } else {
377 mReveal.setBackground(wallpaperManager
378 .getBuiltInDrawable(p.x, p.y, false, 0, 0));
379 }
380 animateOut();
381 }
382
383 private void animateOut() {
384 int cx = (mReveal.getLeft() + mReveal.getRight()) / 2;
385 int cy = (mReveal.getTop() + mReveal.getBottom()) / 2;
386 int finalRadius = Math.max(mReveal.getWidth(), mReveal.getHeight());
387 Animator anim =
388 ViewAnimationUtils.createCircularReveal(mReveal, cx, cy, 0, finalRadius);
389 anim.setDuration(900);
390 anim.addListener(new Animator.AnimatorListener() {
391 @Override
392 public void onAnimationStart(Animator animation) {
393 mReveal.setVisibility(View.VISIBLE);
394 }
395
396 @Override
397 public void onAnimationEnd(Animator animation) {
398 mHandler.post(new Runnable() {
399 @Override
400 public void run() {
401 finalizeSetup();
402 }
403 });
404 }
405
406 @Override
407 public void onAnimationCancel(Animator animation) {}
408
409 @Override
410 public void onAnimationRepeat(Animator animation) {}
411 });
412 anim.start();
413 }
414
415 private void finalizeSetup() {
416 mFinishRunnables.add(new Runnable() {
417 @Override
418 public void run() {
419 Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
420 Settings.Secure.putInt(getContentResolver(),
421 Settings.Secure.USER_SETUP_COMPLETE, 1);
422 if (mEnableAccessibilityController != null) {
423 mEnableAccessibilityController.onDestroy();
424 }
425 final WallpaperManager wallpaperManager =
426 WallpaperManager.getInstance(SetupWizardActivity.this);
427 wallpaperManager.forgetLoadedWallpaper();
428 }
429 });
430 new FinishTask(this, mFinishRunnables).execute();
431 }
432
433 private static class FinishTask extends AsyncTask<Void, Void, Boolean> {
434
435 private final SetupWizardActivity mActivity;
436 private final ArrayList<Runnable> mFinishRunnables;
437
438 public FinishTask(SetupWizardActivity activity,
439 ArrayList<Runnable> finishRunnables) {
440 mActivity = activity;
441 mFinishRunnables = finishRunnables;
442 }
443
444 @Override
445 protected Boolean doInBackground(Void... params) {
446 for (Runnable runnable : mFinishRunnables) {
447 runnable.run();
448 }
449 SetupWizardUtils.disableSetupWizard(mActivity);
450 return Boolean.TRUE;
451 }
452
453 @Override
454 protected void onPostExecute(Boolean aBoolean) {
455 Intent intent = new Intent(Intent.ACTION_MAIN);
456 intent.addCategory(Intent.CATEGORY_HOME);
457 mActivity.startActivity(intent);
458 mActivity.finish();
459 }
460 }
461}