blob: 41ef28186cf9bfc8a4d891b44bb52f7921cb4f16 [file] [log] [blame]
Lujiang Xue0c6dd2d2018-10-02 13:46:00 -07001/*
2 * Copyright (C) 2018 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.car.settings;
18
19import android.app.Activity;
20import android.app.WallpaperColors;
21import android.app.WallpaperManager;
22import android.app.WallpaperManager.OnColorsChangedListener;
23import android.content.BroadcastReceiver;
24import android.content.Context;
25import android.content.Intent;
26import android.content.IntentFilter;
27import android.content.pm.ResolveInfo;
28import android.os.Bundle;
29import android.os.Handler;
30import android.os.Message;
31import android.os.PowerManager;
32import android.os.SystemClock;
33import android.os.UserHandle;
34import android.os.UserManager;
35import android.provider.Settings;
36import android.view.View;
37import android.view.WindowManager.LayoutParams;
38import android.view.animation.AnimationUtils;
39
40import com.android.car.settings.common.Logger;
41
42import java.util.Objects;
43
44/**
45 * Copied over from phone settings. This covers the fallback case where no launcher is available.
46 */
47public class FallbackHome extends Activity {
48 private static final Logger LOG = new Logger(FallbackHome.class);
49 private static final int PROGRESS_TIMEOUT = 2000;
50
51 private boolean mProvisioned;
52 private WallpaperManager mWallManager;
53
54 private final Runnable mProgressTimeoutRunnable = () -> {
55 View v = getLayoutInflater().inflate(
56 R.layout.fallback_home_finishing_boot, null /* root */);
57 setContentView(v);
58 v.setAlpha(0f);
59 v.animate()
60 .alpha(1f)
61 .setDuration(500)
62 .setInterpolator(AnimationUtils.loadInterpolator(
63 this, android.R.interpolator.fast_out_slow_in))
64 .start();
65 getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
66 };
67
68 private final OnColorsChangedListener mColorsChangedListener = new OnColorsChangedListener() {
69 @Override
70 public void onColorsChanged(WallpaperColors colors, int which) {
71 if (colors != null) {
72 View decorView = getWindow().getDecorView();
73 decorView.setSystemUiVisibility(
74 updateVisibilityFlagsFromColors(colors, decorView.getSystemUiVisibility()));
75 mWallManager.removeOnColorsChangedListener(this);
76 }
77 }
78 };
79
80 @Override
81 protected void onCreate(Bundle savedInstanceState) {
82 super.onCreate(savedInstanceState);
83
84 // Set ourselves totally black before the device is provisioned so that
85 // we don't flash the wallpaper before SUW
86 mProvisioned = Settings.Global.getInt(getContentResolver(),
87 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
88 int flags;
89 if (!mProvisioned) {
90 setTheme(R.style.FallbackHome_SetupWizard);
91 flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
92 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
93 } else {
94 flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
95 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
96 }
97
98 // Set the system ui flags to light status bar if the wallpaper supports dark text to match
99 // current system ui color tints. Use a listener to wait for colors if not ready yet.
100 mWallManager = getSystemService(WallpaperManager.class);
101 if (mWallManager == null) {
102 LOG.w("Wallpaper manager isn't ready, can't listen to color changes!");
103 } else {
104 WallpaperColors colors = mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
105 if (colors == null) {
106 mWallManager.addOnColorsChangedListener(mColorsChangedListener, null /* handler */);
107 } else {
108 flags = updateVisibilityFlagsFromColors(colors, flags);
109 }
110 }
111 getWindow().getDecorView().setSystemUiVisibility(flags);
112
113 registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
114 maybeFinish();
115 }
116
117 @Override
118 protected void onResume() {
119 super.onResume();
120 if (mProvisioned) {
121 mHandler.postDelayed(mProgressTimeoutRunnable, PROGRESS_TIMEOUT);
122 }
123 }
124
125 @Override
126 protected void onPause() {
127 super.onPause();
128 mHandler.removeCallbacks(mProgressTimeoutRunnable);
129 }
130
131 protected void onDestroy() {
132 super.onDestroy();
133 unregisterReceiver(mReceiver);
134 if (mWallManager != null) {
135 mWallManager.removeOnColorsChangedListener(mColorsChangedListener);
136 }
137 }
138
139 private BroadcastReceiver mReceiver = new BroadcastReceiver() {
140 @Override
141 public void onReceive(Context context, Intent intent) {
142 maybeFinish();
143 }
144 };
145
146 private void maybeFinish() {
147 if (getSystemService(UserManager.class).isUserUnlocked()) {
148 final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
149 .addCategory(Intent.CATEGORY_HOME);
150 final ResolveInfo homeInfo = getPackageManager().resolveActivity(homeIntent, 0);
151 if (Objects.equals(getPackageName(), homeInfo.activityInfo.packageName)) {
152 if (UserManager.isSplitSystemUser()
153 && UserHandle.myUserId() == UserHandle.USER_SYSTEM) {
154 // This avoids the situation where the system user has no home activity after
155 // SUW and this activity continues to throw out warnings. See b/28870689.
156 return;
157 }
158 LOG.d("User unlocked but no home; let's hope someone enables one soon?");
159 mHandler.sendEmptyMessageDelayed(0, 500);
160 } else {
161 LOG.d("User unlocked and real home found; let's go!");
162 getSystemService(PowerManager.class).userActivity(
163 SystemClock.uptimeMillis(), false);
164 finish();
165 }
166 }
167 }
168
169 private int updateVisibilityFlagsFromColors(WallpaperColors colors, int flags) {
170 if ((colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0) {
171 return flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
172 | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
173 }
174 return flags & ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
175 & ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
176 }
177
178 private Handler mHandler = new Handler() {
179 @Override
180 public void handleMessage(Message msg) {
181 maybeFinish();
182 }
183 };
184}