blob: 427014714040dfe41bbaad8096197200427b08a8 [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;
21
Jorim Jaggid9449862015-05-29 14:49:08 -070022import android.app.ActivityManager;
Jorim Jaggia6310292014-04-16 14:11:52 +020023import android.app.ActivityManagerNative;
Robert Carrfd10cd12016-06-29 16:41:50 -070024import android.app.ActivityOptions;
Jorim Jaggia6310292014-04-16 14:11:52 +020025import android.app.admin.DevicePolicyManager;
26import android.content.BroadcastReceiver;
Jorim Jaggid9449862015-05-29 14:49:08 -070027import android.content.ComponentName;
Jorim Jaggia6310292014-04-16 14:11:52 +020028import android.content.Context;
29import android.content.Intent;
30import android.content.IntentFilter;
Jorim Jaggid9449862015-05-29 14:49:08 -070031import android.content.ServiceConnection;
32import android.content.pm.ActivityInfo;
Jorim Jaggi97b63c42014-05-02 23:03:34 +020033import android.content.pm.PackageManager;
Adrian Roosa06905b2014-05-28 12:13:48 +020034import android.content.pm.ResolveInfo;
Jorim Jaggie210cc82014-08-12 23:44:59 +020035import android.content.res.Configuration;
Yorke Lee583a20242014-08-12 18:47:08 -070036import android.os.AsyncTask;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020037import android.os.Bundle;
Jorim Jaggid9449862015-05-29 14:49:08 -070038import android.os.IBinder;
39import android.os.Message;
40import android.os.Messenger;
Jorim Jaggia6310292014-04-16 14:11:52 +020041import android.os.RemoteException;
42import android.os.UserHandle;
43import android.provider.MediaStore;
Jorim Jaggid9449862015-05-29 14:49:08 -070044import android.service.media.CameraPrewarmService;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070045import android.telecom.TelecomManager;
Jorim Jaggia6310292014-04-16 14:11:52 +020046import android.util.AttributeSet;
47import android.util.Log;
Jorim Jaggie210cc82014-08-12 23:44:59 +020048import android.util.TypedValue;
Jorim Jaggia6310292014-04-16 14:11:52 +020049import android.view.View;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +020050import android.view.ViewGroup;
Robert Carrfd10cd12016-06-29 16:41:50 -070051import android.view.WindowManager;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020052import android.view.accessibility.AccessibilityNodeInfo;
Jorim Jaggia6310292014-04-16 14:11:52 +020053import android.widget.FrameLayout;
Jorim Jaggie210cc82014-08-12 23:44:59 +020054import android.widget.TextView;
Adrian Roosa06905b2014-05-28 12:13:48 +020055
56import com.android.internal.widget.LockPatternUtils;
57import com.android.keyguard.KeyguardUpdateMonitor;
58import com.android.keyguard.KeyguardUpdateMonitorCallback;
Christoph Studerb0183992014-12-22 21:02:26 +010059import com.android.systemui.EventLogConstants;
60import com.android.systemui.EventLogTags;
Winsonc0d70582016-01-29 10:24:39 -080061import com.android.systemui.Interpolators;
Jorim Jaggia6310292014-04-16 14:11:52 +020062import com.android.systemui.R;
Selim Cineke70d6532015-04-24 16:46:13 -070063import com.android.systemui.assist.AssistManager;
Jason Monkb59f46f2016-09-27 12:29:18 -040064import com.android.systemui.plugins.IntentButtonProvider;
65import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
66import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
67import com.android.systemui.plugins.PluginListener;
68import com.android.systemui.plugins.PluginManager;
Jason Monk46767b72016-08-18 10:58:04 -040069import com.android.systemui.plugins.qs.QSContainer.ActivityStarter;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020070import com.android.systemui.statusbar.CommandQueue;
Selim Cinekbaa23272014-07-08 18:01:07 +020071import com.android.systemui.statusbar.KeyguardAffordanceView;
Jorim Jaggib2e104f2014-08-15 18:12:36 +020072import com.android.systemui.statusbar.KeyguardIndicationController;
73import com.android.systemui.statusbar.policy.AccessibilityController;
74import com.android.systemui.statusbar.policy.FlashlightController;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +020075import com.android.systemui.statusbar.policy.PreviewInflater;
Jorim Jaggia6310292014-04-16 14:11:52 +020076
77/**
78 * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
79 * text.
80 */
Selim Cinek4c6969a2014-05-26 19:22:17 +020081public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
Jorim Jaggib2e104f2014-08-15 18:12:36 +020082 UnlockMethodCache.OnUnlockMethodChangedListener,
83 AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener {
Jorim Jaggia6310292014-04-16 14:11:52 +020084
85 final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
86
Jorim Jaggi40aa8812015-09-23 12:59:22 -070087 public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
88 public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
89 public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
90
91 public static final String EXTRA_CAMERA_LAUNCH_SOURCE
92 = "com.android.systemui.camera_launch_source";
93
Jason Monkb59f46f2016-09-27 12:29:18 -040094 private static final String LEFT_BUTTON_PLUGIN
95 = "com.android.systemui.action.PLUGIN_LOCKSCREEN_LEFT_BUTTON";
96 private static final String RIGHT_BUTTON_PLUGIN
97 = "com.android.systemui.action.PLUGIN_LOCKSCREEN_RIGHT_BUTTON";
98
Adrian Roosa06905b2014-05-28 12:13:48 +020099 private static final Intent SECURE_CAMERA_INTENT =
100 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
101 .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Selim Cinek372d1bd2015-08-14 13:19:37 -0700102 public static final Intent INSECURE_CAMERA_INTENT =
Adrian Roosa06905b2014-05-28 12:13:48 +0200103 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200104 private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100105 private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
106 private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200107
Jason Monkb59f46f2016-09-27 12:29:18 -0400108 private KeyguardAffordanceView mRightAffordanceView;
Selim Cineke70d6532015-04-24 16:46:13 -0700109 private KeyguardAffordanceView mLeftAffordanceView;
Jorim Jaggi27267d62015-04-28 13:27:12 -0700110 private LockIcon mLockIcon;
Jorim Jaggie210cc82014-08-12 23:44:59 +0200111 private TextView mIndicationText;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200112 private ViewGroup mPreviewContainer;
113
Selim Cineke70d6532015-04-24 16:46:13 -0700114 private View mLeftPreview;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200115 private View mCameraPreview;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200116
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200117 private ActivityStarter mActivityStarter;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200118 private UnlockMethodCache mUnlockMethodCache;
Adrian Roosa06905b2014-05-28 12:13:48 +0200119 private LockPatternUtils mLockPatternUtils;
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200120 private FlashlightController mFlashlightController;
Jorim Jaggi781c29c2014-08-05 20:39:15 +0200121 private PreviewInflater mPreviewInflater;
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200122 private KeyguardIndicationController mIndicationController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200123 private AccessibilityController mAccessibilityController;
124 private PhoneStatusBar mPhoneStatusBar;
Adrian Roos2fe592d2014-05-17 03:11:59 +0200125
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700126 private boolean mUserSetupComplete;
Jorim Jaggid9449862015-05-29 14:49:08 -0700127 private boolean mPrewarmBound;
128 private Messenger mPrewarmMessenger;
129 private final ServiceConnection mPrewarmConnection = new ServiceConnection() {
130
131 @Override
132 public void onServiceConnected(ComponentName name, IBinder service) {
133 mPrewarmMessenger = new Messenger(service);
Jorim Jaggid9449862015-05-29 14:49:08 -0700134 }
135
136 @Override
137 public void onServiceDisconnected(ComponentName name) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700138 mPrewarmMessenger = null;
139 }
140 };
141
Selim Cineke70d6532015-04-24 16:46:13 -0700142 private boolean mLeftIsVoiceAssist;
143 private AssistManager mAssistManager;
Adrian Roos72cc3702014-09-18 17:25:09 +0200144
Jason Monkb59f46f2016-09-27 12:29:18 -0400145 private IntentButton mRightButton = new DefaultRightButton();
146 private IntentButton mLeftButton = new DefaultLeftButton();
147
Jorim Jaggia6310292014-04-16 14:11:52 +0200148 public KeyguardBottomAreaView(Context context) {
Adrian Roos2e3ccbb2014-08-19 22:23:37 +0200149 this(context, null);
Jorim Jaggia6310292014-04-16 14:11:52 +0200150 }
151
152 public KeyguardBottomAreaView(Context context, AttributeSet attrs) {
Adrian Roos2e3ccbb2014-08-19 22:23:37 +0200153 this(context, attrs, 0);
Jorim Jaggia6310292014-04-16 14:11:52 +0200154 }
155
156 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) {
Adrian Roos2e3ccbb2014-08-19 22:23:37 +0200157 this(context, attrs, defStyleAttr, 0);
Jorim Jaggia6310292014-04-16 14:11:52 +0200158 }
159
160 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
161 int defStyleRes) {
162 super(context, attrs, defStyleAttr, defStyleRes);
163 }
164
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200165 private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
166 @Override
167 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
168 super.onInitializeAccessibilityNodeInfo(host, info);
169 String label = null;
170 if (host == mLockIcon) {
171 label = getResources().getString(R.string.unlock_label);
Jason Monkb59f46f2016-09-27 12:29:18 -0400172 } else if (host == mRightAffordanceView) {
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200173 label = getResources().getString(R.string.camera_label);
Selim Cineke70d6532015-04-24 16:46:13 -0700174 } else if (host == mLeftAffordanceView) {
175 if (mLeftIsVoiceAssist) {
176 label = getResources().getString(R.string.voice_assist_label);
177 } else {
178 label = getResources().getString(R.string.phone_label);
179 }
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200180 }
181 info.addAction(new AccessibilityAction(ACTION_CLICK, label));
182 }
183
184 @Override
185 public boolean performAccessibilityAction(View host, int action, Bundle args) {
186 if (action == ACTION_CLICK) {
187 if (host == mLockIcon) {
188 mPhoneStatusBar.animateCollapsePanels(
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +0100189 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200190 return true;
Jason Monkb59f46f2016-09-27 12:29:18 -0400191 } else if (host == mRightAffordanceView) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700192 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200193 return true;
Selim Cineke70d6532015-04-24 16:46:13 -0700194 } else if (host == mLeftAffordanceView) {
195 launchLeftAffordance();
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200196 return true;
197 }
198 }
199 return super.performAccessibilityAction(host, action, args);
200 }
201 };
202
Jorim Jaggia6310292014-04-16 14:11:52 +0200203 @Override
204 protected void onFinishInflate() {
205 super.onFinishInflate();
Adrian Roosa06905b2014-05-28 12:13:48 +0200206 mLockPatternUtils = new LockPatternUtils(mContext);
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200207 mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
Jason Monkb59f46f2016-09-27 12:29:18 -0400208 mRightAffordanceView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
Selim Cineke70d6532015-04-24 16:46:13 -0700209 mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
Jorim Jaggi27267d62015-04-28 13:27:12 -0700210 mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
Jorim Jaggie210cc82014-08-12 23:44:59 +0200211 mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
Adrian Roosa06905b2014-05-28 12:13:48 +0200212 watchForCameraPolicyChanges();
Jorim Jaggia6310292014-04-16 14:11:52 +0200213 updateCameraVisibility();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200214 mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
215 mUnlockMethodCache.addListener(this);
Jorim Jaggi27267d62015-04-28 13:27:12 -0700216 mLockIcon.update();
Selim Cinekbaa23272014-07-08 18:01:07 +0200217 setClipChildren(false);
218 setClipToPadding(false);
Jorim Jaggi781c29c2014-08-05 20:39:15 +0200219 mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
Selim Cineke70d6532015-04-24 16:46:13 -0700220 inflateCameraPreview();
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200221 mLockIcon.setOnClickListener(this);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200222 mLockIcon.setOnLongClickListener(this);
Jason Monkb59f46f2016-09-27 12:29:18 -0400223 mRightAffordanceView.setOnClickListener(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700224 mLeftAffordanceView.setOnClickListener(this);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200225 initAccessibility();
226 }
227
Jason Monkb59f46f2016-09-27 12:29:18 -0400228 @Override
229 protected void onAttachedToWindow() {
230 super.onAttachedToWindow();
231 PluginManager.getInstance(getContext()).addPluginListener(RIGHT_BUTTON_PLUGIN,
232 mRightListener, IntentButtonProvider.VERSION, false /* Only allow one */);
233 PluginManager.getInstance(getContext()).addPluginListener(LEFT_BUTTON_PLUGIN,
234 mLeftListener, IntentButtonProvider.VERSION, false /* Only allow one */);
235 }
236
237 @Override
238 protected void onDetachedFromWindow() {
239 super.onDetachedFromWindow();
240 PluginManager.getInstance(getContext()).removePluginListener(mRightListener);
241 PluginManager.getInstance(getContext()).removePluginListener(mLeftListener);
242 }
243
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200244 private void initAccessibility() {
245 mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
Selim Cineke70d6532015-04-24 16:46:13 -0700246 mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
Jason Monkb59f46f2016-09-27 12:29:18 -0400247 mRightAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
Jorim Jaggia6310292014-04-16 14:11:52 +0200248 }
249
Jorim Jaggie210cc82014-08-12 23:44:59 +0200250 @Override
251 protected void onConfigurationChanged(Configuration newConfig) {
252 super.onConfigurationChanged(newConfig);
253 int indicationBottomMargin = getResources().getDimensionPixelSize(
254 R.dimen.keyguard_indication_margin_bottom);
255 MarginLayoutParams mlp = (MarginLayoutParams) mIndicationText.getLayoutParams();
256 if (mlp.bottomMargin != indicationBottomMargin) {
257 mlp.bottomMargin = indicationBottomMargin;
258 mIndicationText.setLayoutParams(mlp);
259 }
260
261 // Respect font size setting.
262 mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
263 getResources().getDimensionPixelSize(
264 com.android.internal.R.dimen.text_size_small_material));
Selim Cinek6ebba592016-05-31 15:28:28 -0700265
Jason Monkb59f46f2016-09-27 12:29:18 -0400266 ViewGroup.LayoutParams lp = mRightAffordanceView.getLayoutParams();
Selim Cinek6ebba592016-05-31 15:28:28 -0700267 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
268 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
Jason Monkb59f46f2016-09-27 12:29:18 -0400269 mRightAffordanceView.setLayoutParams(lp);
270 updateRightAffordanceIcon();
Selim Cinek6ebba592016-05-31 15:28:28 -0700271
272 lp = mLockIcon.getLayoutParams();
273 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
274 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
275 mLockIcon.setLayoutParams(lp);
276 mLockIcon.update(true /* force */);
277
278 lp = mLeftAffordanceView.getLayoutParams();
279 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
280 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
281 mLeftAffordanceView.setLayoutParams(lp);
282 updateLeftAffordanceIcon();
Jorim Jaggie210cc82014-08-12 23:44:59 +0200283 }
284
Jason Monkb59f46f2016-09-27 12:29:18 -0400285 private void updateRightAffordanceIcon() {
286 IconState state = mRightButton.getIcon();
287 mRightAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE);
288 mRightAffordanceView.setImageDrawable(state.drawable);
289 mRightAffordanceView.setContentDescription(state.contentDescription);
290 }
291
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200292 public void setActivityStarter(ActivityStarter activityStarter) {
293 mActivityStarter = activityStarter;
294 }
295
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200296 public void setFlashlightController(FlashlightController flashlightController) {
297 mFlashlightController = flashlightController;
298 }
299
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200300 public void setAccessibilityController(AccessibilityController accessibilityController) {
301 mAccessibilityController = accessibilityController;
Jorim Jaggi27267d62015-04-28 13:27:12 -0700302 mLockIcon.setAccessibilityController(accessibilityController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200303 accessibilityController.addStateChangedCallback(this);
304 }
305
306 public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
307 mPhoneStatusBar = phoneStatusBar;
Dan Sandlere163a642015-03-01 22:58:32 -0500308 updateCameraVisibility(); // in case onFinishInflate() was called too early
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200309 }
310
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700311 public void setUserSetupComplete(boolean userSetupComplete) {
312 mUserSetupComplete = userSetupComplete;
313 updateCameraVisibility();
314 updateLeftAffordanceIcon();
315 }
316
Adrian Roosa06905b2014-05-28 12:13:48 +0200317 private Intent getCameraIntent() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400318 return mRightButton.getIntent();
Adrian Roosa06905b2014-05-28 12:13:48 +0200319 }
320
Zhentao Sun04f97402015-08-26 17:37:30 -0700321 /**
322 * Resolves the intent to launch the camera application.
323 */
324 public ResolveInfo resolveCameraIntent() {
325 return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
326 PackageManager.MATCH_DEFAULT_ONLY,
327 KeyguardUpdateMonitor.getCurrentUser());
328 }
329
Jorim Jaggia6310292014-04-16 14:11:52 +0200330 private void updateCameraVisibility() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400331 if (mRightAffordanceView == null) {
Dan Sandlere163a642015-03-01 22:58:32 -0500332 // Things are not set up yet; reply hazy, ask again later
333 return;
334 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400335 mRightAffordanceView.setVisibility(mRightButton.getIcon().isVisible
336 ? View.VISIBLE : View.GONE);
Jorim Jaggia6310292014-04-16 14:11:52 +0200337 }
338
Selim Cineke70d6532015-04-24 16:46:13 -0700339 private void updateLeftAffordanceIcon() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400340 IconState state = mLeftButton.getIcon();
341 mLeftAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE);
342 mLeftAffordanceView.setImageDrawable(state.drawable);
343 mLeftAffordanceView.setContentDescription(state.contentDescription);
Selim Cineke70d6532015-04-24 16:46:13 -0700344 }
345
346 public boolean isLeftVoiceAssist() {
347 return mLeftIsVoiceAssist;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200348 }
349
350 private boolean isPhoneVisible() {
351 PackageManager pm = mContext.getPackageManager();
352 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
353 && pm.resolveActivity(PHONE_INTENT, 0) != null;
354 }
355
Jorim Jaggia6310292014-04-16 14:11:52 +0200356 private boolean isCameraDisabledByDpm() {
357 final DevicePolicyManager dpm =
358 (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
Dan Sandlere163a642015-03-01 22:58:32 -0500359 if (dpm != null && mPhoneStatusBar != null) {
Jorim Jaggia6310292014-04-16 14:11:52 +0200360 try {
361 final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
362 final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
363 final boolean disabledBecauseKeyguardSecure =
364 (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
Jim Millerab954542014-10-10 18:21:49 -0700365 && mPhoneStatusBar.isKeyguardSecure();
Jorim Jaggia6310292014-04-16 14:11:52 +0200366 return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
367 } catch (RemoteException e) {
368 Log.e(TAG, "Can't get userId", e);
369 }
370 }
371 return false;
372 }
373
Adrian Roosa06905b2014-05-28 12:13:48 +0200374 private void watchForCameraPolicyChanges() {
Jorim Jaggia6310292014-04-16 14:11:52 +0200375 final IntentFilter filter = new IntentFilter();
376 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Adrian Roosa06905b2014-05-28 12:13:48 +0200377 getContext().registerReceiverAsUser(mDevicePolicyReceiver,
378 UserHandle.ALL, filter, null, null);
379 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
Jorim Jaggia6310292014-04-16 14:11:52 +0200380 }
381
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200382 @Override
383 public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
Jason Monkb59f46f2016-09-27 12:29:18 -0400384 mRightAffordanceView.setClickable(touchExplorationEnabled);
Selim Cineke70d6532015-04-24 16:46:13 -0700385 mLeftAffordanceView.setClickable(touchExplorationEnabled);
Jason Monkb59f46f2016-09-27 12:29:18 -0400386 mRightAffordanceView.setFocusable(accessibilityEnabled);
Selim Cineke70d6532015-04-24 16:46:13 -0700387 mLeftAffordanceView.setFocusable(accessibilityEnabled);
Jorim Jaggi27267d62015-04-28 13:27:12 -0700388 mLockIcon.update();
Jorim Jaggia6310292014-04-16 14:11:52 +0200389 }
390
Selim Cinek4c6969a2014-05-26 19:22:17 +0200391 @Override
392 public void onClick(View v) {
Jason Monkb59f46f2016-09-27 12:29:18 -0400393 if (v == mRightAffordanceView) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700394 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
Selim Cineke70d6532015-04-24 16:46:13 -0700395 } else if (v == mLeftAffordanceView) {
396 launchLeftAffordance();
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200397 } if (v == mLockIcon) {
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200398 if (!mAccessibilityController.isAccessibilityEnabled()) {
399 handleTrustCircleClick();
400 } else {
401 mPhoneStatusBar.animateCollapsePanels(
402 CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
403 }
Selim Cinek4c6969a2014-05-26 19:22:17 +0200404 }
405 }
406
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200407 @Override
408 public boolean onLongClick(View v) {
409 handleTrustCircleClick();
410 return true;
411 }
412
413 private void handleTrustCircleClick() {
Christoph Studerb0183992014-12-22 21:02:26 +0100414 EventLogTags.writeSysuiLockscreenGesture(
415 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK, 0 /* lengthDp - N/A */,
416 0 /* velocityDp - N/A */);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200417 mIndicationController.showTransientIndication(
418 R.string.keyguard_indication_trust_disabled);
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700419 mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200420 }
421
Jorim Jaggid9449862015-05-29 14:49:08 -0700422 public void bindCameraPrewarmService() {
Adrian Roosa06905b2014-05-28 12:13:48 +0200423 Intent intent = getCameraIntent();
Jorim Jaggid9449862015-05-29 14:49:08 -0700424 ActivityInfo targetInfo = PreviewInflater.getTargetActivityInfo(mContext, intent,
Selim Cinek5f145022016-08-02 16:00:12 -0700425 KeyguardUpdateMonitor.getCurrentUser(), true /* onlyDirectBootAware */);
Jorim Jaggi8b8fa3e2015-08-18 18:33:49 -0700426 if (targetInfo != null && targetInfo.metaData != null) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700427 String clazz = targetInfo.metaData.getString(
428 MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE);
429 if (clazz != null) {
430 Intent serviceIntent = new Intent();
431 serviceIntent.setClassName(targetInfo.packageName, clazz);
432 serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
433 try {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700434 if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
Selim Cinekedf47482015-09-01 18:05:08 -0700435 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
436 new UserHandle(UserHandle.USER_CURRENT))) {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700437 mPrewarmBound = true;
438 }
Jorim Jaggid9449862015-05-29 14:49:08 -0700439 } catch (SecurityException e) {
440 Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName
441 + " class=" + clazz, e);
442 }
443 }
Jorim Jaggia86790b2015-04-02 16:32:29 -0700444 }
445 }
446
Jorim Jaggid9449862015-05-29 14:49:08 -0700447 public void unbindCameraPrewarmService(boolean launched) {
448 if (mPrewarmBound) {
Jorim Jaggif610bd72015-08-17 20:17:30 -0700449 if (mPrewarmMessenger != null && launched) {
Jorim Jaggid9449862015-05-29 14:49:08 -0700450 try {
451 mPrewarmMessenger.send(Message.obtain(null /* handler */,
452 CameraPrewarmService.MSG_CAMERA_FIRED));
453 } catch (RemoteException e) {
454 Log.w(TAG, "Error sending camera fired message", e);
455 }
456 }
457 mContext.unbindService(mPrewarmConnection);
458 mPrewarmBound = false;
Jorim Jaggia86790b2015-04-02 16:32:29 -0700459 }
460 }
461
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700462 public void launchCamera(String source) {
Jorim Jaggia86790b2015-04-02 16:32:29 -0700463 final Intent intent = getCameraIntent();
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700464 intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200465 boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700466 mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
Jorim Jaggi746f7fa2014-08-27 17:52:46 +0200467 if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
Jorim Jaggia86790b2015-04-02 16:32:29 -0700468 AsyncTask.execute(new Runnable() {
469 @Override
470 public void run() {
Jorim Jaggid9449862015-05-29 14:49:08 -0700471 int result = ActivityManager.START_CANCELED;
Robert Carrfd10cd12016-06-29 16:41:50 -0700472
473 // Normally an activity will set it's requested rotation
474 // animation on its window. However when launching an activity
475 // causes the orientation to change this is too late. In these cases
476 // the default animation is used. This doesn't look good for
477 // the camera (as it rotates the camera contents out of sync
478 // with physical reality). So, we ask the WindowManager to
479 // force the crossfade animation if an orientation change
480 // happens to occur during the launch.
481 ActivityOptions o = ActivityOptions.makeBasic();
482 o.setRotationAnimationHint(
Robert Carr57d9fbd2016-08-15 12:00:35 -0700483 WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
Jorim Jaggid9449862015-05-29 14:49:08 -0700484 try {
485 result = ActivityManagerNative.getDefault().startActivityAsUser(
486 null, getContext().getBasePackageName(),
487 intent,
488 intent.resolveTypeIfNeeded(getContext().getContentResolver()),
Robert Carrfd10cd12016-06-29 16:41:50 -0700489 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(),
Jorim Jaggid9449862015-05-29 14:49:08 -0700490 UserHandle.CURRENT.getIdentifier());
491 } catch (RemoteException e) {
492 Log.w(TAG, "Unable to start camera activity", e);
493 }
Selim Cineke70d6532015-04-24 16:46:13 -0700494 mActivityStarter.preventNextAnimation();
Jorim Jaggid9449862015-05-29 14:49:08 -0700495 final boolean launched = isSuccessfulLaunch(result);
496 post(new Runnable() {
497 @Override
498 public void run() {
499 unbindCameraPrewarmService(launched);
500 }
501 });
Jorim Jaggia86790b2015-04-02 16:32:29 -0700502 }
503 });
Adrian Roosa06905b2014-05-28 12:13:48 +0200504 } else {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +0200505
506 // We need to delay starting the activity because ResolverActivity finishes itself if
507 // launched behind lockscreen.
Jorim Jaggid9449862015-05-29 14:49:08 -0700508 mActivityStarter.startActivity(intent, false /* dismissShade */,
509 new ActivityStarter.Callback() {
510 @Override
511 public void onActivityStarted(int resultCode) {
512 unbindCameraPrewarmService(isSuccessfulLaunch(resultCode));
513 }
514 });
Adrian Roosa06905b2014-05-28 12:13:48 +0200515 }
Jorim Jaggia6310292014-04-16 14:11:52 +0200516 }
517
Jorim Jaggid9449862015-05-29 14:49:08 -0700518 private static boolean isSuccessfulLaunch(int result) {
519 return result == ActivityManager.START_SUCCESS
520 || result == ActivityManager.START_DELIVERED_TO_TOP
521 || result == ActivityManager.START_TASK_TO_FRONT;
522 }
523
Selim Cineke70d6532015-04-24 16:46:13 -0700524 public void launchLeftAffordance() {
525 if (mLeftIsVoiceAssist) {
526 launchVoiceAssist();
527 } else {
528 launchPhone();
529 }
530 }
531
532 private void launchVoiceAssist() {
533 Runnable runnable = new Runnable() {
534 @Override
535 public void run() {
536 mAssistManager.launchVoiceAssistFromKeyguard();
537 mActivityStarter.preventNextAnimation();
538 }
539 };
540 if (mPhoneStatusBar.isKeyguardCurrentlySecure()) {
541 AsyncTask.execute(runnable);
542 } else {
Jorim Jaggid9449862015-05-29 14:49:08 -0700543 mPhoneStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
Felipe Lemeee5d6302016-04-22 16:11:19 -0700544 false /* dismissShade */, false /* afterKeyguardGone */, true /* deferred */);
Selim Cineke70d6532015-04-24 16:46:13 -0700545 }
546 }
547
548 private boolean canLaunchVoiceAssist() {
549 return mAssistManager.canVoiceAssistBeLaunchedFromKeyguard();
550 }
551
552 private void launchPhone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700553 final TelecomManager tm = TelecomManager.from(mContext);
Nancy Chen0eb1e402014-08-21 22:52:29 -0700554 if (tm.isInCall()) {
Yorke Lee583a20242014-08-12 18:47:08 -0700555 AsyncTask.execute(new Runnable() {
556 @Override
557 public void run() {
Nancy Chen0eb1e402014-08-21 22:52:29 -0700558 tm.showInCallScreen(false /* showDialpad */);
Yorke Lee583a20242014-08-12 18:47:08 -0700559 }
560 });
561 } else {
Jason Monkb59f46f2016-09-27 12:29:18 -0400562 mActivityStarter.startActivity(mLeftButton.getIntent(), false /* dismissShade */);
Yorke Lee583a20242014-08-12 18:47:08 -0700563 }
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200564 }
565
Adrian Roos2fe592d2014-05-17 03:11:59 +0200566
567 @Override
568 protected void onVisibilityChanged(View changedView, int visibility) {
569 super.onVisibilityChanged(changedView, visibility);
570 if (changedView == this && visibility == VISIBLE) {
Jorim Jaggi27267d62015-04-28 13:27:12 -0700571 mLockIcon.update();
Adrian Roosa06905b2014-05-28 12:13:48 +0200572 updateCameraVisibility();
Adrian Roos2fe592d2014-05-17 03:11:59 +0200573 }
574 }
575
Selim Cineke70d6532015-04-24 16:46:13 -0700576 public KeyguardAffordanceView getLeftView() {
577 return mLeftAffordanceView;
Selim Cinek4c6969a2014-05-26 19:22:17 +0200578 }
579
Selim Cineke70d6532015-04-24 16:46:13 -0700580 public KeyguardAffordanceView getRightView() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400581 return mRightAffordanceView;
Selim Cinek4c6969a2014-05-26 19:22:17 +0200582 }
583
Selim Cineke70d6532015-04-24 16:46:13 -0700584 public View getLeftPreview() {
585 return mLeftPreview;
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200586 }
587
Selim Cineke70d6532015-04-24 16:46:13 -0700588 public View getRightPreview() {
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200589 return mCameraPreview;
590 }
591
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700592 public LockIcon getLockIcon() {
Selim Cinek4c6969a2014-05-26 19:22:17 +0200593 return mLockIcon;
594 }
595
Selim Cinekf99d0002014-06-13 07:36:01 +0200596 public View getIndicationView() {
597 return mIndicationText;
598 }
599
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200600 @Override
Jorim Jaggi2580a9762014-06-25 03:08:25 +0200601 public boolean hasOverlappingRendering() {
602 return false;
603 }
604
605 @Override
Christoph Studer2231c6e2014-12-19 12:40:13 +0100606 public void onUnlockMethodStateChanged() {
Jorim Jaggi27267d62015-04-28 13:27:12 -0700607 mLockIcon.update();
Adrian Roosa06905b2014-05-28 12:13:48 +0200608 updateCameraVisibility();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200609 }
Adrian Roosa06905b2014-05-28 12:13:48 +0200610
Selim Cineke70d6532015-04-24 16:46:13 -0700611 private void inflateCameraPreview() {
Selim Cinek5f145022016-08-02 16:00:12 -0700612 View previewBefore = mCameraPreview;
613 boolean visibleBefore = false;
614 if (previewBefore != null) {
615 mPreviewContainer.removeView(previewBefore);
616 visibleBefore = previewBefore.getVisibility() == View.VISIBLE;
617 }
Jorim Jaggi781c29c2014-08-05 20:39:15 +0200618 mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200619 if (mCameraPreview != null) {
620 mPreviewContainer.addView(mCameraPreview);
Selim Cinek5f145022016-08-02 16:00:12 -0700621 mCameraPreview.setVisibility(visibleBefore ? View.VISIBLE : View.INVISIBLE);
Jorim Jaggib6cdcbc2014-07-25 21:58:29 +0200622 }
623 }
624
Selim Cineke70d6532015-04-24 16:46:13 -0700625 private void updateLeftPreview() {
626 View previewBefore = mLeftPreview;
627 if (previewBefore != null) {
628 mPreviewContainer.removeView(previewBefore);
629 }
630 if (mLeftIsVoiceAssist) {
631 mLeftPreview = mPreviewInflater.inflatePreviewFromService(
632 mAssistManager.getVoiceInteractorComponentName());
633 } else {
Jason Monkb59f46f2016-09-27 12:29:18 -0400634 mLeftPreview = mPreviewInflater.inflatePreview(mLeftButton.getIntent());
Selim Cineke70d6532015-04-24 16:46:13 -0700635 }
636 if (mLeftPreview != null) {
637 mPreviewContainer.addView(mLeftPreview);
638 mLeftPreview.setVisibility(View.INVISIBLE);
639 }
640 }
641
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100642 public void startFinishDozeAnimation() {
643 long delay = 0;
Selim Cineke70d6532015-04-24 16:46:13 -0700644 if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
645 startFinishDozeAnimationElement(mLeftAffordanceView, delay);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100646 delay += DOZE_ANIMATION_STAGGER_DELAY;
647 }
648 startFinishDozeAnimationElement(mLockIcon, delay);
649 delay += DOZE_ANIMATION_STAGGER_DELAY;
Jason Monkb59f46f2016-09-27 12:29:18 -0400650 if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
651 startFinishDozeAnimationElement(mRightAffordanceView, delay);
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100652 }
653 mIndicationText.setAlpha(0f);
654 mIndicationText.animate()
655 .alpha(1f)
Selim Cinekc18010f2016-01-20 13:41:30 -0800656 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100657 .setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
658 }
659
660 private void startFinishDozeAnimationElement(View element, long delay) {
661 element.setAlpha(0f);
662 element.setTranslationY(element.getHeight() / 2);
663 element.animate()
664 .alpha(1f)
665 .translationY(0f)
Selim Cinekc18010f2016-01-20 13:41:30 -0800666 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
Jorim Jaggi16423aa2014-10-28 11:42:58 +0100667 .setStartDelay(delay)
668 .setDuration(DOZE_ANIMATION_ELEMENT_DURATION);
669 }
670
Adrian Roosa06905b2014-05-28 12:13:48 +0200671 private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
Jim Millerb29814c2015-08-05 19:03:01 -0700672 @Override
Adrian Roosa06905b2014-05-28 12:13:48 +0200673 public void onReceive(Context context, Intent intent) {
674 post(new Runnable() {
675 @Override
676 public void run() {
677 updateCameraVisibility();
678 }
679 });
680 }
681 };
682
683 private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
684 new KeyguardUpdateMonitorCallback() {
Jason Monkb59f46f2016-09-27 12:29:18 -0400685 @Override
686 public void onUserSwitchComplete(int userId) {
687 updateCameraVisibility();
688 }
Jorim Jaggie7b12522014-08-06 16:41:21 +0200689
Jason Monkb59f46f2016-09-27 12:29:18 -0400690 @Override
691 public void onStartedWakingUp() {
692 mLockIcon.setDeviceInteractive(true);
693 }
Adrian Roos2e3ccbb2014-08-19 22:23:37 +0200694
Jason Monkb59f46f2016-09-27 12:29:18 -0400695 @Override
696 public void onFinishedGoingToSleep(int why) {
697 mLockIcon.setDeviceInteractive(false);
698 }
Adrian Roosb9ae0902014-10-27 14:20:30 +0100699
Jason Monkb59f46f2016-09-27 12:29:18 -0400700 @Override
701 public void onScreenTurnedOn() {
702 mLockIcon.setScreenOn(true);
703 }
Jorim Jaggif1518da2015-07-30 11:56:36 -0700704
Jason Monkb59f46f2016-09-27 12:29:18 -0400705 @Override
706 public void onScreenTurnedOff() {
707 mLockIcon.setScreenOn(false);
708 }
Jorim Jaggif1518da2015-07-30 11:56:36 -0700709
Jason Monkb59f46f2016-09-27 12:29:18 -0400710 @Override
711 public void onKeyguardVisibilityChanged(boolean showing) {
712 mLockIcon.update();
713 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700714
Jason Monkb59f46f2016-09-27 12:29:18 -0400715 @Override
716 public void onFingerprintRunningStateChanged(boolean running) {
717 mLockIcon.update();
718 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700719
Jason Monkb59f46f2016-09-27 12:29:18 -0400720 @Override
721 public void onStrongAuthStateChanged(int userId) {
722 mLockIcon.update();
723 }
724 };
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200725
726 public void setKeyguardIndicationController(
727 KeyguardIndicationController keyguardIndicationController) {
728 mIndicationController = keyguardIndicationController;
729 }
Selim Cineke70d6532015-04-24 16:46:13 -0700730
731 public void setAssistManager(AssistManager assistManager) {
732 mAssistManager = assistManager;
733 updateLeftAffordance();
734 }
735
736 public void updateLeftAffordance() {
737 updateLeftAffordanceIcon();
738 updateLeftPreview();
739 }
Selim Cinek5f145022016-08-02 16:00:12 -0700740
741 public void onKeyguardShowingChanged() {
742 updateLeftAffordance();
743 inflateCameraPreview();
744 }
Jason Monkb59f46f2016-09-27 12:29:18 -0400745
746 private void setRightButton(IntentButton button) {
747 mRightButton = button;
748 updateRightAffordanceIcon();
749 updateCameraVisibility();
750 inflateCameraPreview();
751 }
752
753 private void setLeftButton(IntentButton button) {
754 mLeftButton = button;
755 mLeftIsVoiceAssist = false;
756 updateLeftAffordance();
757 }
758
759 private final PluginListener<IntentButtonProvider> mRightListener =
760 new PluginListener<IntentButtonProvider>() {
761 @Override
762 public void onPluginConnected(IntentButtonProvider plugin) {
763 setRightButton(plugin.getIntentButton());
764 }
765
766 @Override
767 public void onPluginDisconnected(IntentButtonProvider plugin) {
768 setRightButton(new DefaultRightButton());
769 }
770 };
771
772 private final PluginListener<IntentButtonProvider> mLeftListener =
773 new PluginListener<IntentButtonProvider>() {
774 @Override
775 public void onPluginConnected(IntentButtonProvider plugin) {
776 setLeftButton(plugin.getIntentButton());
777 }
778
779 @Override
780 public void onPluginDisconnected(IntentButtonProvider plugin) {
781 setLeftButton(new DefaultLeftButton());
782 }
783 };
784
785 private class DefaultLeftButton implements IntentButton {
786
787 private IconState mIconState = new IconState();
788
789 @Override
790 public IconState getIcon() {
791 mLeftIsVoiceAssist = canLaunchVoiceAssist();
792 if (mLeftIsVoiceAssist) {
793 mIconState.isVisible = mUserSetupComplete;
794 mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
795 mIconState.contentDescription = mContext.getString(
796 R.string.accessibility_voice_assist_button);
797 } else {
798 mIconState.isVisible = mUserSetupComplete && isPhoneVisible();
799 mIconState.drawable = mContext.getDrawable(R.drawable.ic_phone_24dp);
800 mIconState.contentDescription = mContext.getString(
801 R.string.accessibility_phone_button);
802 }
803 return mIconState;
804 }
805
806 @Override
807 public Intent getIntent() {
808 return PHONE_INTENT;
809 }
810 }
811
812 private class DefaultRightButton implements IntentButton {
813
814 private IconState mIconState = new IconState();
815
816 @Override
817 public IconState getIcon() {
818 ResolveInfo resolved = resolveCameraIntent();
819 mIconState.isVisible = !isCameraDisabledByDpm() && resolved != null
820 && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
821 && mUserSetupComplete;
822 mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
823 mIconState.contentDescription =
824 mContext.getString(R.string.accessibility_camera_button);
825 return mIconState;
826 }
827
828 @Override
829 public Intent getIntent() {
830 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
831 boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
832 KeyguardUpdateMonitor.getCurrentUser());
833 boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
834 return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
835 }
836 }
Jorim Jaggia6310292014-04-16 14:11:52 +0200837}