blob: 23b48141d0cc23a69978a078e7d57551b49f66b1 [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 Dupin8968f6a2019-08-09 17:41:15 -070022import static com.android.systemui.DejankUtils.whitelistIpcs;
Lucas Dupin07ed3df2019-03-26 21:23:59 -070023import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
Jason Monk1d9632d2017-02-09 13:20:04 -080024import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
Jason Monkd6fa02f2017-01-25 18:26:50 -050025import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
Jason Monk1d9632d2017-02-09 13:20:04 -080026import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
Jason Monkd6fa02f2017-01-25 18:26:50 -050027import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_UNLOCK;
Selim Cinek5f145022016-08-02 16:00:12 -070028
Jorim Jaggid9449862015-05-29 14:49:08 -070029import android.app.ActivityManager;
Robert Carrfd10cd12016-06-29 16:41:50 -070030import android.app.ActivityOptions;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070031import android.app.ActivityTaskManager;
Jorim Jaggia6310292014-04-16 14:11:52 +020032import android.app.admin.DevicePolicyManager;
33import android.content.BroadcastReceiver;
Jorim Jaggid9449862015-05-29 14:49:08 -070034import android.content.ComponentName;
Jorim Jaggia6310292014-04-16 14:11:52 +020035import android.content.Context;
36import android.content.Intent;
37import android.content.IntentFilter;
Jorim Jaggid9449862015-05-29 14:49:08 -070038import android.content.ServiceConnection;
39import android.content.pm.ActivityInfo;
Jorim Jaggi97b63c42014-05-02 23:03:34 +020040import android.content.pm.PackageManager;
Adrian Roosa06905b2014-05-28 12:13:48 +020041import android.content.pm.ResolveInfo;
Jorim Jaggie210cc82014-08-12 23:44:59 +020042import android.content.res.Configuration;
Evan Roskyd388c752016-11-15 13:59:06 -080043import android.graphics.drawable.Drawable;
Yorke Lee583a20242014-08-12 18:47:08 -070044import android.os.AsyncTask;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020045import android.os.Bundle;
Jorim Jaggid9449862015-05-29 14:49:08 -070046import android.os.IBinder;
47import android.os.Message;
48import android.os.Messenger;
Jorim Jaggia6310292014-04-16 14:11:52 +020049import android.os.RemoteException;
50import android.os.UserHandle;
51import android.provider.MediaStore;
Jorim Jaggid9449862015-05-29 14:49:08 -070052import android.service.media.CameraPrewarmService;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070053import android.telecom.TelecomManager;
Jason Monkd6fa02f2017-01-25 18:26:50 -050054import android.text.TextUtils;
Jorim Jaggia6310292014-04-16 14:11:52 +020055import android.util.AttributeSet;
56import android.util.Log;
Jorim Jaggie210cc82014-08-12 23:44:59 +020057import android.util.TypedValue;
Jorim Jaggia6310292014-04-16 14:11:52 +020058import android.view.View;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +020059import android.view.ViewGroup;
Adrian Roos7e58a082018-03-09 16:40:56 +010060import android.view.WindowInsets;
Robert Carrfd10cd12016-06-29 16:41:50 -070061import android.view.WindowManager;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020062import android.view.accessibility.AccessibilityNodeInfo;
Jorim Jaggia6310292014-04-16 14:11:52 +020063import android.widget.FrameLayout;
Jorim Jaggie210cc82014-08-12 23:44:59 +020064import android.widget.TextView;
Adrian Roosa06905b2014-05-28 12:13:48 +020065
Lucas Dupincea7dee2018-10-16 12:43:37 -070066import com.android.internal.annotations.VisibleForTesting;
Adrian Roosa06905b2014-05-28 12:13:48 +020067import com.android.internal.widget.LockPatternUtils;
68import com.android.keyguard.KeyguardUpdateMonitor;
69import com.android.keyguard.KeyguardUpdateMonitorCallback;
Mark Renouf6b2331c2019-03-21 13:40:08 -040070import com.android.systemui.ActivityIntentHelper;
Jason Monk9c7844c2017-01-18 15:21:53 -050071import com.android.systemui.Dependency;
Winsonc0d70582016-01-29 10:24:39 -080072import com.android.systemui.Interpolators;
Jorim Jaggia6310292014-04-16 14:11:52 +020073import com.android.systemui.R;
Selim Cineke70d6532015-04-24 16:46:13 -070074import com.android.systemui.assist.AssistManager;
Lucas Dupin117365d2018-10-03 15:49:46 -070075import com.android.systemui.plugins.ActivityStarter;
Jason Monkb59f46f2016-09-27 12:29:18 -040076import com.android.systemui.plugins.IntentButtonProvider;
77import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
78import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
Selim Cinekbaa23272014-07-08 18:01:07 +020079import com.android.systemui.statusbar.KeyguardAffordanceView;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020080import 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() {
Lucas Dupin8968f6a2019-08-09 17:41:15 -0700368 // TODO(b/140057230)
369 return whitelistIpcs(() ->
370 mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
371 PackageManager.MATCH_DEFAULT_ONLY,
372 KeyguardUpdateMonitor.getCurrentUser()));
Zhentao Sun04f97402015-08-26 17:37:30 -0700373 }
374
Jorim Jaggia6310292014-04-16 14:11:52 +0200375 private void updateCameraVisibility() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400376 if (mRightAffordanceView == null) {
Dan Sandlere163a642015-03-01 22:58:32 -0500377 // Things are not set up yet; reply hazy, ask again later
378 return;
379 }
Adrian Roos91ba3072017-02-14 16:50:46 +0100380 mRightAffordanceView.setVisibility(!mDozing && mRightButton.getIcon().isVisible
Jason Monkb59f46f2016-09-27 12:29:18 -0400381 ? View.VISIBLE : View.GONE);
Jorim Jaggia6310292014-04-16 14:11:52 +0200382 }
383
Evan Roskyd388c752016-11-15 13:59:06 -0800384 /**
385 * Set an alternate icon for the left assist affordance (replace the mic icon)
386 */
387 public void setLeftAssistIcon(Drawable drawable) {
388 mLeftAssistIcon = drawable;
389 updateLeftAffordanceIcon();
390 }
391
Selim Cineke70d6532015-04-24 16:46:13 -0700392 private void updateLeftAffordanceIcon() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400393 IconState state = mLeftButton.getIcon();
Adrian Roos91ba3072017-02-14 16:50:46 +0100394 mLeftAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
Lucas Dupin3704d532019-04-18 19:23:06 -0700395 if (state.drawable != mLeftAffordanceView.getDrawable()
396 || state.tint != mLeftAffordanceView.shouldTint()) {
397 mLeftAffordanceView.setImageDrawable(state.drawable, state.tint);
398 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400399 mLeftAffordanceView.setContentDescription(state.contentDescription);
Selim Cineke70d6532015-04-24 16:46:13 -0700400 }
401
402 public boolean isLeftVoiceAssist() {
403 return mLeftIsVoiceAssist;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200404 }
405
406 private boolean isPhoneVisible() {
407 PackageManager pm = mContext.getPackageManager();
408 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
409 && pm.resolveActivity(PHONE_INTENT, 0) != null;
410 }
411
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200412 @Override
413 public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
Jason Monkb59f46f2016-09-27 12:29:18 -0400414 mRightAffordanceView.setClickable(touchExplorationEnabled);
Selim Cineke70d6532015-04-24 16:46:13 -0700415 mLeftAffordanceView.setClickable(touchExplorationEnabled);
Jason Monkb59f46f2016-09-27 12:29:18 -0400416 mRightAffordanceView.setFocusable(accessibilityEnabled);
Selim Cineke70d6532015-04-24 16:46:13 -0700417 mLeftAffordanceView.setFocusable(accessibilityEnabled);
Jorim Jaggia6310292014-04-16 14:11:52 +0200418 }
419
Selim Cinek4c6969a2014-05-26 19:22:17 +0200420 @Override
421 public void onClick(View v) {
Jason Monkb59f46f2016-09-27 12:29:18 -0400422 if (v == mRightAffordanceView) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700423 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
Selim Cineke70d6532015-04-24 16:46:13 -0700424 } else if (v == mLeftAffordanceView) {
425 launchLeftAffordance();
Selim Cinek4c6969a2014-05-26 19:22:17 +0200426 }
427 }
428
Jorim Jaggid9449862015-05-29 14:49:08 -0700429 public void bindCameraPrewarmService() {
Adrian Roosa06905b2014-05-28 12:13:48 +0200430 Intent intent = getCameraIntent();
Mark Renouf6b2331c2019-03-21 13:40:08 -0400431 ActivityInfo targetInfo = mActivityIntentHelper.getTargetActivityInfo(intent,
Selim Cinek5f145022016-08-02 16:00:12 -0700432 KeyguardUpdateMonitor.getCurrentUser(), true /* onlyDirectBootAware */);
Jorim Jaggi8b8fa3e2015-08-18 18:33:49 -0700433 if (targetInfo != null && targetInfo.metaData != null) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700434 String clazz = targetInfo.metaData.getString(
435 MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE);
436 if (clazz != null) {
437 Intent serviceIntent = new Intent();
438 serviceIntent.setClassName(targetInfo.packageName, clazz);
439 serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
440 try {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700441 if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
Selim Cinekedf47482015-09-01 18:05:08 -0700442 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
443 new UserHandle(UserHandle.USER_CURRENT))) {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700444 mPrewarmBound = true;
445 }
Jorim Jaggid9449862015-05-29 14:49:08 -0700446 } catch (SecurityException e) {
447 Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName
448 + " class=" + clazz, e);
449 }
450 }
Jorim Jaggia86790b2015-04-02 16:32:29 -0700451 }
452 }
453
Jorim Jaggid9449862015-05-29 14:49:08 -0700454 public void unbindCameraPrewarmService(boolean launched) {
455 if (mPrewarmBound) {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700456 if (mPrewarmMessenger != null && launched) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700457 try {
458 mPrewarmMessenger.send(Message.obtain(null /* handler */,
459 CameraPrewarmService.MSG_CAMERA_FIRED));
460 } catch (RemoteException e) {
461 Log.w(TAG, "Error sending camera fired message", e);
462 }
463 }
464 mContext.unbindService(mPrewarmConnection);
465 mPrewarmBound = false;
Jorim Jaggia86790b2015-04-02 16:32:29 -0700466 }
467 }
468
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700469 public void launchCamera(String source) {
Jorim Jaggia86790b2015-04-02 16:32:29 -0700470 final Intent intent = getCameraIntent();
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700471 intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
Mark Renouf6b2331c2019-03-21 13:40:08 -0400472 boolean wouldLaunchResolverActivity = mActivityIntentHelper.wouldLaunchResolverActivity(
473 intent, KeyguardUpdateMonitor.getCurrentUser());
Jorim Jaggi746f7fa2014-08-27 17:52:46 +0200474 if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
Jorim Jaggia86790b2015-04-02 16:32:29 -0700475 AsyncTask.execute(new Runnable() {
476 @Override
477 public void run() {
Jorim Jaggid9449862015-05-29 14:49:08 -0700478 int result = ActivityManager.START_CANCELED;
Robert Carrfd10cd12016-06-29 16:41:50 -0700479
480 // Normally an activity will set it's requested rotation
481 // animation on its window. However when launching an activity
482 // causes the orientation to change this is too late. In these cases
483 // the default animation is used. This doesn't look good for
484 // the camera (as it rotates the camera contents out of sync
485 // with physical reality). So, we ask the WindowManager to
486 // force the crossfade animation if an orientation change
487 // happens to occur during the launch.
488 ActivityOptions o = ActivityOptions.makeBasic();
Winson Chungf7e03e12017-08-22 11:32:16 -0700489 o.setDisallowEnterPictureInPictureWhileLaunching(true);
Robert Carrfd10cd12016-06-29 16:41:50 -0700490 o.setRotationAnimationHint(
Robert Carr57d9fbd2016-08-15 12:00:35 -0700491 WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
Jorim Jaggid9449862015-05-29 14:49:08 -0700492 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700493 result = ActivityTaskManager.getService().startActivityAsUser(
Jorim Jaggid9449862015-05-29 14:49:08 -0700494 null, getContext().getBasePackageName(),
495 intent,
496 intent.resolveTypeIfNeeded(getContext().getContentResolver()),
Robert Carrfd10cd12016-06-29 16:41:50 -0700497 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(),
Jorim Jaggid9449862015-05-29 14:49:08 -0700498 UserHandle.CURRENT.getIdentifier());
499 } catch (RemoteException e) {
500 Log.w(TAG, "Unable to start camera activity", e);
501 }
Jorim Jaggid9449862015-05-29 14:49:08 -0700502 final boolean launched = isSuccessfulLaunch(result);
503 post(new Runnable() {
504 @Override
505 public void run() {
506 unbindCameraPrewarmService(launched);
507 }
508 });
Jorim Jaggia86790b2015-04-02 16:32:29 -0700509 }
510 });
Adrian Roosa06905b2014-05-28 12:13:48 +0200511 } else {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +0200512
513 // We need to delay starting the activity because ResolverActivity finishes itself if
514 // launched behind lockscreen.
Jorim Jaggid9449862015-05-29 14:49:08 -0700515 mActivityStarter.startActivity(intent, false /* dismissShade */,
516 new ActivityStarter.Callback() {
517 @Override
518 public void onActivityStarted(int resultCode) {
519 unbindCameraPrewarmService(isSuccessfulLaunch(resultCode));
520 }
521 });
Adrian Roosa06905b2014-05-28 12:13:48 +0200522 }
Jorim Jaggia6310292014-04-16 14:11:52 +0200523 }
524
Lucas Dupin4272f442018-01-13 22:00:35 -0800525 public void setDarkAmount(float darkAmount) {
526 if (darkAmount == mDarkAmount) {
527 return;
528 }
529 mDarkAmount = darkAmount;
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700530 dozeTimeTick();
Lucas Dupinf22194f2018-12-26 11:43:57 -0800531 }
532
Jorim Jaggid9449862015-05-29 14:49:08 -0700533 private static boolean isSuccessfulLaunch(int result) {
534 return result == ActivityManager.START_SUCCESS
535 || result == ActivityManager.START_DELIVERED_TO_TOP
536 || result == ActivityManager.START_TASK_TO_FRONT;
537 }
538
Selim Cineke70d6532015-04-24 16:46:13 -0700539 public void launchLeftAffordance() {
540 if (mLeftIsVoiceAssist) {
541 launchVoiceAssist();
542 } else {
543 launchPhone();
544 }
545 }
546
Lucas Dupincea7dee2018-10-16 12:43:37 -0700547 @VisibleForTesting
548 void launchVoiceAssist() {
Selim Cineke70d6532015-04-24 16:46:13 -0700549 Runnable runnable = new Runnable() {
550 @Override
551 public void run() {
552 mAssistManager.launchVoiceAssistFromKeyguard();
Selim Cineke70d6532015-04-24 16:46:13 -0700553 }
554 };
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500555 if (mStatusBar.isKeyguardCurrentlySecure()) {
Selim Cineke70d6532015-04-24 16:46:13 -0700556 AsyncTask.execute(runnable);
557 } else {
Jason Monkd6fa02f2017-01-25 18:26:50 -0500558 boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
Jason Monkde850bb2017-02-01 19:26:30 -0500559 && Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500560 mStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
Jason Monkd6fa02f2017-01-25 18:26:50 -0500561 dismissShade, false /* afterKeyguardGone */, true /* deferred */);
Selim Cineke70d6532015-04-24 16:46:13 -0700562 }
563 }
564
565 private boolean canLaunchVoiceAssist() {
566 return mAssistManager.canVoiceAssistBeLaunchedFromKeyguard();
567 }
568
569 private void launchPhone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700570 final TelecomManager tm = TelecomManager.from(mContext);
Nancy Chen0eb1e402014-08-21 22:52:29 -0700571 if (tm.isInCall()) {
Yorke Lee583a20242014-08-12 18:47:08 -0700572 AsyncTask.execute(new Runnable() {
573 @Override
574 public void run() {
Nancy Chen0eb1e402014-08-21 22:52:29 -0700575 tm.showInCallScreen(false /* showDialpad */);
Yorke Lee583a20242014-08-12 18:47:08 -0700576 }
577 });
578 } else {
Jason Monkd6fa02f2017-01-25 18:26:50 -0500579 boolean dismissShade = !TextUtils.isEmpty(mLeftButtonStr)
Jason Monkde850bb2017-02-01 19:26:30 -0500580 && Dependency.get(TunerService.class).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
Jason Monkd6fa02f2017-01-25 18:26:50 -0500581 mActivityStarter.startActivity(mLeftButton.getIntent(), dismissShade);
Yorke Lee583a20242014-08-12 18:47:08 -0700582 }
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200583 }
584
Adrian Roos2fe592d2014-05-17 03:11:59 +0200585
586 @Override
587 protected void onVisibilityChanged(View changedView, int visibility) {
588 super.onVisibilityChanged(changedView, visibility);
589 if (changedView == this && visibility == VISIBLE) {
Adrian Roosa06905b2014-05-28 12:13:48 +0200590 updateCameraVisibility();
Adrian Roos2fe592d2014-05-17 03:11:59 +0200591 }
592 }
593
Selim Cineke70d6532015-04-24 16:46:13 -0700594 public KeyguardAffordanceView getLeftView() {
595 return mLeftAffordanceView;
Selim Cinek4c6969a2014-05-26 19:22:17 +0200596 }
597
Selim Cineke70d6532015-04-24 16:46:13 -0700598 public KeyguardAffordanceView getRightView() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400599 return mRightAffordanceView;
Selim Cinek4c6969a2014-05-26 19:22:17 +0200600 }
601
Selim Cineke70d6532015-04-24 16:46:13 -0700602 public View getLeftPreview() {
603 return mLeftPreview;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200604 }
605
Selim Cineke70d6532015-04-24 16:46:13 -0700606 public View getRightPreview() {
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200607 return mCameraPreview;
608 }
609
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100610 public View getIndicationArea() {
611 return mIndicationArea;
Selim Cinekf99d0002014-06-13 07:36:01 +0200612 }
613
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200614 @Override
Jorim Jaggi2580a9762014-06-25 03:08:25 +0200615 public boolean hasOverlappingRendering() {
616 return false;
617 }
618
619 @Override
Christoph Studer2231c6e2014-12-19 12:40:13 +0100620 public void onUnlockMethodStateChanged() {
Adrian Roosa06905b2014-05-28 12:13:48 +0200621 updateCameraVisibility();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200622 }
Adrian Roosa06905b2014-05-28 12:13:48 +0200623
Selim Cineke70d6532015-04-24 16:46:13 -0700624 private void inflateCameraPreview() {
Selim Cinek5f145022016-08-02 16:00:12 -0700625 View previewBefore = mCameraPreview;
626 boolean visibleBefore = false;
627 if (previewBefore != null) {
628 mPreviewContainer.removeView(previewBefore);
629 visibleBefore = previewBefore.getVisibility() == View.VISIBLE;
630 }
Jorim Jaggi781c29c2014-08-05 20:39:15 +0200631 mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200632 if (mCameraPreview != null) {
633 mPreviewContainer.addView(mCameraPreview);
Selim Cinek5f145022016-08-02 16:00:12 -0700634 mCameraPreview.setVisibility(visibleBefore ? View.VISIBLE : View.INVISIBLE);
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200635 }
Jorim Jaggidadafd42016-09-30 07:20:25 -0700636 if (mAffordanceHelper != null) {
637 mAffordanceHelper.updatePreviews();
638 }
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200639 }
640
Selim Cineke70d6532015-04-24 16:46:13 -0700641 private void updateLeftPreview() {
642 View previewBefore = mLeftPreview;
643 if (previewBefore != null) {
644 mPreviewContainer.removeView(previewBefore);
645 }
646 if (mLeftIsVoiceAssist) {
647 mLeftPreview = mPreviewInflater.inflatePreviewFromService(
648 mAssistManager.getVoiceInteractorComponentName());
649 } else {
Jason Monkb59f46f2016-09-27 12:29:18 -0400650 mLeftPreview = mPreviewInflater.inflatePreview(mLeftButton.getIntent());
Selim Cineke70d6532015-04-24 16:46:13 -0700651 }
652 if (mLeftPreview != null) {
653 mPreviewContainer.addView(mLeftPreview);
654 mLeftPreview.setVisibility(View.INVISIBLE);
655 }
Jorim Jaggidadafd42016-09-30 07:20:25 -0700656 if (mAffordanceHelper != null) {
657 mAffordanceHelper.updatePreviews();
658 }
Selim Cineke70d6532015-04-24 16:46:13 -0700659 }
660
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100661 public void startFinishDozeAnimation() {
662 long delay = 0;
Selim Cineke70d6532015-04-24 16:46:13 -0700663 if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
664 startFinishDozeAnimationElement(mLeftAffordanceView, delay);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100665 delay += DOZE_ANIMATION_STAGGER_DELAY;
666 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400667 if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
668 startFinishDozeAnimationElement(mRightAffordanceView, delay);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100669 }
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100670 }
671
672 private void startFinishDozeAnimationElement(View element, long delay) {
673 element.setAlpha(0f);
674 element.setTranslationY(element.getHeight() / 2);
675 element.animate()
676 .alpha(1f)
677 .translationY(0f)
Selim Cinekc18010f2016-01-20 13:41:30 -0800678 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100679 .setStartDelay(delay)
680 .setDuration(DOZE_ANIMATION_ELEMENT_DURATION);
681 }
682
Adrian Roosa06905b2014-05-28 12:13:48 +0200683 private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
Jim Millerb29814c2015-08-05 19:03:01 -0700684 @Override
Adrian Roosa06905b2014-05-28 12:13:48 +0200685 public void onReceive(Context context, Intent intent) {
686 post(new Runnable() {
687 @Override
688 public void run() {
689 updateCameraVisibility();
690 }
691 });
692 }
693 };
694
695 private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
696 new KeyguardUpdateMonitorCallback() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400697 @Override
698 public void onUserSwitchComplete(int userId) {
699 updateCameraVisibility();
700 }
Jorim Jaggie7b12522014-08-06 16:41:21 +0200701
Jason Monkb59f46f2016-09-27 12:29:18 -0400702 @Override
Jorim Jaggi90f62792016-10-07 15:11:44 +0200703 public void onUserUnlocked() {
704 inflateCameraPreview();
705 updateCameraVisibility();
706 updateLeftAffordance();
Jason Monkb59f46f2016-09-27 12:29:18 -0400707 }
708 };
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200709
Selim Cineke70d6532015-04-24 16:46:13 -0700710 public void updateLeftAffordance() {
711 updateLeftAffordanceIcon();
712 updateLeftPreview();
713 }
Selim Cinek5f145022016-08-02 16:00:12 -0700714
Jason Monkb59f46f2016-09-27 12:29:18 -0400715 private void setRightButton(IntentButton button) {
Jason Monk1d9632d2017-02-09 13:20:04 -0800716 mRightButton = button;
Jason Monkb59f46f2016-09-27 12:29:18 -0400717 updateRightAffordanceIcon();
718 updateCameraVisibility();
719 inflateCameraPreview();
720 }
721
722 private void setLeftButton(IntentButton button) {
Jason Monk1d9632d2017-02-09 13:20:04 -0800723 mLeftButton = button;
724 if (!(mLeftButton instanceof DefaultLeftButton)) {
725 mLeftIsVoiceAssist = false;
726 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400727 updateLeftAffordance();
728 }
729
Adrian Roos91ba3072017-02-14 16:50:46 +0100730 public void setDozing(boolean dozing, boolean animate) {
731 mDozing = dozing;
732
733 updateCameraVisibility();
734 updateLeftAffordanceIcon();
735
736 if (dozing) {
Philip Quinnb86efa42017-07-08 12:59:24 -0700737 mOverlayContainer.setVisibility(INVISIBLE);
Adrian Roos91ba3072017-02-14 16:50:46 +0100738 } else {
Philip Quinnb86efa42017-07-08 12:59:24 -0700739 mOverlayContainer.setVisibility(VISIBLE);
Adrian Roos91ba3072017-02-14 16:50:46 +0100740 if (animate) {
741 startFinishDozeAnimation();
742 }
743 }
744 }
745
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700746 public void dozeTimeTick() {
747 int burnInYOffset = getBurnInOffset(mBurnInYOffset * 2, false /* xAxis */)
748 - mBurnInYOffset;
749 mIndicationArea.setTranslationY(burnInYOffset * mDarkAmount);
750 }
751
752 public void setAntiBurnInOffsetX(int burnInXOffset) {
753 if (mBurnInXOffset == burnInXOffset) {
754 return;
755 }
756 mBurnInXOffset = burnInXOffset;
757 mIndicationArea.setTranslationX(burnInXOffset);
758 }
759
Lucas Dupin407cc582019-03-11 21:04:31 -0700760 /**
761 * Sets the alpha of the indication areas and affordances, excluding the lock icon.
762 */
763 public void setAffordanceAlpha(float alpha) {
764 mLeftAffordanceView.setAlpha(alpha);
765 mRightAffordanceView.setAlpha(alpha);
766 mIndicationArea.setAlpha(alpha);
767 }
768
Jason Monkb59f46f2016-09-27 12:29:18 -0400769 private class DefaultLeftButton implements IntentButton {
770
771 private IconState mIconState = new IconState();
772
773 @Override
774 public IconState getIcon() {
775 mLeftIsVoiceAssist = canLaunchVoiceAssist();
Lucas Dupinf78c5402018-01-05 12:57:27 -0800776 final boolean showAffordance =
777 getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance);
Jason Monkb59f46f2016-09-27 12:29:18 -0400778 if (mLeftIsVoiceAssist) {
Lucas Dupinf78c5402018-01-05 12:57:27 -0800779 mIconState.isVisible = mUserSetupComplete && showAffordance;
Evan Roskyd388c752016-11-15 13:59:06 -0800780 if (mLeftAssistIcon == null) {
781 mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
782 } else {
783 mIconState.drawable = mLeftAssistIcon;
784 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400785 mIconState.contentDescription = mContext.getString(
786 R.string.accessibility_voice_assist_button);
787 } else {
Lucas Dupinf78c5402018-01-05 12:57:27 -0800788 mIconState.isVisible = mUserSetupComplete && showAffordance && isPhoneVisible();
Amin Shaikhf3a94272019-01-29 18:22:14 -0500789 mIconState.drawable = mContext.getDrawable(
790 com.android.internal.R.drawable.ic_phone);
Jason Monkb59f46f2016-09-27 12:29:18 -0400791 mIconState.contentDescription = mContext.getString(
792 R.string.accessibility_phone_button);
793 }
794 return mIconState;
795 }
796
797 @Override
798 public Intent getIntent() {
799 return PHONE_INTENT;
800 }
801 }
802
803 private class DefaultRightButton implements IntentButton {
804
805 private IconState mIconState = new IconState();
806
807 @Override
808 public IconState getIcon() {
809 ResolveInfo resolved = resolveCameraIntent();
Esteban Talavera40f8b992017-07-14 16:14:07 +0100810 boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
811 mIconState.isVisible = !isCameraDisabled && resolved != null
Jason Monkb59f46f2016-09-27 12:29:18 -0400812 && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
813 && mUserSetupComplete;
814 mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
815 mIconState.contentDescription =
816 mContext.getString(R.string.accessibility_camera_button);
817 return mIconState;
818 }
819
820 @Override
821 public Intent getIntent() {
822 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
823 boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
824 KeyguardUpdateMonitor.getCurrentUser());
Lucas Dupin8968f6a2019-08-09 17:41:15 -0700825 // TODO(b/140057230)
826 boolean secure = whitelistIpcs(() ->
827 mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()));
Jason Monkb59f46f2016-09-27 12:29:18 -0400828 return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
829 }
830 }
Adrian Roos7e58a082018-03-09 16:40:56 +0100831
832 @Override
833 public WindowInsets onApplyWindowInsets(WindowInsets insets) {
834 int bottom = insets.getDisplayCutout() != null
835 ? insets.getDisplayCutout().getSafeInsetBottom() : 0;
836 if (isPaddingRelative()) {
837 setPaddingRelative(getPaddingStart(), getPaddingTop(), getPaddingEnd(), bottom);
838 } else {
839 setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), bottom);
840 }
841 return insets;
842 }
Jorim Jaggia6310292014-04-16 14:11:52 +0200843}