blob: 80d36a1a4e54babac49bdb60aee09751fb023869 [file] [log] [blame]
Jorim Jaggia6310292014-04-16 14:11:52 +02001/*
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.systemui.statusbar.phone;
18
Selim Cinek5f145022016-08-02 16:00:12 -070019import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
20import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
Jason Monk2a6ea9c2017-01-26 11:14:51 -050021
Lucas Dupin07ed3df2019-03-26 21:23:59 -070022import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
Jason Monk1d9632d2017-02-09 13:20:04 -080023import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
Jason Monkd6fa02f2017-01-25 18:26:50 -050024import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
Jason Monk1d9632d2017-02-09 13:20:04 -080025import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
Jason Monkd6fa02f2017-01-25 18:26:50 -050026import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_UNLOCK;
Selim Cinek5f145022016-08-02 16:00:12 -070027
Jorim Jaggid9449862015-05-29 14:49:08 -070028import android.app.ActivityManager;
Robert Carrfd10cd12016-06-29 16:41:50 -070029import android.app.ActivityOptions;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070030import android.app.ActivityTaskManager;
Jorim Jaggia6310292014-04-16 14:11:52 +020031import android.app.admin.DevicePolicyManager;
32import android.content.BroadcastReceiver;
Jorim Jaggid9449862015-05-29 14:49:08 -070033import android.content.ComponentName;
Jorim Jaggia6310292014-04-16 14:11:52 +020034import android.content.Context;
35import android.content.Intent;
36import android.content.IntentFilter;
Jorim Jaggid9449862015-05-29 14:49:08 -070037import android.content.ServiceConnection;
38import android.content.pm.ActivityInfo;
Jorim Jaggi97b63c42014-05-02 23:03:34 +020039import android.content.pm.PackageManager;
Adrian Roosa06905b2014-05-28 12:13:48 +020040import android.content.pm.ResolveInfo;
Jorim Jaggie210cc82014-08-12 23:44:59 +020041import android.content.res.Configuration;
Evan Roskyd388c752016-11-15 13:59:06 -080042import android.graphics.drawable.Drawable;
Yorke Lee583a20242014-08-12 18:47:08 -070043import android.os.AsyncTask;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020044import android.os.Bundle;
Jorim Jaggid9449862015-05-29 14:49:08 -070045import android.os.IBinder;
46import android.os.Message;
47import android.os.Messenger;
Jorim Jaggia6310292014-04-16 14:11:52 +020048import android.os.RemoteException;
49import android.os.UserHandle;
50import android.provider.MediaStore;
Jorim Jaggid9449862015-05-29 14:49:08 -070051import android.service.media.CameraPrewarmService;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070052import android.telecom.TelecomManager;
Jason Monkd6fa02f2017-01-25 18:26:50 -050053import android.text.TextUtils;
Jorim Jaggia6310292014-04-16 14:11:52 +020054import android.util.AttributeSet;
55import android.util.Log;
Jorim Jaggie210cc82014-08-12 23:44:59 +020056import android.util.TypedValue;
Jorim Jaggia6310292014-04-16 14:11:52 +020057import android.view.View;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +020058import android.view.ViewGroup;
Adrian Roos7e58a082018-03-09 16:40:56 +010059import android.view.WindowInsets;
Robert Carrfd10cd12016-06-29 16:41:50 -070060import android.view.WindowManager;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020061import android.view.accessibility.AccessibilityNodeInfo;
Jorim Jaggia6310292014-04-16 14:11:52 +020062import android.widget.FrameLayout;
Jorim Jaggie210cc82014-08-12 23:44:59 +020063import android.widget.TextView;
Adrian Roosa06905b2014-05-28 12:13:48 +020064
Lucas Dupincea7dee2018-10-16 12:43:37 -070065import com.android.internal.annotations.VisibleForTesting;
Adrian Roosa06905b2014-05-28 12:13:48 +020066import com.android.internal.widget.LockPatternUtils;
67import com.android.keyguard.KeyguardUpdateMonitor;
68import com.android.keyguard.KeyguardUpdateMonitorCallback;
Mark Renouf6b2331c2019-03-21 13:40:08 -040069import com.android.systemui.ActivityIntentHelper;
Jason Monk9c7844c2017-01-18 15:21:53 -050070import com.android.systemui.Dependency;
Winsonc0d70582016-01-29 10:24:39 -080071import com.android.systemui.Interpolators;
Jorim Jaggia6310292014-04-16 14:11:52 +020072import com.android.systemui.R;
Selim Cineke70d6532015-04-24 16:46:13 -070073import com.android.systemui.assist.AssistManager;
Lucas Dupin117365d2018-10-03 15:49:46 -070074import com.android.systemui.plugins.ActivityStarter;
Jason Monkb59f46f2016-09-27 12:29:18 -040075import com.android.systemui.plugins.IntentButtonProvider;
76import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
77import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
Selim Cinekbaa23272014-07-08 18:01:07 +020078import com.android.systemui.statusbar.KeyguardAffordanceView;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020079import com.android.systemui.statusbar.KeyguardIndicationController;
80import com.android.systemui.statusbar.policy.AccessibilityController;
Jason Monk1d9632d2017-02-09 13:20:04 -080081import com.android.systemui.statusbar.policy.ExtensionController;
82import com.android.systemui.statusbar.policy.ExtensionController.Extension;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020083import com.android.systemui.statusbar.policy.FlashlightController;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +020084import com.android.systemui.statusbar.policy.PreviewInflater;
Jason Monk1d9632d2017-02-09 13:20:04 -080085import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory;
Jason Monkd6fa02f2017-01-25 18:26:50 -050086import com.android.systemui.tuner.TunerService;
Jorim Jaggia6310292014-04-16 14:11:52 +020087
88/**
89 * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
90 * text.
91 */
Selim Cinek4c6969a2014-05-26 19:22:17 +020092public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
Jorim Jaggib2e104f2014-08-15 18:12:36 +020093 UnlockMethodCache.OnUnlockMethodChangedListener,
Lucas Dupin2e838ac2019-04-17 16:50:58 -070094 AccessibilityController.AccessibilityStateChangedCallback {
Jorim Jaggia6310292014-04-16 14:11:52 +020095
Jason Monk2a6ea9c2017-01-26 11:14:51 -050096 final static String TAG = "StatusBar/KeyguardBottomAreaView";
Jorim Jaggia6310292014-04-16 14:11:52 +020097
Jorim Jaggi40aa8812015-09-23 12:59:22 -070098 public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
99 public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
100 public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
Jonathan Solnita4138162017-05-10 21:06:04 -0700101 public static final String CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = "lift_to_launch_ml";
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700102
103 public static final String EXTRA_CAMERA_LAUNCH_SOURCE
104 = "com.android.systemui.camera_launch_source";
105
Jason Monkb59f46f2016-09-27 12:29:18 -0400106 private static final String LEFT_BUTTON_PLUGIN
107 = "com.android.systemui.action.PLUGIN_LOCKSCREEN_LEFT_BUTTON";
108 private static final String RIGHT_BUTTON_PLUGIN
109 = "com.android.systemui.action.PLUGIN_LOCKSCREEN_RIGHT_BUTTON";
110
Adrian Roosa06905b2014-05-28 12:13:48 +0200111 private static final Intent SECURE_CAMERA_INTENT =
112 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
113 .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Selim Cinek372d1bd2015-08-14 13:19:37 -0700114 public static final Intent INSECURE_CAMERA_INTENT =
Adrian Roosa06905b2014-05-28 12:13:48 +0200115 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200116 private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100117 private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
118 private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200119
Jason Monkb59f46f2016-09-27 12:29:18 -0400120 private KeyguardAffordanceView mRightAffordanceView;
Selim Cineke70d6532015-04-24 16:46:13 -0700121 private KeyguardAffordanceView mLeftAffordanceView;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100122 private ViewGroup mIndicationArea;
123 private TextView mEnterpriseDisclosure;
Jorim Jaggie210cc82014-08-12 23:44:59 +0200124 private TextView mIndicationText;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200125 private ViewGroup mPreviewContainer;
Philip Quinnb86efa42017-07-08 12:59:24 -0700126 private ViewGroup mOverlayContainer;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200127
Selim Cineke70d6532015-04-24 16:46:13 -0700128 private View mLeftPreview;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200129 private View mCameraPreview;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200130
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200131 private ActivityStarter mActivityStarter;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200132 private UnlockMethodCache mUnlockMethodCache;
Adrian Roosa06905b2014-05-28 12:13:48 +0200133 private LockPatternUtils mLockPatternUtils;
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200134 private FlashlightController mFlashlightController;
Jorim Jaggi781c29c2014-08-05 20:39:15 +0200135 private PreviewInflater mPreviewInflater;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200136 private AccessibilityController mAccessibilityController;
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500137 private StatusBar mStatusBar;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700138 private KeyguardAffordanceHelper mAffordanceHelper;
Adrian Roos2fe592d2014-05-17 03:11:59 +0200139
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700140 private boolean mUserSetupComplete;
Jorim Jaggid9449862015-05-29 14:49:08 -0700141 private boolean mPrewarmBound;
142 private Messenger mPrewarmMessenger;
143 private final ServiceConnection mPrewarmConnection = new ServiceConnection() {
144
145 @Override
146 public void onServiceConnected(ComponentName name, IBinder service) {
147 mPrewarmMessenger = new Messenger(service);
Jorim Jaggid9449862015-05-29 14:49:08 -0700148 }
149
150 @Override
151 public void onServiceDisconnected(ComponentName name) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700152 mPrewarmMessenger = null;
153 }
154 };
155
Selim Cineke70d6532015-04-24 16:46:13 -0700156 private boolean mLeftIsVoiceAssist;
157 private AssistManager mAssistManager;
Evan Roskyd388c752016-11-15 13:59:06 -0800158 private Drawable mLeftAssistIcon;
Adrian Roos72cc3702014-09-18 17:25:09 +0200159
Jason Monkb59f46f2016-09-27 12:29:18 -0400160 private IntentButton mRightButton = new DefaultRightButton();
Jason Monk1d9632d2017-02-09 13:20:04 -0800161 private Extension<IntentButton> mRightExtension;
Jason Monkd6fa02f2017-01-25 18:26:50 -0500162 private String mRightButtonStr;
Jason Monkb59f46f2016-09-27 12:29:18 -0400163 private IntentButton mLeftButton = new DefaultLeftButton();
Jason Monk1d9632d2017-02-09 13:20:04 -0800164 private Extension<IntentButton> mLeftExtension;
Jason Monkd6fa02f2017-01-25 18:26:50 -0500165 private String mLeftButtonStr;
Adrian Roos91ba3072017-02-14 16:50:46 +0100166 private boolean mDozing;
Lucas Dupin4272f442018-01-13 22:00:35 -0800167 private int mIndicationBottomMargin;
Lucas Dupin4272f442018-01-13 22:00:35 -0800168 private float mDarkAmount;
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700169 private int mBurnInXOffset;
170 private int mBurnInYOffset;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400171 private ActivityIntentHelper mActivityIntentHelper;
Jason Monkb59f46f2016-09-27 12:29:18 -0400172
Jorim Jaggia6310292014-04-16 14:11:52 +0200173 public KeyguardBottomAreaView(Context context) {
Adrian Roos2e3ccbb2014-08-19 22:23:37 +0200174 this(context, null);
Jorim Jaggia6310292014-04-16 14:11:52 +0200175 }
176
177 public KeyguardBottomAreaView(Context context, AttributeSet attrs) {
Adrian Roos2e3ccbb2014-08-19 22:23:37 +0200178 this(context, attrs, 0);
Jorim Jaggia6310292014-04-16 14:11:52 +0200179 }
180
181 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) {
Adrian Roos2e3ccbb2014-08-19 22:23:37 +0200182 this(context, attrs, defStyleAttr, 0);
Jorim Jaggia6310292014-04-16 14:11:52 +0200183 }
184
185 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
186 int defStyleRes) {
187 super(context, attrs, defStyleAttr, defStyleRes);
188 }
189
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200190 private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
191 @Override
192 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
193 super.onInitializeAccessibilityNodeInfo(host, info);
194 String label = null;
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700195 if (host == mRightAffordanceView) {
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200196 label = getResources().getString(R.string.camera_label);
Selim Cineke70d6532015-04-24 16:46:13 -0700197 } else if (host == mLeftAffordanceView) {
198 if (mLeftIsVoiceAssist) {
199 label = getResources().getString(R.string.voice_assist_label);
200 } else {
201 label = getResources().getString(R.string.phone_label);
202 }
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200203 }
204 info.addAction(new AccessibilityAction(ACTION_CLICK, label));
205 }
206
207 @Override
208 public boolean performAccessibilityAction(View host, int action, Bundle args) {
209 if (action == ACTION_CLICK) {
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700210 if (host == mRightAffordanceView) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700211 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200212 return true;
Selim Cineke70d6532015-04-24 16:46:13 -0700213 } else if (host == mLeftAffordanceView) {
214 launchLeftAffordance();
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200215 return true;
216 }
217 }
218 return super.performAccessibilityAction(host, action, args);
219 }
220 };
221
Lucas Dupincea7dee2018-10-16 12:43:37 -0700222 public void initFrom(KeyguardBottomAreaView oldBottomArea) {
Lucas Dupincea7dee2018-10-16 12:43:37 -0700223 setStatusBar(oldBottomArea.mStatusBar);
224 }
225
Jorim Jaggia6310292014-04-16 14:11:52 +0200226 @Override
227 protected void onFinishInflate() {
228 super.onFinishInflate();
Adrian Roosa06905b2014-05-28 12:13:48 +0200229 mLockPatternUtils = new LockPatternUtils(mContext);
Mark Renouf6b2331c2019-03-21 13:40:08 -0400230 mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext),
231 new ActivityIntentHelper(mContext));
Alan Viverette51efddb2017-04-05 10:00:01 -0400232 mPreviewContainer = findViewById(R.id.preview_container);
Philip Quinnb86efa42017-07-08 12:59:24 -0700233 mOverlayContainer = findViewById(R.id.overlay_container);
Alan Viverette51efddb2017-04-05 10:00:01 -0400234 mRightAffordanceView = findViewById(R.id.camera_button);
235 mLeftAffordanceView = findViewById(R.id.left_button);
Alan Viverette51efddb2017-04-05 10:00:01 -0400236 mIndicationArea = findViewById(R.id.keyguard_indication_area);
237 mEnterpriseDisclosure = findViewById(
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100238 R.id.keyguard_indication_enterprise_disclosure);
Alan Viverette51efddb2017-04-05 10:00:01 -0400239 mIndicationText = findViewById(R.id.keyguard_indication_text);
Lucas Dupin4272f442018-01-13 22:00:35 -0800240 mIndicationBottomMargin = getResources().getDimensionPixelSize(
241 R.dimen.keyguard_indication_margin_bottom);
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700242 mBurnInYOffset = getResources().getDimensionPixelSize(
243 R.dimen.default_burn_in_prevention_offset);
Jorim Jaggia6310292014-04-16 14:11:52 +0200244 updateCameraVisibility();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200245 mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
246 mUnlockMethodCache.addListener(this);
Selim Cinekbaa23272014-07-08 18:01:07 +0200247 setClipChildren(false);
248 setClipToPadding(false);
Selim Cineke70d6532015-04-24 16:46:13 -0700249 inflateCameraPreview();
Jason Monkb59f46f2016-09-27 12:29:18 -0400250 mRightAffordanceView.setOnClickListener(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700251 mLeftAffordanceView.setOnClickListener(this);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200252 initAccessibility();
Jason Monk9c7844c2017-01-18 15:21:53 -0500253 mActivityStarter = Dependency.get(ActivityStarter.class);
254 mFlashlightController = Dependency.get(FlashlightController.class);
255 mAccessibilityController = Dependency.get(AccessibilityController.class);
256 mAssistManager = Dependency.get(AssistManager.class);
Mark Renouf6b2331c2019-03-21 13:40:08 -0400257 mActivityIntentHelper = new ActivityIntentHelper(getContext());
Jason Monk9c7844c2017-01-18 15:21:53 -0500258 updateLeftAffordance();
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200259 }
260
Jason Monkb59f46f2016-09-27 12:29:18 -0400261 @Override
262 protected void onAttachedToWindow() {
263 super.onAttachedToWindow();
Jason Monk9ef73072017-01-27 13:32:51 -0500264 mAccessibilityController.addStateChangedCallback(this);
Jason Monk1d9632d2017-02-09 13:20:04 -0800265 mRightExtension = Dependency.get(ExtensionController.class).newExtension(IntentButton.class)
266 .withPlugin(IntentButtonProvider.class, RIGHT_BUTTON_PLUGIN,
267 p -> p.getIntentButton())
268 .withTunerFactory(new LockButtonFactory(mContext, LOCKSCREEN_RIGHT_BUTTON))
269 .withDefault(() -> new DefaultRightButton())
270 .withCallback(button -> setRightButton(button))
271 .build();
272 mLeftExtension = Dependency.get(ExtensionController.class).newExtension(IntentButton.class)
273 .withPlugin(IntentButtonProvider.class, LEFT_BUTTON_PLUGIN,
274 p -> p.getIntentButton())
275 .withTunerFactory(new LockButtonFactory(mContext, LOCKSCREEN_LEFT_BUTTON))
276 .withDefault(() -> new DefaultLeftButton())
277 .withCallback(button -> setLeftButton(button))
278 .build();
Selim Cinek9a105312017-07-21 17:16:05 -0700279 final IntentFilter filter = new IntentFilter();
280 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
281 getContext().registerReceiverAsUser(mDevicePolicyReceiver,
282 UserHandle.ALL, filter, null, null);
283 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
Jason Monkb59f46f2016-09-27 12:29:18 -0400284 }
285
286 @Override
287 protected void onDetachedFromWindow() {
288 super.onDetachedFromWindow();
Jason Monk9ef73072017-01-27 13:32:51 -0500289 mAccessibilityController.removeStateChangedCallback(this);
Jason Monk1d9632d2017-02-09 13:20:04 -0800290 mRightExtension.destroy();
291 mLeftExtension.destroy();
Selim Cinek9a105312017-07-21 17:16:05 -0700292 getContext().unregisterReceiver(mDevicePolicyReceiver);
293 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
Jason Monkb59f46f2016-09-27 12:29:18 -0400294 }
295
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200296 private void initAccessibility() {
Selim Cineke70d6532015-04-24 16:46:13 -0700297 mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
Jason Monkb59f46f2016-09-27 12:29:18 -0400298 mRightAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
Jorim Jaggia6310292014-04-16 14:11:52 +0200299 }
300
Jorim Jaggie210cc82014-08-12 23:44:59 +0200301 @Override
302 protected void onConfigurationChanged(Configuration newConfig) {
303 super.onConfigurationChanged(newConfig);
Lucas Dupin4272f442018-01-13 22:00:35 -0800304 mIndicationBottomMargin = getResources().getDimensionPixelSize(
Jorim Jaggie210cc82014-08-12 23:44:59 +0200305 R.dimen.keyguard_indication_margin_bottom);
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700306 mBurnInYOffset = getResources().getDimensionPixelSize(
307 R.dimen.default_burn_in_prevention_offset);
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100308 MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams();
Lucas Dupin4272f442018-01-13 22:00:35 -0800309 if (mlp.bottomMargin != mIndicationBottomMargin) {
310 mlp.bottomMargin = mIndicationBottomMargin;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100311 mIndicationArea.setLayoutParams(mlp);
Jorim Jaggie210cc82014-08-12 23:44:59 +0200312 }
313
314 // Respect font size setting.
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100315 mEnterpriseDisclosure.setTextSize(TypedValue.COMPLEX_UNIT_PX,
316 getResources().getDimensionPixelSize(
317 com.android.internal.R.dimen.text_size_small_material));
Jorim Jaggie210cc82014-08-12 23:44:59 +0200318 mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
319 getResources().getDimensionPixelSize(
320 com.android.internal.R.dimen.text_size_small_material));
Selim Cinek6ebba592016-05-31 15:28:28 -0700321
Jason Monkb59f46f2016-09-27 12:29:18 -0400322 ViewGroup.LayoutParams lp = mRightAffordanceView.getLayoutParams();
Selim Cinek6ebba592016-05-31 15:28:28 -0700323 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
324 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
Jason Monkb59f46f2016-09-27 12:29:18 -0400325 mRightAffordanceView.setLayoutParams(lp);
326 updateRightAffordanceIcon();
Selim Cinek6ebba592016-05-31 15:28:28 -0700327
Selim Cinek6ebba592016-05-31 15:28:28 -0700328 lp = mLeftAffordanceView.getLayoutParams();
329 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
330 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
331 mLeftAffordanceView.setLayoutParams(lp);
332 updateLeftAffordanceIcon();
Jorim Jaggie210cc82014-08-12 23:44:59 +0200333 }
334
Jason Monkb59f46f2016-09-27 12:29:18 -0400335 private void updateRightAffordanceIcon() {
336 IconState state = mRightButton.getIcon();
Adrian Roos674b8ea2017-05-25 12:33:17 -0700337 mRightAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
Lucas Dupin3704d532019-04-18 19:23:06 -0700338 if (state.drawable != mRightAffordanceView.getDrawable()
339 || state.tint != mRightAffordanceView.shouldTint()) {
340 mRightAffordanceView.setImageDrawable(state.drawable, state.tint);
341 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400342 mRightAffordanceView.setContentDescription(state.contentDescription);
343 }
344
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500345 public void setStatusBar(StatusBar statusBar) {
346 mStatusBar = statusBar;
Dan Sandlere163a642015-03-01 22:58:32 -0500347 updateCameraVisibility(); // in case onFinishInflate() was called too early
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200348 }
349
Jorim Jaggidadafd42016-09-30 07:20:25 -0700350 public void setAffordanceHelper(KeyguardAffordanceHelper affordanceHelper) {
351 mAffordanceHelper = affordanceHelper;
352 }
353
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700354 public void setUserSetupComplete(boolean userSetupComplete) {
355 mUserSetupComplete = userSetupComplete;
356 updateCameraVisibility();
357 updateLeftAffordanceIcon();
358 }
359
Adrian Roosa06905b2014-05-28 12:13:48 +0200360 private Intent getCameraIntent() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400361 return mRightButton.getIntent();
Adrian Roosa06905b2014-05-28 12:13:48 +0200362 }
363
Zhentao Sun04f97402015-08-26 17:37:30 -0700364 /**
365 * Resolves the intent to launch the camera application.
366 */
367 public ResolveInfo resolveCameraIntent() {
368 return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
369 PackageManager.MATCH_DEFAULT_ONLY,
370 KeyguardUpdateMonitor.getCurrentUser());
371 }
372
Jorim Jaggia6310292014-04-16 14:11:52 +0200373 private void updateCameraVisibility() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400374 if (mRightAffordanceView == null) {
Dan Sandlere163a642015-03-01 22:58:32 -0500375 // Things are not set up yet; reply hazy, ask again later
376 return;
377 }
Adrian Roos91ba3072017-02-14 16:50:46 +0100378 mRightAffordanceView.setVisibility(!mDozing && mRightButton.getIcon().isVisible
Jason Monkb59f46f2016-09-27 12:29:18 -0400379 ? View.VISIBLE : View.GONE);
Jorim Jaggia6310292014-04-16 14:11:52 +0200380 }
381
Evan Roskyd388c752016-11-15 13:59:06 -0800382 /**
383 * Set an alternate icon for the left assist affordance (replace the mic icon)
384 */
385 public void setLeftAssistIcon(Drawable drawable) {
386 mLeftAssistIcon = drawable;
387 updateLeftAffordanceIcon();
388 }
389
Selim Cineke70d6532015-04-24 16:46:13 -0700390 private void updateLeftAffordanceIcon() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400391 IconState state = mLeftButton.getIcon();
Adrian Roos91ba3072017-02-14 16:50:46 +0100392 mLeftAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
Lucas Dupin3704d532019-04-18 19:23:06 -0700393 if (state.drawable != mLeftAffordanceView.getDrawable()
394 || state.tint != mLeftAffordanceView.shouldTint()) {
395 mLeftAffordanceView.setImageDrawable(state.drawable, state.tint);
396 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400397 mLeftAffordanceView.setContentDescription(state.contentDescription);
Selim Cineke70d6532015-04-24 16:46:13 -0700398 }
399
400 public boolean isLeftVoiceAssist() {
401 return mLeftIsVoiceAssist;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200402 }
403
404 private boolean isPhoneVisible() {
405 PackageManager pm = mContext.getPackageManager();
406 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
407 && pm.resolveActivity(PHONE_INTENT, 0) != null;
408 }
409
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200410 @Override
411 public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
Jason Monkb59f46f2016-09-27 12:29:18 -0400412 mRightAffordanceView.setClickable(touchExplorationEnabled);
Selim Cineke70d6532015-04-24 16:46:13 -0700413 mLeftAffordanceView.setClickable(touchExplorationEnabled);
Jason Monkb59f46f2016-09-27 12:29:18 -0400414 mRightAffordanceView.setFocusable(accessibilityEnabled);
Selim Cineke70d6532015-04-24 16:46:13 -0700415 mLeftAffordanceView.setFocusable(accessibilityEnabled);
Jorim Jaggia6310292014-04-16 14:11:52 +0200416 }
417
Selim Cinek4c6969a2014-05-26 19:22:17 +0200418 @Override
419 public void onClick(View v) {
Jason Monkb59f46f2016-09-27 12:29:18 -0400420 if (v == mRightAffordanceView) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700421 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
Selim Cineke70d6532015-04-24 16:46:13 -0700422 } else if (v == mLeftAffordanceView) {
423 launchLeftAffordance();
Selim Cinek4c6969a2014-05-26 19:22:17 +0200424 }
425 }
426
Jorim Jaggid9449862015-05-29 14:49:08 -0700427 public void bindCameraPrewarmService() {
Adrian Roosa06905b2014-05-28 12:13:48 +0200428 Intent intent = getCameraIntent();
Mark Renouf6b2331c2019-03-21 13:40:08 -0400429 ActivityInfo targetInfo = mActivityIntentHelper.getTargetActivityInfo(intent,
Selim Cinek5f145022016-08-02 16:00:12 -0700430 KeyguardUpdateMonitor.getCurrentUser(), true /* onlyDirectBootAware */);
Jorim Jaggi8b8fa3e2015-08-18 18:33:49 -0700431 if (targetInfo != null && targetInfo.metaData != null) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700432 String clazz = targetInfo.metaData.getString(
433 MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE);
434 if (clazz != null) {
435 Intent serviceIntent = new Intent();
436 serviceIntent.setClassName(targetInfo.packageName, clazz);
437 serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
438 try {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700439 if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
Selim Cinekedf47482015-09-01 18:05:08 -0700440 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
441 new UserHandle(UserHandle.USER_CURRENT))) {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700442 mPrewarmBound = true;
443 }
Jorim Jaggid9449862015-05-29 14:49:08 -0700444 } catch (SecurityException e) {
445 Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName
446 + " class=" + clazz, e);
447 }
448 }
Jorim Jaggia86790b2015-04-02 16:32:29 -0700449 }
450 }
451
Jorim Jaggid9449862015-05-29 14:49:08 -0700452 public void unbindCameraPrewarmService(boolean launched) {
453 if (mPrewarmBound) {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700454 if (mPrewarmMessenger != null && launched) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700455 try {
456 mPrewarmMessenger.send(Message.obtain(null /* handler */,
457 CameraPrewarmService.MSG_CAMERA_FIRED));
458 } catch (RemoteException e) {
459 Log.w(TAG, "Error sending camera fired message", e);
460 }
461 }
462 mContext.unbindService(mPrewarmConnection);
463 mPrewarmBound = false;
Jorim Jaggia86790b2015-04-02 16:32:29 -0700464 }
465 }
466
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700467 public void launchCamera(String source) {
Jorim Jaggia86790b2015-04-02 16:32:29 -0700468 final Intent intent = getCameraIntent();
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700469 intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
Mark Renouf6b2331c2019-03-21 13:40:08 -0400470 boolean wouldLaunchResolverActivity = mActivityIntentHelper.wouldLaunchResolverActivity(
471 intent, KeyguardUpdateMonitor.getCurrentUser());
Jorim Jaggi746f7fa2014-08-27 17:52:46 +0200472 if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
Jorim Jaggia86790b2015-04-02 16:32:29 -0700473 AsyncTask.execute(new Runnable() {
474 @Override
475 public void run() {
Jorim Jaggid9449862015-05-29 14:49:08 -0700476 int result = ActivityManager.START_CANCELED;
Robert Carrfd10cd12016-06-29 16:41:50 -0700477
478 // Normally an activity will set it's requested rotation
479 // animation on its window. However when launching an activity
480 // causes the orientation to change this is too late. In these cases
481 // the default animation is used. This doesn't look good for
482 // the camera (as it rotates the camera contents out of sync
483 // with physical reality). So, we ask the WindowManager to
484 // force the crossfade animation if an orientation change
485 // happens to occur during the launch.
486 ActivityOptions o = ActivityOptions.makeBasic();
Winson Chungf7e03e12017-08-22 11:32:16 -0700487 o.setDisallowEnterPictureInPictureWhileLaunching(true);
Robert Carrfd10cd12016-06-29 16:41:50 -0700488 o.setRotationAnimationHint(
Robert Carr57d9fbd2016-08-15 12:00:35 -0700489 WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
Jorim Jaggid9449862015-05-29 14:49:08 -0700490 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700491 result = ActivityTaskManager.getService().startActivityAsUser(
Jorim Jaggid9449862015-05-29 14:49:08 -0700492 null, getContext().getBasePackageName(),
493 intent,
494 intent.resolveTypeIfNeeded(getContext().getContentResolver()),
Robert Carrfd10cd12016-06-29 16:41:50 -0700495 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(),
Jorim Jaggid9449862015-05-29 14:49:08 -0700496 UserHandle.CURRENT.getIdentifier());
497 } catch (RemoteException e) {
498 Log.w(TAG, "Unable to start camera activity", e);
499 }
Jorim Jaggid9449862015-05-29 14:49:08 -0700500 final boolean launched = isSuccessfulLaunch(result);
501 post(new Runnable() {
502 @Override
503 public void run() {
504 unbindCameraPrewarmService(launched);
505 }
506 });
Jorim Jaggia86790b2015-04-02 16:32:29 -0700507 }
508 });
Adrian Roosa06905b2014-05-28 12:13:48 +0200509 } else {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +0200510
511 // We need to delay starting the activity because ResolverActivity finishes itself if
512 // launched behind lockscreen.
Jorim Jaggid9449862015-05-29 14:49:08 -0700513 mActivityStarter.startActivity(intent, false /* dismissShade */,
514 new ActivityStarter.Callback() {
515 @Override
516 public void onActivityStarted(int resultCode) {
517 unbindCameraPrewarmService(isSuccessfulLaunch(resultCode));
518 }
519 });
Adrian Roosa06905b2014-05-28 12:13:48 +0200520 }
Jorim Jaggia6310292014-04-16 14:11:52 +0200521 }
522
Lucas Dupin4272f442018-01-13 22:00:35 -0800523 public void setDarkAmount(float darkAmount) {
524 if (darkAmount == mDarkAmount) {
525 return;
526 }
527 mDarkAmount = darkAmount;
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700528 dozeTimeTick();
Lucas Dupinf22194f2018-12-26 11:43:57 -0800529 }
530
Jorim Jaggid9449862015-05-29 14:49:08 -0700531 private static boolean isSuccessfulLaunch(int result) {
532 return result == ActivityManager.START_SUCCESS
533 || result == ActivityManager.START_DELIVERED_TO_TOP
534 || result == ActivityManager.START_TASK_TO_FRONT;
535 }
536
Selim Cineke70d6532015-04-24 16:46:13 -0700537 public void launchLeftAffordance() {
538 if (mLeftIsVoiceAssist) {
539 launchVoiceAssist();
540 } else {
541 launchPhone();
542 }
543 }
544
Lucas Dupincea7dee2018-10-16 12:43:37 -0700545 @VisibleForTesting
546 void launchVoiceAssist() {
Selim Cineke70d6532015-04-24 16:46:13 -0700547 Runnable runnable = new Runnable() {
548 @Override
549 public void run() {
550 mAssistManager.launchVoiceAssistFromKeyguard();
Selim Cineke70d6532015-04-24 16:46:13 -0700551 }
552 };
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500553 if (mStatusBar.isKeyguardCurrentlySecure()) {
Selim Cineke70d6532015-04-24 16:46:13 -0700554 AsyncTask.execute(runnable);
555 } else {
Jason Monkd6fa02f2017-01-25 18:26:50 -0500556 boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
Jason Monkde850bb2017-02-01 19:26:30 -0500557 && Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500558 mStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
Jason Monkd6fa02f2017-01-25 18:26:50 -0500559 dismissShade, false /* afterKeyguardGone */, true /* deferred */);
Selim Cineke70d6532015-04-24 16:46:13 -0700560 }
561 }
562
563 private boolean canLaunchVoiceAssist() {
564 return mAssistManager.canVoiceAssistBeLaunchedFromKeyguard();
565 }
566
567 private void launchPhone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700568 final TelecomManager tm = TelecomManager.from(mContext);
Nancy Chen0eb1e402014-08-21 22:52:29 -0700569 if (tm.isInCall()) {
Yorke Lee583a20242014-08-12 18:47:08 -0700570 AsyncTask.execute(new Runnable() {
571 @Override
572 public void run() {
Nancy Chen0eb1e402014-08-21 22:52:29 -0700573 tm.showInCallScreen(false /* showDialpad */);
Yorke Lee583a20242014-08-12 18:47:08 -0700574 }
575 });
576 } else {
Jason Monkd6fa02f2017-01-25 18:26:50 -0500577 boolean dismissShade = !TextUtils.isEmpty(mLeftButtonStr)
Jason Monkde850bb2017-02-01 19:26:30 -0500578 && Dependency.get(TunerService.class).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
Jason Monkd6fa02f2017-01-25 18:26:50 -0500579 mActivityStarter.startActivity(mLeftButton.getIntent(), dismissShade);
Yorke Lee583a20242014-08-12 18:47:08 -0700580 }
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200581 }
582
Adrian Roos2fe592d2014-05-17 03:11:59 +0200583
584 @Override
585 protected void onVisibilityChanged(View changedView, int visibility) {
586 super.onVisibilityChanged(changedView, visibility);
587 if (changedView == this && visibility == VISIBLE) {
Adrian Roosa06905b2014-05-28 12:13:48 +0200588 updateCameraVisibility();
Adrian Roos2fe592d2014-05-17 03:11:59 +0200589 }
590 }
591
Selim Cineke70d6532015-04-24 16:46:13 -0700592 public KeyguardAffordanceView getLeftView() {
593 return mLeftAffordanceView;
Selim Cinek4c6969a2014-05-26 19:22:17 +0200594 }
595
Selim Cineke70d6532015-04-24 16:46:13 -0700596 public KeyguardAffordanceView getRightView() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400597 return mRightAffordanceView;
Selim Cinek4c6969a2014-05-26 19:22:17 +0200598 }
599
Selim Cineke70d6532015-04-24 16:46:13 -0700600 public View getLeftPreview() {
601 return mLeftPreview;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200602 }
603
Selim Cineke70d6532015-04-24 16:46:13 -0700604 public View getRightPreview() {
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200605 return mCameraPreview;
606 }
607
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100608 public View getIndicationArea() {
609 return mIndicationArea;
Selim Cinekf99d0002014-06-13 07:36:01 +0200610 }
611
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200612 @Override
Jorim Jaggi2580a9762014-06-25 03:08:25 +0200613 public boolean hasOverlappingRendering() {
614 return false;
615 }
616
617 @Override
Christoph Studer2231c6e2014-12-19 12:40:13 +0100618 public void onUnlockMethodStateChanged() {
Adrian Roosa06905b2014-05-28 12:13:48 +0200619 updateCameraVisibility();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200620 }
Adrian Roosa06905b2014-05-28 12:13:48 +0200621
Selim Cineke70d6532015-04-24 16:46:13 -0700622 private void inflateCameraPreview() {
Selim Cinek5f145022016-08-02 16:00:12 -0700623 View previewBefore = mCameraPreview;
624 boolean visibleBefore = false;
625 if (previewBefore != null) {
626 mPreviewContainer.removeView(previewBefore);
627 visibleBefore = previewBefore.getVisibility() == View.VISIBLE;
628 }
Jorim Jaggi781c29c2014-08-05 20:39:15 +0200629 mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200630 if (mCameraPreview != null) {
631 mPreviewContainer.addView(mCameraPreview);
Selim Cinek5f145022016-08-02 16:00:12 -0700632 mCameraPreview.setVisibility(visibleBefore ? View.VISIBLE : View.INVISIBLE);
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200633 }
Jorim Jaggidadafd42016-09-30 07:20:25 -0700634 if (mAffordanceHelper != null) {
635 mAffordanceHelper.updatePreviews();
636 }
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200637 }
638
Selim Cineke70d6532015-04-24 16:46:13 -0700639 private void updateLeftPreview() {
640 View previewBefore = mLeftPreview;
641 if (previewBefore != null) {
642 mPreviewContainer.removeView(previewBefore);
643 }
644 if (mLeftIsVoiceAssist) {
645 mLeftPreview = mPreviewInflater.inflatePreviewFromService(
646 mAssistManager.getVoiceInteractorComponentName());
647 } else {
Jason Monkb59f46f2016-09-27 12:29:18 -0400648 mLeftPreview = mPreviewInflater.inflatePreview(mLeftButton.getIntent());
Selim Cineke70d6532015-04-24 16:46:13 -0700649 }
650 if (mLeftPreview != null) {
651 mPreviewContainer.addView(mLeftPreview);
652 mLeftPreview.setVisibility(View.INVISIBLE);
653 }
Jorim Jaggidadafd42016-09-30 07:20:25 -0700654 if (mAffordanceHelper != null) {
655 mAffordanceHelper.updatePreviews();
656 }
Selim Cineke70d6532015-04-24 16:46:13 -0700657 }
658
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100659 public void startFinishDozeAnimation() {
660 long delay = 0;
Selim Cineke70d6532015-04-24 16:46:13 -0700661 if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
662 startFinishDozeAnimationElement(mLeftAffordanceView, delay);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100663 delay += DOZE_ANIMATION_STAGGER_DELAY;
664 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400665 if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
666 startFinishDozeAnimationElement(mRightAffordanceView, delay);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100667 }
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100668 }
669
670 private void startFinishDozeAnimationElement(View element, long delay) {
671 element.setAlpha(0f);
672 element.setTranslationY(element.getHeight() / 2);
673 element.animate()
674 .alpha(1f)
675 .translationY(0f)
Selim Cinekc18010f2016-01-20 13:41:30 -0800676 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100677 .setStartDelay(delay)
678 .setDuration(DOZE_ANIMATION_ELEMENT_DURATION);
679 }
680
Adrian Roosa06905b2014-05-28 12:13:48 +0200681 private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
Jim Millerb29814c2015-08-05 19:03:01 -0700682 @Override
Adrian Roosa06905b2014-05-28 12:13:48 +0200683 public void onReceive(Context context, Intent intent) {
684 post(new Runnable() {
685 @Override
686 public void run() {
687 updateCameraVisibility();
688 }
689 });
690 }
691 };
692
693 private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
694 new KeyguardUpdateMonitorCallback() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400695 @Override
696 public void onUserSwitchComplete(int userId) {
697 updateCameraVisibility();
698 }
Jorim Jaggie7b12522014-08-06 16:41:21 +0200699
Jason Monkb59f46f2016-09-27 12:29:18 -0400700 @Override
Jorim Jaggi90f62792016-10-07 15:11:44 +0200701 public void onUserUnlocked() {
702 inflateCameraPreview();
703 updateCameraVisibility();
704 updateLeftAffordance();
Jason Monkb59f46f2016-09-27 12:29:18 -0400705 }
706 };
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200707
Selim Cineke70d6532015-04-24 16:46:13 -0700708 public void updateLeftAffordance() {
709 updateLeftAffordanceIcon();
710 updateLeftPreview();
711 }
Selim Cinek5f145022016-08-02 16:00:12 -0700712
Jason Monkb59f46f2016-09-27 12:29:18 -0400713 private void setRightButton(IntentButton button) {
Jason Monk1d9632d2017-02-09 13:20:04 -0800714 mRightButton = button;
Jason Monkb59f46f2016-09-27 12:29:18 -0400715 updateRightAffordanceIcon();
716 updateCameraVisibility();
717 inflateCameraPreview();
718 }
719
720 private void setLeftButton(IntentButton button) {
Jason Monk1d9632d2017-02-09 13:20:04 -0800721 mLeftButton = button;
722 if (!(mLeftButton instanceof DefaultLeftButton)) {
723 mLeftIsVoiceAssist = false;
724 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400725 updateLeftAffordance();
726 }
727
Adrian Roos91ba3072017-02-14 16:50:46 +0100728 public void setDozing(boolean dozing, boolean animate) {
729 mDozing = dozing;
730
731 updateCameraVisibility();
732 updateLeftAffordanceIcon();
733
734 if (dozing) {
Philip Quinnb86efa42017-07-08 12:59:24 -0700735 mOverlayContainer.setVisibility(INVISIBLE);
Adrian Roos91ba3072017-02-14 16:50:46 +0100736 } else {
Philip Quinnb86efa42017-07-08 12:59:24 -0700737 mOverlayContainer.setVisibility(VISIBLE);
Adrian Roos91ba3072017-02-14 16:50:46 +0100738 if (animate) {
739 startFinishDozeAnimation();
740 }
741 }
742 }
743
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700744 public void dozeTimeTick() {
745 int burnInYOffset = getBurnInOffset(mBurnInYOffset * 2, false /* xAxis */)
746 - mBurnInYOffset;
747 mIndicationArea.setTranslationY(burnInYOffset * mDarkAmount);
748 }
749
750 public void setAntiBurnInOffsetX(int burnInXOffset) {
751 if (mBurnInXOffset == burnInXOffset) {
752 return;
753 }
754 mBurnInXOffset = burnInXOffset;
755 mIndicationArea.setTranslationX(burnInXOffset);
756 }
757
Lucas Dupin407cc582019-03-11 21:04:31 -0700758 /**
759 * Sets the alpha of the indication areas and affordances, excluding the lock icon.
760 */
761 public void setAffordanceAlpha(float alpha) {
762 mLeftAffordanceView.setAlpha(alpha);
763 mRightAffordanceView.setAlpha(alpha);
764 mIndicationArea.setAlpha(alpha);
765 }
766
Jason Monkb59f46f2016-09-27 12:29:18 -0400767 private class DefaultLeftButton implements IntentButton {
768
769 private IconState mIconState = new IconState();
770
771 @Override
772 public IconState getIcon() {
773 mLeftIsVoiceAssist = canLaunchVoiceAssist();
Lucas Dupinf78c5402018-01-05 12:57:27 -0800774 final boolean showAffordance =
775 getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance);
Jason Monkb59f46f2016-09-27 12:29:18 -0400776 if (mLeftIsVoiceAssist) {
Lucas Dupinf78c5402018-01-05 12:57:27 -0800777 mIconState.isVisible = mUserSetupComplete && showAffordance;
Evan Roskyd388c752016-11-15 13:59:06 -0800778 if (mLeftAssistIcon == null) {
779 mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
780 } else {
781 mIconState.drawable = mLeftAssistIcon;
782 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400783 mIconState.contentDescription = mContext.getString(
784 R.string.accessibility_voice_assist_button);
785 } else {
Lucas Dupinf78c5402018-01-05 12:57:27 -0800786 mIconState.isVisible = mUserSetupComplete && showAffordance && isPhoneVisible();
Amin Shaikhf3a94272019-01-29 18:22:14 -0500787 mIconState.drawable = mContext.getDrawable(
788 com.android.internal.R.drawable.ic_phone);
Jason Monkb59f46f2016-09-27 12:29:18 -0400789 mIconState.contentDescription = mContext.getString(
790 R.string.accessibility_phone_button);
791 }
792 return mIconState;
793 }
794
795 @Override
796 public Intent getIntent() {
797 return PHONE_INTENT;
798 }
799 }
800
801 private class DefaultRightButton implements IntentButton {
802
803 private IconState mIconState = new IconState();
804
805 @Override
806 public IconState getIcon() {
807 ResolveInfo resolved = resolveCameraIntent();
Esteban Talavera40f8b992017-07-14 16:14:07 +0100808 boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
809 mIconState.isVisible = !isCameraDisabled && resolved != null
Jason Monkb59f46f2016-09-27 12:29:18 -0400810 && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
811 && mUserSetupComplete;
812 mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
813 mIconState.contentDescription =
814 mContext.getString(R.string.accessibility_camera_button);
815 return mIconState;
816 }
817
818 @Override
819 public Intent getIntent() {
820 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
821 boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
822 KeyguardUpdateMonitor.getCurrentUser());
823 boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
824 return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
825 }
826 }
Adrian Roos7e58a082018-03-09 16:40:56 +0100827
828 @Override
829 public WindowInsets onApplyWindowInsets(WindowInsets insets) {
830 int bottom = insets.getDisplayCutout() != null
831 ? insets.getDisplayCutout().getSafeInsetBottom() : 0;
832 if (isPaddingRelative()) {
833 setPaddingRelative(getPaddingStart(), getPaddingTop(), getPaddingEnd(), bottom);
834 } else {
835 setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), bottom);
836 }
837 return insets;
838 }
Jorim Jaggia6310292014-04-16 14:11:52 +0200839}