KeyguardBottomAreaView.java revision 40aa8811bc817293d7400c14fa60350d2350d29f
1/* 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 19import android.app.ActivityManager; 20import android.app.ActivityManagerNative; 21import android.app.admin.DevicePolicyManager; 22import android.content.BroadcastReceiver; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.Intent; 26import android.content.IntentFilter; 27import android.content.ServiceConnection; 28import android.content.pm.ActivityInfo; 29import android.content.pm.PackageManager; 30import android.content.pm.ResolveInfo; 31import android.content.res.Configuration; 32import android.os.AsyncTask; 33import android.os.Bundle; 34import android.os.IBinder; 35import android.os.Message; 36import android.os.Messenger; 37import android.os.RemoteException; 38import android.os.UserHandle; 39import android.provider.MediaStore; 40import android.service.media.CameraPrewarmService; 41import android.telecom.TelecomManager; 42import android.util.AttributeSet; 43import android.util.Log; 44import android.util.TypedValue; 45import android.view.View; 46import android.view.ViewGroup; 47import android.view.accessibility.AccessibilityNodeInfo; 48import android.view.animation.AnimationUtils; 49import android.view.animation.Interpolator; 50import android.widget.FrameLayout; 51import android.widget.TextView; 52 53import com.android.internal.widget.LockPatternUtils; 54import com.android.keyguard.KeyguardUpdateMonitor; 55import com.android.keyguard.KeyguardUpdateMonitorCallback; 56import com.android.systemui.EventLogConstants; 57import com.android.systemui.EventLogTags; 58import com.android.systemui.R; 59import com.android.systemui.assist.AssistManager; 60import com.android.systemui.statusbar.CommandQueue; 61import com.android.systemui.statusbar.KeyguardAffordanceView; 62import com.android.systemui.statusbar.KeyguardIndicationController; 63import com.android.systemui.statusbar.policy.AccessibilityController; 64import com.android.systemui.statusbar.policy.FlashlightController; 65import com.android.systemui.statusbar.policy.PreviewInflater; 66 67import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; 68import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; 69 70/** 71 * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status 72 * text. 73 */ 74public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener, 75 UnlockMethodCache.OnUnlockMethodChangedListener, 76 AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener { 77 78 final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView"; 79 80 public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance"; 81 public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture"; 82 public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap"; 83 84 public static final String EXTRA_CAMERA_LAUNCH_SOURCE 85 = "com.android.systemui.camera_launch_source"; 86 87 private static final Intent SECURE_CAMERA_INTENT = 88 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE) 89 .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 90 public static final Intent INSECURE_CAMERA_INTENT = 91 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); 92 private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL); 93 private static final int DOZE_ANIMATION_STAGGER_DELAY = 48; 94 private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250; 95 96 private KeyguardAffordanceView mCameraImageView; 97 private KeyguardAffordanceView mLeftAffordanceView; 98 private LockIcon mLockIcon; 99 private TextView mIndicationText; 100 private ViewGroup mPreviewContainer; 101 102 private View mLeftPreview; 103 private View mCameraPreview; 104 105 private ActivityStarter mActivityStarter; 106 private UnlockMethodCache mUnlockMethodCache; 107 private LockPatternUtils mLockPatternUtils; 108 private FlashlightController mFlashlightController; 109 private PreviewInflater mPreviewInflater; 110 private KeyguardIndicationController mIndicationController; 111 private AccessibilityController mAccessibilityController; 112 private PhoneStatusBar mPhoneStatusBar; 113 114 private final Interpolator mLinearOutSlowInInterpolator; 115 private boolean mUserSetupComplete; 116 private boolean mPrewarmBound; 117 private Messenger mPrewarmMessenger; 118 private final ServiceConnection mPrewarmConnection = new ServiceConnection() { 119 120 @Override 121 public void onServiceConnected(ComponentName name, IBinder service) { 122 mPrewarmMessenger = new Messenger(service); 123 } 124 125 @Override 126 public void onServiceDisconnected(ComponentName name) { 127 mPrewarmMessenger = null; 128 } 129 }; 130 131 private boolean mLeftIsVoiceAssist; 132 private AssistManager mAssistManager; 133 134 public KeyguardBottomAreaView(Context context) { 135 this(context, null); 136 } 137 138 public KeyguardBottomAreaView(Context context, AttributeSet attrs) { 139 this(context, attrs, 0); 140 } 141 142 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) { 143 this(context, attrs, defStyleAttr, 0); 144 } 145 146 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr, 147 int defStyleRes) { 148 super(context, attrs, defStyleAttr, defStyleRes); 149 mLinearOutSlowInInterpolator = 150 AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); 151 } 152 153 private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() { 154 @Override 155 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { 156 super.onInitializeAccessibilityNodeInfo(host, info); 157 String label = null; 158 if (host == mLockIcon) { 159 label = getResources().getString(R.string.unlock_label); 160 } else if (host == mCameraImageView) { 161 label = getResources().getString(R.string.camera_label); 162 } else if (host == mLeftAffordanceView) { 163 if (mLeftIsVoiceAssist) { 164 label = getResources().getString(R.string.voice_assist_label); 165 } else { 166 label = getResources().getString(R.string.phone_label); 167 } 168 } 169 info.addAction(new AccessibilityAction(ACTION_CLICK, label)); 170 } 171 172 @Override 173 public boolean performAccessibilityAction(View host, int action, Bundle args) { 174 if (action == ACTION_CLICK) { 175 if (host == mLockIcon) { 176 mPhoneStatusBar.animateCollapsePanels( 177 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */); 178 return true; 179 } else if (host == mCameraImageView) { 180 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE); 181 return true; 182 } else if (host == mLeftAffordanceView) { 183 launchLeftAffordance(); 184 return true; 185 } 186 } 187 return super.performAccessibilityAction(host, action, args); 188 } 189 }; 190 191 @Override 192 protected void onFinishInflate() { 193 super.onFinishInflate(); 194 mLockPatternUtils = new LockPatternUtils(mContext); 195 mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container); 196 mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button); 197 mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button); 198 mLockIcon = (LockIcon) findViewById(R.id.lock_icon); 199 mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text); 200 watchForCameraPolicyChanges(); 201 updateCameraVisibility(); 202 mUnlockMethodCache = UnlockMethodCache.getInstance(getContext()); 203 mUnlockMethodCache.addListener(this); 204 mLockIcon.update(); 205 setClipChildren(false); 206 setClipToPadding(false); 207 mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext)); 208 inflateCameraPreview(); 209 mLockIcon.setOnClickListener(this); 210 mLockIcon.setOnLongClickListener(this); 211 mCameraImageView.setOnClickListener(this); 212 mLeftAffordanceView.setOnClickListener(this); 213 initAccessibility(); 214 } 215 216 private void initAccessibility() { 217 mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate); 218 mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate); 219 mCameraImageView.setAccessibilityDelegate(mAccessibilityDelegate); 220 } 221 222 @Override 223 protected void onConfigurationChanged(Configuration newConfig) { 224 super.onConfigurationChanged(newConfig); 225 int indicationBottomMargin = getResources().getDimensionPixelSize( 226 R.dimen.keyguard_indication_margin_bottom); 227 MarginLayoutParams mlp = (MarginLayoutParams) mIndicationText.getLayoutParams(); 228 if (mlp.bottomMargin != indicationBottomMargin) { 229 mlp.bottomMargin = indicationBottomMargin; 230 mIndicationText.setLayoutParams(mlp); 231 } 232 233 // Respect font size setting. 234 mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX, 235 getResources().getDimensionPixelSize( 236 com.android.internal.R.dimen.text_size_small_material)); 237 } 238 239 public void setActivityStarter(ActivityStarter activityStarter) { 240 mActivityStarter = activityStarter; 241 } 242 243 public void setFlashlightController(FlashlightController flashlightController) { 244 mFlashlightController = flashlightController; 245 } 246 247 public void setAccessibilityController(AccessibilityController accessibilityController) { 248 mAccessibilityController = accessibilityController; 249 mLockIcon.setAccessibilityController(accessibilityController); 250 accessibilityController.addStateChangedCallback(this); 251 } 252 253 public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) { 254 mPhoneStatusBar = phoneStatusBar; 255 updateCameraVisibility(); // in case onFinishInflate() was called too early 256 } 257 258 public void setUserSetupComplete(boolean userSetupComplete) { 259 mUserSetupComplete = userSetupComplete; 260 updateCameraVisibility(); 261 updateLeftAffordanceIcon(); 262 } 263 264 private Intent getCameraIntent() { 265 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); 266 boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer( 267 KeyguardUpdateMonitor.getCurrentUser()); 268 boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()); 269 return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT; 270 } 271 272 /** 273 * Resolves the intent to launch the camera application. 274 */ 275 public ResolveInfo resolveCameraIntent() { 276 return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(), 277 PackageManager.MATCH_DEFAULT_ONLY, 278 KeyguardUpdateMonitor.getCurrentUser()); 279 } 280 281 private void updateCameraVisibility() { 282 if (mCameraImageView == null) { 283 // Things are not set up yet; reply hazy, ask again later 284 return; 285 } 286 ResolveInfo resolved = resolveCameraIntent(); 287 boolean visible = !isCameraDisabledByDpm() && resolved != null 288 && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance) 289 && mUserSetupComplete; 290 mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE); 291 } 292 293 private void updateLeftAffordanceIcon() { 294 mLeftIsVoiceAssist = canLaunchVoiceAssist(); 295 int drawableId; 296 int contentDescription; 297 boolean visible = mUserSetupComplete; 298 if (mLeftIsVoiceAssist) { 299 drawableId = R.drawable.ic_mic_26dp; 300 contentDescription = R.string.accessibility_voice_assist_button; 301 } else { 302 visible &= isPhoneVisible(); 303 drawableId = R.drawable.ic_phone_24dp; 304 contentDescription = R.string.accessibility_phone_button; 305 } 306 mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE); 307 mLeftAffordanceView.setImageDrawable(mContext.getDrawable(drawableId)); 308 mLeftAffordanceView.setContentDescription(mContext.getString(contentDescription)); 309 } 310 311 public boolean isLeftVoiceAssist() { 312 return mLeftIsVoiceAssist; 313 } 314 315 private boolean isPhoneVisible() { 316 PackageManager pm = mContext.getPackageManager(); 317 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) 318 && pm.resolveActivity(PHONE_INTENT, 0) != null; 319 } 320 321 private boolean isCameraDisabledByDpm() { 322 final DevicePolicyManager dpm = 323 (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE); 324 if (dpm != null && mPhoneStatusBar != null) { 325 try { 326 final int userId = ActivityManagerNative.getDefault().getCurrentUser().id; 327 final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId); 328 final boolean disabledBecauseKeyguardSecure = 329 (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0 330 && mPhoneStatusBar.isKeyguardSecure(); 331 return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure; 332 } catch (RemoteException e) { 333 Log.e(TAG, "Can't get userId", e); 334 } 335 } 336 return false; 337 } 338 339 private void watchForCameraPolicyChanges() { 340 final IntentFilter filter = new IntentFilter(); 341 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 342 getContext().registerReceiverAsUser(mDevicePolicyReceiver, 343 UserHandle.ALL, filter, null, null); 344 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback); 345 } 346 347 @Override 348 public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) { 349 mCameraImageView.setClickable(touchExplorationEnabled); 350 mLeftAffordanceView.setClickable(touchExplorationEnabled); 351 mCameraImageView.setFocusable(accessibilityEnabled); 352 mLeftAffordanceView.setFocusable(accessibilityEnabled); 353 mLockIcon.update(); 354 } 355 356 @Override 357 public void onClick(View v) { 358 if (v == mCameraImageView) { 359 launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE); 360 } else if (v == mLeftAffordanceView) { 361 launchLeftAffordance(); 362 } if (v == mLockIcon) { 363 if (!mAccessibilityController.isAccessibilityEnabled()) { 364 handleTrustCircleClick(); 365 } else { 366 mPhoneStatusBar.animateCollapsePanels( 367 CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); 368 } 369 } 370 } 371 372 @Override 373 public boolean onLongClick(View v) { 374 handleTrustCircleClick(); 375 return true; 376 } 377 378 private void handleTrustCircleClick() { 379 EventLogTags.writeSysuiLockscreenGesture( 380 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK, 0 /* lengthDp - N/A */, 381 0 /* velocityDp - N/A */); 382 mIndicationController.showTransientIndication( 383 R.string.keyguard_indication_trust_disabled); 384 mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser()); 385 } 386 387 public void bindCameraPrewarmService() { 388 Intent intent = getCameraIntent(); 389 ActivityInfo targetInfo = PreviewInflater.getTargetActivityInfo(mContext, intent, 390 KeyguardUpdateMonitor.getCurrentUser()); 391 if (targetInfo != null && targetInfo.metaData != null) { 392 String clazz = targetInfo.metaData.getString( 393 MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE); 394 if (clazz != null) { 395 Intent serviceIntent = new Intent(); 396 serviceIntent.setClassName(targetInfo.packageName, clazz); 397 serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM); 398 try { 399 if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection, 400 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, 401 new UserHandle(UserHandle.USER_CURRENT))) { 402 mPrewarmBound = true; 403 } 404 } catch (SecurityException e) { 405 Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName 406 + " class=" + clazz, e); 407 } 408 } 409 } 410 } 411 412 public void unbindCameraPrewarmService(boolean launched) { 413 if (mPrewarmBound) { 414 if (mPrewarmMessenger != null && launched) { 415 try { 416 mPrewarmMessenger.send(Message.obtain(null /* handler */, 417 CameraPrewarmService.MSG_CAMERA_FIRED)); 418 } catch (RemoteException e) { 419 Log.w(TAG, "Error sending camera fired message", e); 420 } 421 } 422 mContext.unbindService(mPrewarmConnection); 423 mPrewarmBound = false; 424 } 425 } 426 427 public void launchCamera(String source) { 428 final Intent intent = getCameraIntent(); 429 intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source); 430 boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity( 431 mContext, intent, KeyguardUpdateMonitor.getCurrentUser()); 432 if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) { 433 AsyncTask.execute(new Runnable() { 434 @Override 435 public void run() { 436 int result = ActivityManager.START_CANCELED; 437 try { 438 result = ActivityManagerNative.getDefault().startActivityAsUser( 439 null, getContext().getBasePackageName(), 440 intent, 441 intent.resolveTypeIfNeeded(getContext().getContentResolver()), 442 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, 443 UserHandle.CURRENT.getIdentifier()); 444 } catch (RemoteException e) { 445 Log.w(TAG, "Unable to start camera activity", e); 446 } 447 mActivityStarter.preventNextAnimation(); 448 final boolean launched = isSuccessfulLaunch(result); 449 post(new Runnable() { 450 @Override 451 public void run() { 452 unbindCameraPrewarmService(launched); 453 } 454 }); 455 } 456 }); 457 } else { 458 459 // We need to delay starting the activity because ResolverActivity finishes itself if 460 // launched behind lockscreen. 461 mActivityStarter.startActivity(intent, false /* dismissShade */, 462 new ActivityStarter.Callback() { 463 @Override 464 public void onActivityStarted(int resultCode) { 465 unbindCameraPrewarmService(isSuccessfulLaunch(resultCode)); 466 } 467 }); 468 } 469 } 470 471 private static boolean isSuccessfulLaunch(int result) { 472 return result == ActivityManager.START_SUCCESS 473 || result == ActivityManager.START_DELIVERED_TO_TOP 474 || result == ActivityManager.START_TASK_TO_FRONT; 475 } 476 477 public void launchLeftAffordance() { 478 if (mLeftIsVoiceAssist) { 479 launchVoiceAssist(); 480 } else { 481 launchPhone(); 482 } 483 } 484 485 private void launchVoiceAssist() { 486 Runnable runnable = new Runnable() { 487 @Override 488 public void run() { 489 mAssistManager.launchVoiceAssistFromKeyguard(); 490 mActivityStarter.preventNextAnimation(); 491 } 492 }; 493 if (mPhoneStatusBar.isKeyguardCurrentlySecure()) { 494 AsyncTask.execute(runnable); 495 } else { 496 mPhoneStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */, 497 false /* dismissShade */, false /* afterKeyguardGone */); 498 } 499 } 500 501 private boolean canLaunchVoiceAssist() { 502 return mAssistManager.canVoiceAssistBeLaunchedFromKeyguard(); 503 } 504 505 private void launchPhone() { 506 final TelecomManager tm = TelecomManager.from(mContext); 507 if (tm.isInCall()) { 508 AsyncTask.execute(new Runnable() { 509 @Override 510 public void run() { 511 tm.showInCallScreen(false /* showDialpad */); 512 } 513 }); 514 } else { 515 mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */); 516 } 517 } 518 519 520 @Override 521 protected void onVisibilityChanged(View changedView, int visibility) { 522 super.onVisibilityChanged(changedView, visibility); 523 if (changedView == this && visibility == VISIBLE) { 524 mLockIcon.update(); 525 updateCameraVisibility(); 526 } 527 } 528 529 public KeyguardAffordanceView getLeftView() { 530 return mLeftAffordanceView; 531 } 532 533 public KeyguardAffordanceView getRightView() { 534 return mCameraImageView; 535 } 536 537 public View getLeftPreview() { 538 return mLeftPreview; 539 } 540 541 public View getRightPreview() { 542 return mCameraPreview; 543 } 544 545 public LockIcon getLockIcon() { 546 return mLockIcon; 547 } 548 549 public View getIndicationView() { 550 return mIndicationText; 551 } 552 553 @Override 554 public boolean hasOverlappingRendering() { 555 return false; 556 } 557 558 @Override 559 public void onUnlockMethodStateChanged() { 560 mLockIcon.update(); 561 updateCameraVisibility(); 562 } 563 564 private void inflateCameraPreview() { 565 mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent()); 566 if (mCameraPreview != null) { 567 mPreviewContainer.addView(mCameraPreview); 568 mCameraPreview.setVisibility(View.INVISIBLE); 569 } 570 } 571 572 private void updateLeftPreview() { 573 View previewBefore = mLeftPreview; 574 if (previewBefore != null) { 575 mPreviewContainer.removeView(previewBefore); 576 } 577 if (mLeftIsVoiceAssist) { 578 mLeftPreview = mPreviewInflater.inflatePreviewFromService( 579 mAssistManager.getVoiceInteractorComponentName()); 580 } else { 581 mLeftPreview = mPreviewInflater.inflatePreview(PHONE_INTENT); 582 } 583 if (mLeftPreview != null) { 584 mPreviewContainer.addView(mLeftPreview); 585 mLeftPreview.setVisibility(View.INVISIBLE); 586 } 587 } 588 589 public void startFinishDozeAnimation() { 590 long delay = 0; 591 if (mLeftAffordanceView.getVisibility() == View.VISIBLE) { 592 startFinishDozeAnimationElement(mLeftAffordanceView, delay); 593 delay += DOZE_ANIMATION_STAGGER_DELAY; 594 } 595 startFinishDozeAnimationElement(mLockIcon, delay); 596 delay += DOZE_ANIMATION_STAGGER_DELAY; 597 if (mCameraImageView.getVisibility() == View.VISIBLE) { 598 startFinishDozeAnimationElement(mCameraImageView, delay); 599 } 600 mIndicationText.setAlpha(0f); 601 mIndicationText.animate() 602 .alpha(1f) 603 .setInterpolator(mLinearOutSlowInInterpolator) 604 .setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION); 605 } 606 607 private void startFinishDozeAnimationElement(View element, long delay) { 608 element.setAlpha(0f); 609 element.setTranslationY(element.getHeight() / 2); 610 element.animate() 611 .alpha(1f) 612 .translationY(0f) 613 .setInterpolator(mLinearOutSlowInInterpolator) 614 .setStartDelay(delay) 615 .setDuration(DOZE_ANIMATION_ELEMENT_DURATION); 616 } 617 618 private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() { 619 @Override 620 public void onReceive(Context context, Intent intent) { 621 post(new Runnable() { 622 @Override 623 public void run() { 624 updateCameraVisibility(); 625 } 626 }); 627 } 628 }; 629 630 private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback = 631 new KeyguardUpdateMonitorCallback() { 632 @Override 633 public void onUserSwitchComplete(int userId) { 634 updateCameraVisibility(); 635 } 636 637 @Override 638 public void onStartedWakingUp() { 639 mLockIcon.setDeviceInteractive(true); 640 } 641 642 @Override 643 public void onFinishedGoingToSleep(int why) { 644 mLockIcon.setDeviceInteractive(false); 645 } 646 647 @Override 648 public void onScreenTurnedOn() { 649 mLockIcon.setScreenOn(true); 650 } 651 652 @Override 653 public void onScreenTurnedOff() { 654 mLockIcon.setScreenOn(false); 655 } 656 657 @Override 658 public void onKeyguardVisibilityChanged(boolean showing) { 659 mLockIcon.update(); 660 } 661 662 @Override 663 public void onFingerprintRunningStateChanged(boolean running) { 664 mLockIcon.update(); 665 } 666 667 @Override 668 public void onStrongAuthStateChanged(int userId) { 669 mLockIcon.update(); 670 } 671 }; 672 673 public void setKeyguardIndicationController( 674 KeyguardIndicationController keyguardIndicationController) { 675 mIndicationController = keyguardIndicationController; 676 } 677 678 public void setAssistManager(AssistManager assistManager) { 679 mAssistManager = assistManager; 680 updateLeftAffordance(); 681 } 682 683 public void updateLeftAffordance() { 684 updateLeftAffordanceIcon(); 685 updateLeftPreview(); 686 } 687} 688