2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 package com.android.systemui.statusbar.phone;
19 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
20 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
22 import android.app.ActivityManager;
23 import android.app.ActivityManagerNative;
24 import android.app.ActivityOptions;
25 import android.app.admin.DevicePolicyManager;
26 import android.content.BroadcastReceiver;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.content.ServiceConnection;
32 import android.content.pm.ActivityInfo;
33 import android.content.pm.PackageManager;
34 import android.content.pm.ResolveInfo;
35 import android.content.res.Configuration;
36 import android.os.AsyncTask;
37 import android.os.Bundle;
38 import android.os.IBinder;
39 import android.os.Message;
40 import android.os.Messenger;
41 import android.os.RemoteException;
42 import android.os.UserHandle;
43 import android.provider.MediaStore;
44 import android.service.media.CameraPrewarmService;
45 import android.telecom.TelecomManager;
46 import android.util.AttributeSet;
47 import android.util.Log;
48 import android.util.TypedValue;
49 import android.view.View;
50 import android.view.ViewGroup;
51 import android.view.WindowManager;
52 import android.view.accessibility.AccessibilityNodeInfo;
53 import android.widget.FrameLayout;
54 import android.widget.TextView;
56 import com.android.internal.widget.LockPatternUtils;
57 import com.android.keyguard.KeyguardUpdateMonitor;
58 import com.android.keyguard.KeyguardUpdateMonitorCallback;
59 import com.android.systemui.EventLogConstants;
60 import com.android.systemui.EventLogTags;
61 import com.android.systemui.Interpolators;
62 import com.android.systemui.R;
63 import com.android.systemui.assist.AssistManager;
64 import com.android.systemui.statusbar.CommandQueue;
65 import com.android.systemui.statusbar.KeyguardAffordanceView;
66 import com.android.systemui.statusbar.KeyguardIndicationController;
67 import com.android.systemui.statusbar.policy.AccessibilityController;
68 import com.android.systemui.statusbar.policy.FlashlightController;
69 import com.android.systemui.statusbar.policy.PreviewInflater;
72 * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
75 public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
76 UnlockMethodCache.OnUnlockMethodChangedListener,
77 AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener {
79 final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
81 public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
82 public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
83 public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
85 public static final String EXTRA_CAMERA_LAUNCH_SOURCE
86 = "com.android.systemui.camera_launch_source";
88 private static final Intent SECURE_CAMERA_INTENT =
89 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
90 .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
91 public static final Intent INSECURE_CAMERA_INTENT =
92 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
93 private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
94 private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
95 private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
97 private KeyguardAffordanceView mCameraImageView;
98 private KeyguardAffordanceView mLeftAffordanceView;
99 private LockIcon mLockIcon;
100 private TextView mIndicationText;
101 private ViewGroup mPreviewContainer;
103 private View mLeftPreview;
104 private View mCameraPreview;
106 private ActivityStarter mActivityStarter;
107 private UnlockMethodCache mUnlockMethodCache;
108 private LockPatternUtils mLockPatternUtils;
109 private FlashlightController mFlashlightController;
110 private PreviewInflater mPreviewInflater;
111 private KeyguardIndicationController mIndicationController;
112 private AccessibilityController mAccessibilityController;
113 private PhoneStatusBar mPhoneStatusBar;
114 private KeyguardAffordanceHelper mAffordanceHelper;
116 private boolean mUserSetupComplete;
117 private boolean mPrewarmBound;
118 private Messenger mPrewarmMessenger;
119 private final ServiceConnection mPrewarmConnection = new ServiceConnection() {
122 public void onServiceConnected(ComponentName name, IBinder service) {
123 mPrewarmMessenger = new Messenger(service);
127 public void onServiceDisconnected(ComponentName name) {
128 mPrewarmMessenger = null;
132 private boolean mLeftIsVoiceAssist;
133 private AssistManager mAssistManager;
135 public KeyguardBottomAreaView(Context context) {
139 public KeyguardBottomAreaView(Context context, AttributeSet attrs) {
140 this(context, attrs, 0);
143 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) {
144 this(context, attrs, defStyleAttr, 0);
147 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
149 super(context, attrs, defStyleAttr, defStyleRes);
152 private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
154 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
155 super.onInitializeAccessibilityNodeInfo(host, info);
157 if (host == mLockIcon) {
158 label = getResources().getString(R.string.unlock_label);
159 } else if (host == mCameraImageView) {
160 label = getResources().getString(R.string.camera_label);
161 } else if (host == mLeftAffordanceView) {
162 if (mLeftIsVoiceAssist) {
163 label = getResources().getString(R.string.voice_assist_label);
165 label = getResources().getString(R.string.phone_label);
168 info.addAction(new AccessibilityAction(ACTION_CLICK, label));
172 public boolean performAccessibilityAction(View host, int action, Bundle args) {
173 if (action == ACTION_CLICK) {
174 if (host == mLockIcon) {
175 mPhoneStatusBar.animateCollapsePanels(
176 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
178 } else if (host == mCameraImageView) {
179 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
181 } else if (host == mLeftAffordanceView) {
182 launchLeftAffordance();
186 return super.performAccessibilityAction(host, action, args);
191 protected void onFinishInflate() {
192 super.onFinishInflate();
193 mLockPatternUtils = new LockPatternUtils(mContext);
194 mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
195 mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
196 mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
197 mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
198 mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
199 watchForCameraPolicyChanges();
200 updateCameraVisibility();
201 mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
202 mUnlockMethodCache.addListener(this);
204 setClipChildren(false);
205 setClipToPadding(false);
206 mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
207 inflateCameraPreview();
208 mLockIcon.setOnClickListener(this);
209 mLockIcon.setOnLongClickListener(this);
210 mCameraImageView.setOnClickListener(this);
211 mLeftAffordanceView.setOnClickListener(this);
215 private void initAccessibility() {
216 mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
217 mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
218 mCameraImageView.setAccessibilityDelegate(mAccessibilityDelegate);
222 protected void onConfigurationChanged(Configuration newConfig) {
223 super.onConfigurationChanged(newConfig);
224 int indicationBottomMargin = getResources().getDimensionPixelSize(
225 R.dimen.keyguard_indication_margin_bottom);
226 MarginLayoutParams mlp = (MarginLayoutParams) mIndicationText.getLayoutParams();
227 if (mlp.bottomMargin != indicationBottomMargin) {
228 mlp.bottomMargin = indicationBottomMargin;
229 mIndicationText.setLayoutParams(mlp);
232 // Respect font size setting.
233 mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
234 getResources().getDimensionPixelSize(
235 com.android.internal.R.dimen.text_size_small_material));
237 ViewGroup.LayoutParams lp = mCameraImageView.getLayoutParams();
238 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
239 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
240 mCameraImageView.setLayoutParams(lp);
241 mCameraImageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_camera_alt_24dp));
243 lp = mLockIcon.getLayoutParams();
244 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
245 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
246 mLockIcon.setLayoutParams(lp);
247 mLockIcon.update(true /* force */);
249 lp = mLeftAffordanceView.getLayoutParams();
250 lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
251 lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
252 mLeftAffordanceView.setLayoutParams(lp);
253 updateLeftAffordanceIcon();
256 public void setActivityStarter(ActivityStarter activityStarter) {
257 mActivityStarter = activityStarter;
260 public void setFlashlightController(FlashlightController flashlightController) {
261 mFlashlightController = flashlightController;
264 public void setAccessibilityController(AccessibilityController accessibilityController) {
265 mAccessibilityController = accessibilityController;
266 mLockIcon.setAccessibilityController(accessibilityController);
267 accessibilityController.addStateChangedCallback(this);
270 public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
271 mPhoneStatusBar = phoneStatusBar;
272 updateCameraVisibility(); // in case onFinishInflate() was called too early
275 public void setAffordanceHelper(KeyguardAffordanceHelper affordanceHelper) {
276 mAffordanceHelper = affordanceHelper;
279 public void setUserSetupComplete(boolean userSetupComplete) {
280 mUserSetupComplete = userSetupComplete;
281 updateCameraVisibility();
282 updateLeftAffordanceIcon();
285 private Intent getCameraIntent() {
286 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
287 boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
288 KeyguardUpdateMonitor.getCurrentUser());
289 boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
290 return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
294 * Resolves the intent to launch the camera application.
296 public ResolveInfo resolveCameraIntent() {
297 return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
298 PackageManager.MATCH_DEFAULT_ONLY,
299 KeyguardUpdateMonitor.getCurrentUser());
302 private void updateCameraVisibility() {
303 if (mCameraImageView == null) {
304 // Things are not set up yet; reply hazy, ask again later
307 ResolveInfo resolved = resolveCameraIntent();
308 boolean visible = !isCameraDisabledByDpm() && resolved != null
309 && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
310 && mUserSetupComplete;
311 mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
314 private void updateLeftAffordanceIcon() {
315 mLeftIsVoiceAssist = canLaunchVoiceAssist();
317 int contentDescription;
318 boolean visible = mUserSetupComplete;
319 if (mLeftIsVoiceAssist) {
320 drawableId = R.drawable.ic_mic_26dp;
321 contentDescription = R.string.accessibility_voice_assist_button;
323 visible &= isPhoneVisible();
324 drawableId = R.drawable.ic_phone_24dp;
325 contentDescription = R.string.accessibility_phone_button;
327 mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE);
328 mLeftAffordanceView.setImageDrawable(mContext.getDrawable(drawableId));
329 mLeftAffordanceView.setContentDescription(mContext.getString(contentDescription));
332 public boolean isLeftVoiceAssist() {
333 return mLeftIsVoiceAssist;
336 private boolean isPhoneVisible() {
337 PackageManager pm = mContext.getPackageManager();
338 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
339 && pm.resolveActivity(PHONE_INTENT, 0) != null;
342 private boolean isCameraDisabledByDpm() {
343 final DevicePolicyManager dpm =
344 (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
345 if (dpm != null && mPhoneStatusBar != null) {
347 final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
348 final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
349 final boolean disabledBecauseKeyguardSecure =
350 (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
351 && mPhoneStatusBar.isKeyguardSecure();
352 return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
353 } catch (RemoteException e) {
354 Log.e(TAG, "Can't get userId", e);
360 private void watchForCameraPolicyChanges() {
361 final IntentFilter filter = new IntentFilter();
362 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
363 getContext().registerReceiverAsUser(mDevicePolicyReceiver,
364 UserHandle.ALL, filter, null, null);
365 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
369 public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
370 mCameraImageView.setClickable(touchExplorationEnabled);
371 mLeftAffordanceView.setClickable(touchExplorationEnabled);
372 mCameraImageView.setFocusable(accessibilityEnabled);
373 mLeftAffordanceView.setFocusable(accessibilityEnabled);
378 public void onClick(View v) {
379 if (v == mCameraImageView) {
380 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
381 } else if (v == mLeftAffordanceView) {
382 launchLeftAffordance();
383 } if (v == mLockIcon) {
384 if (!mAccessibilityController.isAccessibilityEnabled()) {
385 handleTrustCircleClick();
387 mPhoneStatusBar.animateCollapsePanels(
388 CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
394 public boolean onLongClick(View v) {
395 handleTrustCircleClick();
399 private void handleTrustCircleClick() {
400 EventLogTags.writeSysuiLockscreenGesture(
401 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK, 0 /* lengthDp - N/A */,
402 0 /* velocityDp - N/A */);
403 mIndicationController.showTransientIndication(
404 R.string.keyguard_indication_trust_disabled);
405 mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
408 public void bindCameraPrewarmService() {
409 Intent intent = getCameraIntent();
410 ActivityInfo targetInfo = PreviewInflater.getTargetActivityInfo(mContext, intent,
411 KeyguardUpdateMonitor.getCurrentUser(), true /* onlyDirectBootAware */);
412 if (targetInfo != null && targetInfo.metaData != null) {
413 String clazz = targetInfo.metaData.getString(
414 MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE);
416 Intent serviceIntent = new Intent();
417 serviceIntent.setClassName(targetInfo.packageName, clazz);
418 serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
420 if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
421 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
422 new UserHandle(UserHandle.USER_CURRENT))) {
423 mPrewarmBound = true;
425 } catch (SecurityException e) {
426 Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName
427 + " class=" + clazz, e);
433 public void unbindCameraPrewarmService(boolean launched) {
435 if (mPrewarmMessenger != null && launched) {
437 mPrewarmMessenger.send(Message.obtain(null /* handler */,
438 CameraPrewarmService.MSG_CAMERA_FIRED));
439 } catch (RemoteException e) {
440 Log.w(TAG, "Error sending camera fired message", e);
443 mContext.unbindService(mPrewarmConnection);
444 mPrewarmBound = false;
448 public void launchCamera(String source) {
449 final Intent intent = getCameraIntent();
450 intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
451 boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
452 mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
453 if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
454 AsyncTask.execute(new Runnable() {
457 int result = ActivityManager.START_CANCELED;
459 // Normally an activity will set it's requested rotation
460 // animation on its window. However when launching an activity
461 // causes the orientation to change this is too late. In these cases
462 // the default animation is used. This doesn't look good for
463 // the camera (as it rotates the camera contents out of sync
464 // with physical reality). So, we ask the WindowManager to
465 // force the crossfade animation if an orientation change
466 // happens to occur during the launch.
467 ActivityOptions o = ActivityOptions.makeBasic();
468 o.setRotationAnimationHint(
469 WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
471 result = ActivityManagerNative.getDefault().startActivityAsUser(
472 null, getContext().getBasePackageName(),
474 intent.resolveTypeIfNeeded(getContext().getContentResolver()),
475 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(),
476 UserHandle.CURRENT.getIdentifier());
477 } catch (RemoteException e) {
478 Log.w(TAG, "Unable to start camera activity", e);
480 mActivityStarter.preventNextAnimation();
481 final boolean launched = isSuccessfulLaunch(result);
482 post(new Runnable() {
485 unbindCameraPrewarmService(launched);
492 // We need to delay starting the activity because ResolverActivity finishes itself if
493 // launched behind lockscreen.
494 mActivityStarter.startActivity(intent, false /* dismissShade */,
495 new ActivityStarter.Callback() {
497 public void onActivityStarted(int resultCode) {
498 unbindCameraPrewarmService(isSuccessfulLaunch(resultCode));
504 private static boolean isSuccessfulLaunch(int result) {
505 return result == ActivityManager.START_SUCCESS
506 || result == ActivityManager.START_DELIVERED_TO_TOP
507 || result == ActivityManager.START_TASK_TO_FRONT;
510 public void launchLeftAffordance() {
511 if (mLeftIsVoiceAssist) {
518 private void launchVoiceAssist() {
519 Runnable runnable = new Runnable() {
522 mAssistManager.launchVoiceAssistFromKeyguard();
523 mActivityStarter.preventNextAnimation();
526 if (mPhoneStatusBar.isKeyguardCurrentlySecure()) {
527 AsyncTask.execute(runnable);
529 mPhoneStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
530 false /* dismissShade */, false /* afterKeyguardGone */, true /* deferred */);
534 private boolean canLaunchVoiceAssist() {
535 return mAssistManager.canVoiceAssistBeLaunchedFromKeyguard();
538 private void launchPhone() {
539 final TelecomManager tm = TelecomManager.from(mContext);
541 AsyncTask.execute(new Runnable() {
544 tm.showInCallScreen(false /* showDialpad */);
548 mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */);
554 protected void onVisibilityChanged(View changedView, int visibility) {
555 super.onVisibilityChanged(changedView, visibility);
556 if (changedView == this && visibility == VISIBLE) {
558 updateCameraVisibility();
562 public KeyguardAffordanceView getLeftView() {
563 return mLeftAffordanceView;
566 public KeyguardAffordanceView getRightView() {
567 return mCameraImageView;
570 public View getLeftPreview() {
574 public View getRightPreview() {
575 return mCameraPreview;
578 public LockIcon getLockIcon() {
582 public View getIndicationView() {
583 return mIndicationText;
587 public boolean hasOverlappingRendering() {
592 public void onUnlockMethodStateChanged() {
594 updateCameraVisibility();
597 private void inflateCameraPreview() {
598 View previewBefore = mCameraPreview;
599 boolean visibleBefore = false;
600 if (previewBefore != null) {
601 mPreviewContainer.removeView(previewBefore);
602 visibleBefore = previewBefore.getVisibility() == View.VISIBLE;
604 mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
605 if (mCameraPreview != null) {
606 mPreviewContainer.addView(mCameraPreview);
607 mCameraPreview.setVisibility(visibleBefore ? View.VISIBLE : View.INVISIBLE);
609 if (mAffordanceHelper != null) {
610 mAffordanceHelper.updatePreviews();
614 private void updateLeftPreview() {
615 View previewBefore = mLeftPreview;
616 if (previewBefore != null) {
617 mPreviewContainer.removeView(previewBefore);
619 if (mLeftIsVoiceAssist) {
620 mLeftPreview = mPreviewInflater.inflatePreviewFromService(
621 mAssistManager.getVoiceInteractorComponentName());
623 mLeftPreview = mPreviewInflater.inflatePreview(PHONE_INTENT);
625 if (mLeftPreview != null) {
626 mPreviewContainer.addView(mLeftPreview);
627 mLeftPreview.setVisibility(View.INVISIBLE);
629 if (mAffordanceHelper != null) {
630 mAffordanceHelper.updatePreviews();
634 public void startFinishDozeAnimation() {
636 if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
637 startFinishDozeAnimationElement(mLeftAffordanceView, delay);
638 delay += DOZE_ANIMATION_STAGGER_DELAY;
640 startFinishDozeAnimationElement(mLockIcon, delay);
641 delay += DOZE_ANIMATION_STAGGER_DELAY;
642 if (mCameraImageView.getVisibility() == View.VISIBLE) {
643 startFinishDozeAnimationElement(mCameraImageView, delay);
645 mIndicationText.setAlpha(0f);
646 mIndicationText.animate()
648 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
649 .setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
652 private void startFinishDozeAnimationElement(View element, long delay) {
653 element.setAlpha(0f);
654 element.setTranslationY(element.getHeight() / 2);
658 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
659 .setStartDelay(delay)
660 .setDuration(DOZE_ANIMATION_ELEMENT_DURATION);
663 private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
665 public void onReceive(Context context, Intent intent) {
666 post(new Runnable() {
669 updateCameraVisibility();
675 private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
676 new KeyguardUpdateMonitorCallback() {
678 public void onUserSwitchComplete(int userId) {
679 updateCameraVisibility();
683 public void onStartedWakingUp() {
684 mLockIcon.setDeviceInteractive(true);
688 public void onFinishedGoingToSleep(int why) {
689 mLockIcon.setDeviceInteractive(false);
693 public void onScreenTurnedOn() {
694 mLockIcon.setScreenOn(true);
698 public void onScreenTurnedOff() {
699 mLockIcon.setScreenOn(false);
703 public void onKeyguardVisibilityChanged(boolean showing) {
708 public void onFingerprintRunningStateChanged(boolean running) {
713 public void onStrongAuthStateChanged(int userId) {
718 public void onUserUnlocked() {
719 inflateCameraPreview();
720 updateCameraVisibility();
721 updateLeftAffordance();
725 public void setKeyguardIndicationController(
726 KeyguardIndicationController keyguardIndicationController) {
727 mIndicationController = keyguardIndicationController;
730 public void setAssistManager(AssistManager assistManager) {
731 mAssistManager = assistManager;
732 updateLeftAffordance();
735 public void updateLeftAffordance() {
736 updateLeftAffordanceIcon();
740 public void onKeyguardShowingChanged() {
741 updateLeftAffordance();
742 inflateCameraPreview();