package com.android.systemui.statusbar.phone;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.hardware.fingerprint.FingerprintManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.InsetDrawable;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
+import android.service.media.CameraPrewarmService;
import android.telecom.TelecomManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
-
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.EventLogConstants;
+import com.android.systemui.EventLogTags;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.cm.LockscreenShortcutsHelper;
+import com.android.systemui.cm.LockscreenShortcutsHelper.Shortcuts;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.PreviewInflater;
+import java.util.Objects;
+
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
* text.
*/
public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
- UnlockMethodCache.OnUnlockMethodChangedListener,
+ UnlockMethodCache.OnUnlockMethodChangedListener, LockscreenShortcutsHelper.OnChangeListener,
AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener {
final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
+ public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
+ public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
+ public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
+ public static final String CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE = "screen_gesture";
+
+ public static final String EXTRA_CAMERA_LAUNCH_SOURCE
+ = "com.android.systemui.camera_launch_source";
+
private static final Intent SECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- private static final Intent INSECURE_CAMERA_INTENT =
+ public static final Intent INSECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
+ private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
+ private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
private KeyguardAffordanceView mCameraImageView;
- private KeyguardAffordanceView mPhoneImageView;
- private KeyguardAffordanceView mLockIcon;
+ private KeyguardAffordanceView mLeftAffordanceView;
+ private LockIcon mLockIcon;
private TextView mIndicationText;
private ViewGroup mPreviewContainer;
- private View mPhonePreview;
+ private View mLeftPreview;
private View mCameraPreview;
private ActivityStarter mActivityStarter;
private KeyguardIndicationController mIndicationController;
private AccessibilityController mAccessibilityController;
private PhoneStatusBar mPhoneStatusBar;
+ private LockscreenShortcutsHelper mShortcutHelper;
+ private final ColorMatrixColorFilter mGrayScaleFilter;
+
+ private boolean mUserSetupComplete;
+ private boolean mPrewarmBound;
+ private Messenger mPrewarmMessenger;
+ private Intent mLastCameraIntent;
- private final TrustDrawable mTrustDrawable;
+ private final ServiceConnection mPrewarmConnection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mPrewarmMessenger = new Messenger(service);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mPrewarmMessenger = null;
+ }
+ };
- private int mLastUnlockIconRes = 0;
+ private AssistManager mAssistManager;
public KeyguardBottomAreaView(Context context) {
this(context, null);
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mTrustDrawable = new TrustDrawable(mContext);
+ ColorMatrix cm = new ColorMatrix();
+ cm.setSaturation(0);
+ mGrayScaleFilter = new ColorMatrixColorFilter(cm);
}
private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
if (host == mLockIcon) {
label = getResources().getString(R.string.unlock_label);
} else if (host == mCameraImageView) {
- label = getResources().getString(R.string.camera_label);
- } else if (host == mPhoneImageView) {
- label = getResources().getString(R.string.phone_label);
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ label = mShortcutHelper.getFriendlyNameForUri(Shortcuts.RIGHT_SHORTCUT);
+ } else {
+ label = getResources().getString(R.string.camera_label);
+ }
+ } else if (host == mLeftAffordanceView) {
+ if (isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ label = mShortcutHelper.getFriendlyNameForUri(Shortcuts.LEFT_SHORTCUT);
+ } else {
+ if (isLeftVoiceAssist()) {
+ label = getResources().getString(R.string.voice_assist_label);
+ } else {
+ label = getResources().getString(R.string.phone_label);
+ }
+ }
}
info.addAction(new AccessibilityAction(ACTION_CLICK, label));
}
if (action == ACTION_CLICK) {
if (host == mLockIcon) {
mPhoneStatusBar.animateCollapsePanels(
- CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
+ CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
return true;
} else if (host == mCameraImageView) {
- launchCamera();
+ launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
return true;
- } else if (host == mPhoneImageView) {
- launchPhone();
+ } else if (host == mLeftAffordanceView) {
+ launchLeftAffordance();
return true;
}
}
mLockPatternUtils = new LockPatternUtils(mContext);
mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
- mPhoneImageView = (KeyguardAffordanceView) findViewById(R.id.phone_button);
- mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon);
+ mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
+ mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
+ mShortcutHelper = new LockscreenShortcutsHelper(mContext, this);
watchForCameraPolicyChanges();
updateCameraVisibility();
- updatePhoneVisibility();
+ updateLeftButtonVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
- updateLockIcon();
+ mLockIcon.update();
setClipChildren(false);
setClipToPadding(false);
mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
- inflatePreviews();
mLockIcon.setOnClickListener(this);
- mLockIcon.setBackground(mTrustDrawable);
mLockIcon.setOnLongClickListener(this);
mCameraImageView.setOnClickListener(this);
- mPhoneImageView.setOnClickListener(this);
+ mLeftAffordanceView.setOnClickListener(this);
initAccessibility();
+ updateCustomShortcuts();
+ }
+
+ private void updateCustomShortcuts() {
+ updateLeftAffordanceIcon();
+ updateRightAffordanceIcon();
+ inflateCameraPreview();
+ }
+
+ private void updateRightAffordanceIcon() {
+ Drawable drawable;
+ String contentDescription;
+ boolean shouldGrayScale = false;
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ drawable = mShortcutHelper.getDrawableForTarget(Shortcuts.RIGHT_SHORTCUT);
+ shouldGrayScale = true;
+ contentDescription = mShortcutHelper.getFriendlyNameForUri(Shortcuts.RIGHT_SHORTCUT);
+ } else {
+ drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
+ contentDescription = mContext.getString(R.string.accessibility_camera_button);
+ }
+ mCameraImageView.setImageDrawable(drawable);
+ mCameraImageView.setContentDescription(contentDescription);
+ mCameraImageView.setDefaultFilter(shouldGrayScale ? mGrayScaleFilter : null);
+ updateCameraVisibility();
+ updateLeftButtonVisibility();
}
private void initAccessibility() {
mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
- mPhoneImageView.setAccessibilityDelegate(mAccessibilityDelegate);
+ mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
mCameraImageView.setAccessibilityDelegate(mAccessibilityDelegate);
}
mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(
com.android.internal.R.dimen.text_size_small_material));
+
+ ViewGroup.LayoutParams lp = mCameraImageView.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
+ mCameraImageView.setLayoutParams(lp);
+ mCameraImageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_camera_alt_24dp));
+
+ lp = mLockIcon.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
+ mLockIcon.setLayoutParams(lp);
+ mLockIcon.update(true /* force */);
+
+ lp = mLeftAffordanceView.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
+ mLeftAffordanceView.setLayoutParams(lp);
+ updateLeftAffordanceIcon();
}
public void setActivityStarter(ActivityStarter activityStarter) {
public void setAccessibilityController(AccessibilityController accessibilityController) {
mAccessibilityController = accessibilityController;
+ mLockIcon.setAccessibilityController(accessibilityController);
accessibilityController.addStateChangedCallback(this);
}
public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
mPhoneStatusBar = phoneStatusBar;
+ updateCameraVisibility(); // in case onFinishInflate() was called too early
+ updateLeftButtonVisibility();
+ }
+
+ public void setUserSetupComplete(boolean userSetupComplete) {
+ mUserSetupComplete = userSetupComplete;
+ updateCameraVisibility();
+ updateLeftButtonVisibility();
+ updateLeftAffordanceIcon();
}
private Intent getCameraIntent() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
- boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
- mLockPatternUtils.getCurrentUser());
- return mLockPatternUtils.isSecure() && !currentUserHasTrust
- ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
+ boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
+ KeyguardUpdateMonitor.getCurrentUser());
+ boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
+ return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
}
- private void updateCameraVisibility() {
- ResolveInfo resolved = mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
+ /**
+ * Resolves the intent to launch the camera application.
+ */
+ public ResolveInfo resolveCameraIntent() {
+ return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
PackageManager.MATCH_DEFAULT_ONLY,
- mLockPatternUtils.getCurrentUser());
- boolean visible = !isCameraDisabledByDpm() && resolved != null
- && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance);
+ KeyguardUpdateMonitor.getCurrentUser());
+ }
+
+ private void updateLeftButtonVisibility() {
+ if (mLeftAffordanceView == null) {
+ return;
+ }
+ boolean visible = mUserSetupComplete;
+ if (visible) {
+ if (isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ visible = !mShortcutHelper.isTargetEmpty(Shortcuts.LEFT_SHORTCUT);
+ } else {
+ // Display left shortcut
+ }
+ }
+ mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+
+ private void updateCameraVisibility() {
+ if (mCameraImageView == null) {
+ // Things are not set up yet; reply hazy, ask again later
+ return;
+ }
+ boolean visible = mUserSetupComplete;
+ if (visible) {
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ visible = !mShortcutHelper.isTargetEmpty(Shortcuts.RIGHT_SHORTCUT);
+ } else {
+ ResolveInfo resolved = resolveCameraIntent();
+ visible = !isCameraDisabledByDpm() && resolved != null
+ && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance);
+ }
+ }
mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
- private void updatePhoneVisibility() {
- boolean visible = isPhoneVisible();
- mPhoneImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
+ private void updateLeftAffordanceIcon() {
+ Drawable drawable;
+ String contentDescription;
+ boolean shouldGrayScale = false;
+ boolean visible = mUserSetupComplete;
+ if (mShortcutHelper.isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ drawable = mShortcutHelper.getDrawableForTarget(Shortcuts.LEFT_SHORTCUT);
+ shouldGrayScale = true;
+ contentDescription = mShortcutHelper.getFriendlyNameForUri(Shortcuts.LEFT_SHORTCUT);
+ visible |= !mShortcutHelper.isTargetEmpty(Shortcuts.LEFT_SHORTCUT);
+ } else if (canLaunchVoiceAssist()) {
+ drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
+ contentDescription = mContext.getString(R.string.accessibility_voice_assist_button);
+ } else {
+ visible &= isPhoneVisible();
+ drawable = mContext.getDrawable(R.drawable.ic_phone_24dp);
+ contentDescription = mContext.getString(R.string.accessibility_phone_button);
+ }
+ mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mLeftAffordanceView.setImageDrawable(drawable);
+ mLeftAffordanceView.setContentDescription(contentDescription);
+ mLeftAffordanceView.setDefaultFilter(shouldGrayScale ? mGrayScaleFilter : null);
+ updateLeftButtonVisibility();
+ }
+
+ public boolean isLeftVoiceAssist() {
+ return !isTargetCustom(Shortcuts.LEFT_SHORTCUT) && canLaunchVoiceAssist();
}
private boolean isPhoneVisible() {
private boolean isCameraDisabledByDpm() {
final DevicePolicyManager dpm =
(DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
+ if (dpm != null && mPhoneStatusBar != null) {
try {
final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
final boolean disabledBecauseKeyguardSecure =
(disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
- && KeyguardTouchDelegate.getInstance(getContext()).isSecure();
+ && mPhoneStatusBar.isKeyguardSecure();
return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
} catch (RemoteException e) {
Log.e(TAG, "Can't get userId", e);
@Override
public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
mCameraImageView.setClickable(touchExplorationEnabled);
- mPhoneImageView.setClickable(touchExplorationEnabled);
+ mLeftAffordanceView.setClickable(touchExplorationEnabled);
mCameraImageView.setFocusable(accessibilityEnabled);
- mPhoneImageView.setFocusable(accessibilityEnabled);
- updateLockIconClickability();
- }
-
- private void updateLockIconClickability() {
- if (mAccessibilityController == null) {
- return;
- }
- boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
- boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
- && !mAccessibilityController.isAccessibilityEnabled();
- boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
- && !clickToForceLock;
- mLockIcon.setClickable(clickToForceLock || clickToUnlock);
- mLockIcon.setLongClickable(longClickToForceLock);
- mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
+ mLeftAffordanceView.setFocusable(accessibilityEnabled);
+ mLockIcon.update();
}
@Override
public void onClick(View v) {
if (v == mCameraImageView) {
- launchCamera();
- } else if (v == mPhoneImageView) {
- launchPhone();
+ launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
+ } else if (v == mLeftAffordanceView) {
+ launchLeftAffordance();
} if (v == mLockIcon) {
if (!mAccessibilityController.isAccessibilityEnabled()) {
handleTrustCircleClick();
}
private void handleTrustCircleClick() {
+ EventLogTags.writeSysuiLockscreenGesture(
+ EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK, 0 /* lengthDp - N/A */,
+ 0 /* velocityDp - N/A */);
mIndicationController.showTransientIndication(
R.string.keyguard_indication_trust_disabled);
- mLockPatternUtils.requireCredentialEntry(mLockPatternUtils.getCurrentUser());
+ mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
}
- public void launchCamera() {
- mFlashlightController.killFlashlight();
+ public void bindCameraPrewarmService() {
Intent intent = getCameraIntent();
+ ActivityInfo targetInfo = PreviewInflater.getTargetActivityInfo(mContext, intent,
+ KeyguardUpdateMonitor.getCurrentUser());
+ if (targetInfo != null && targetInfo.metaData != null) {
+ String clazz = targetInfo.metaData.getString(
+ MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE);
+ if (clazz != null) {
+ Intent serviceIntent = new Intent();
+ serviceIntent.setClassName(targetInfo.packageName, clazz);
+ serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
+ try {
+ if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ new UserHandle(UserHandle.USER_CURRENT))) {
+ mPrewarmBound = true;
+ }
+ } catch (SecurityException e) {
+ Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName
+ + " class=" + clazz, e);
+ }
+ }
+ }
+ }
+
+ public void unbindCameraPrewarmService(boolean launched) {
+ if (mPrewarmBound) {
+ if (mPrewarmMessenger != null && launched) {
+ try {
+ mPrewarmMessenger.send(Message.obtain(null /* handler */,
+ CameraPrewarmService.MSG_CAMERA_FIRED));
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error sending camera fired message", e);
+ }
+ }
+ mContext.unbindService(mPrewarmConnection);
+ mPrewarmBound = false;
+ }
+ }
+
+ public void launchCamera(String source) {
+ final Intent intent;
+ if (source.equals(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) ||
+ source.equals(CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE) ||
+ !mShortcutHelper.isTargetCustom(LockscreenShortcutsHelper.Shortcuts.RIGHT_SHORTCUT)) {
+ intent = getCameraIntent();
+ } else {
+ intent = mShortcutHelper.getIntent(LockscreenShortcutsHelper.Shortcuts.RIGHT_SHORTCUT);
+ intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
+ }
boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
- mContext, intent, mLockPatternUtils.getCurrentUser());
+ mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ AsyncTask.execute(new Runnable() {
+ @Override
+ public void run() {
+ int result = ActivityManager.START_CANCELED;
+ try {
+ result = ActivityManagerNative.getDefault().startActivityAsUser(
+ null, getContext().getBasePackageName(),
+ intent,
+ intent.resolveTypeIfNeeded(getContext().getContentResolver()),
+ null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
+ UserHandle.CURRENT.getIdentifier());
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to start camera activity", e);
+ }
+ mActivityStarter.preventNextAnimation();
+ final boolean launched = isSuccessfulLaunch(result);
+ post(new Runnable() {
+ @Override
+ public void run() {
+ unbindCameraPrewarmService(launched);
+ }
+ });
+ }
+ });
} else {
// We need to delay starting the activity because ResolverActivity finishes itself if
// launched behind lockscreen.
+ mActivityStarter.startActivity(intent, false /* dismissShade */,
+ new ActivityStarter.Callback() {
+ @Override
+ public void onActivityStarted(int resultCode) {
+ unbindCameraPrewarmService(isSuccessfulLaunch(resultCode));
+ }
+ });
+ }
+ }
+
+ private static boolean isSuccessfulLaunch(int result) {
+ return result == ActivityManager.START_SUCCESS
+ || result == ActivityManager.START_DELIVERED_TO_TOP
+ || result == ActivityManager.START_TASK_TO_FRONT;
+ }
+
+ public void launchLeftAffordance() {
+ if (mShortcutHelper.isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ Intent intent = mShortcutHelper.getIntent(Shortcuts.LEFT_SHORTCUT);
mActivityStarter.startActivity(intent, false /* dismissShade */);
+ } else if (isLeftVoiceAssist()) {
+ launchVoiceAssist();
+ } else {
+ launchPhone();
+ }
+ }
+
+ private void launchVoiceAssist() {
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ mAssistManager.launchVoiceAssistFromKeyguard();
+ mActivityStarter.preventNextAnimation();
+ }
+ };
+ if (mPhoneStatusBar.isKeyguardCurrentlySecure()) {
+ AsyncTask.execute(runnable);
+ } else {
+ mPhoneStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
+ false /* dismissShade */, false /* afterKeyguardGone */, true /* deferred */);
}
}
- public void launchPhone() {
+ private boolean canLaunchVoiceAssist() {
+ if (mAssistManager == null) {
+ return false;
+ }
+ return mAssistManager.canVoiceAssistBeLaunchedFromKeyguard();
+ }
+
+ private void launchPhone() {
final TelecomManager tm = TelecomManager.from(mContext);
if (tm.isInCall()) {
AsyncTask.execute(new Runnable() {
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
- if (isShown()) {
- mTrustDrawable.start();
- } else {
- mTrustDrawable.stop();
- }
if (changedView == this && visibility == VISIBLE) {
- updateLockIcon();
+ mLockIcon.update();
updateCameraVisibility();
+ updateLeftButtonVisibility();
}
}
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mTrustDrawable.stop();
+ public KeyguardAffordanceView getLeftView() {
+ return mLeftAffordanceView;
}
- private void updateLockIcon() {
- boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
- if (visible) {
- mTrustDrawable.start();
- } else {
- mTrustDrawable.stop();
- }
- if (!visible) {
- return;
- }
- // TODO: Real icon for facelock.
- int iconRes = mUnlockMethodCache.isFaceUnlockRunning()
- ? com.android.internal.R.drawable.ic_account_circle
- : mUnlockMethodCache.isMethodInsecure() ? R.drawable.ic_lock_open_24dp
- : R.drawable.ic_lock_24dp;
- if (mLastUnlockIconRes != iconRes) {
- Drawable icon = mContext.getDrawable(iconRes);
- int iconHeight = getResources().getDimensionPixelSize(
- R.dimen.keyguard_affordance_icon_height);
- int iconWidth = getResources().getDimensionPixelSize(
- R.dimen.keyguard_affordance_icon_width);
- if (icon.getIntrinsicHeight() != iconHeight || icon.getIntrinsicWidth() != iconWidth) {
- icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
- }
- mLockIcon.setImageDrawable(icon);
- }
- boolean trustManaged = mUnlockMethodCache.isTrustManaged();
- mTrustDrawable.setTrustManaged(trustManaged);
- updateLockIconClickability();
- }
-
-
-
- public KeyguardAffordanceView getPhoneView() {
- return mPhoneImageView;
- }
-
- public KeyguardAffordanceView getCameraView() {
+ public KeyguardAffordanceView getRightView() {
return mCameraImageView;
}
- public View getPhonePreview() {
- return mPhonePreview;
+ public View getLeftPreview() {
+ return mLeftPreview;
}
- public View getCameraPreview() {
+ public View getRightPreview() {
return mCameraPreview;
}
- public KeyguardAffordanceView getLockIcon() {
+ public LockIcon getLockIcon() {
return mLockIcon;
}
}
@Override
- public void onMethodSecureChanged(boolean methodSecure) {
- updateLockIcon();
+ public void onUnlockMethodStateChanged() {
+ mLockIcon.update();
updateCameraVisibility();
+ updateLeftButtonVisibility();
+ }
+
+ private void inflateCameraPreview() {
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ mPreviewContainer.removeView(mCameraPreview);
+ } else {
+ Intent cameraIntent = getCameraIntent();
+ if (!Objects.equals(cameraIntent, mLastCameraIntent)) {
+ if (mCameraPreview != null) {
+ mPreviewContainer.removeView(mCameraPreview);
+ }
+ mCameraPreview = mPreviewInflater.inflatePreview(cameraIntent);
+ if (mCameraPreview != null) {
+ mPreviewContainer.addView(mCameraPreview);
+ }
+ }
+ mLastCameraIntent = cameraIntent;
+ if (mCameraPreview != null) {
+ mCameraPreview.setVisibility(View.GONE);
+ }
+ }
+ }
+
+ private void updateLeftPreview() {
+ View previewBefore = mLeftPreview;
+ if (previewBefore != null) {
+ mPreviewContainer.removeView(previewBefore);
+ }
+ if (isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ // Custom shortcuts don't support previews
+ return;
+ }
+ if (isLeftVoiceAssist()) {
+ mLeftPreview = mPreviewInflater.inflatePreviewFromService(
+ mAssistManager.getVoiceInteractorComponentName());
+ } else {
+ mLeftPreview = mPreviewInflater.inflatePreview(PHONE_INTENT);
+ }
+ if (mLeftPreview != null) {
+ mPreviewContainer.addView(mLeftPreview);
+ mLeftPreview.setVisibility(View.INVISIBLE);
+ }
}
- private void inflatePreviews() {
- mPhonePreview = mPreviewInflater.inflatePreview(PHONE_INTENT);
- mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
- if (mPhonePreview != null) {
- mPreviewContainer.addView(mPhonePreview);
- mPhonePreview.setVisibility(View.INVISIBLE);
+ public void startFinishDozeAnimation() {
+ long delay = 0;
+ if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
+ startFinishDozeAnimationElement(mLeftAffordanceView, delay);
+ delay += DOZE_ANIMATION_STAGGER_DELAY;
}
- if (mCameraPreview != null) {
- mPreviewContainer.addView(mCameraPreview);
- mCameraPreview.setVisibility(View.INVISIBLE);
+ startFinishDozeAnimationElement(mLockIcon, delay);
+ delay += DOZE_ANIMATION_STAGGER_DELAY;
+ if (mCameraImageView.getVisibility() == View.VISIBLE) {
+ startFinishDozeAnimationElement(mCameraImageView, delay);
}
+ mIndicationText.setAlpha(0f);
+ mIndicationText.animate()
+ .alpha(1f)
+ .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+ .setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
+ }
+
+ private void startFinishDozeAnimationElement(View element, long delay) {
+ element.setAlpha(0f);
+ element.setTranslationY(element.getHeight() / 2);
+ element.animate()
+ .alpha(1f)
+ .translationY(0f)
+ .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+ .setStartDelay(delay)
+ .setDuration(DOZE_ANIMATION_ELEMENT_DURATION);
}
private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
post(new Runnable() {
@Override
public void run() {
updateCameraVisibility();
+ updateLeftButtonVisibility();
}
});
}
@Override
public void onUserSwitchComplete(int userId) {
updateCameraVisibility();
+ updateLeftButtonVisibility();
+ }
+
+ @Override
+ public void onStartedWakingUp() {
+ mLockIcon.setDeviceInteractive(true);
+ }
+
+ @Override
+ public void onFinishedGoingToSleep(int why) {
+ mLockIcon.setDeviceInteractive(false);
}
@Override
public void onScreenTurnedOn() {
- updateLockIcon();
+ mLockIcon.setScreenOn(true);
+ }
+
+ @Override
+ public void onScreenTurnedOff() {
+ mLockIcon.setScreenOn(false);
+ }
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ mLockIcon.update();
+ }
+
+ @Override
+ public void onFingerprintRunningStateChanged(boolean running) {
+ mLockIcon.update();
}
@Override
- public void onScreenTurnedOff(int why) {
- updateLockIcon();
+ public void onStrongAuthStateChanged(int userId) {
+ mLockIcon.update();
}
};
mIndicationController = keyguardIndicationController;
}
+ public void setAssistManager(AssistManager assistManager) {
+ mAssistManager = assistManager;
+ updateLeftAffordance();
+ }
- /**
- * A wrapper around another Drawable that overrides the intrinsic size.
- */
- private static class IntrinsicSizeDrawable extends InsetDrawable {
-
- private final int mIntrinsicWidth;
- private final int mIntrinsicHeight;
+ public void updateLeftAffordance() {
+ updateLeftAffordanceIcon();
+ updateLeftPreview();
+ }
- public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
- super(drawable, 0);
- mIntrinsicWidth = intrinsicWidth;
- mIntrinsicHeight = intrinsicHeight;
+ private String getIndexHint(LockscreenShortcutsHelper.Shortcuts shortcut) {
+ if (mShortcutHelper.isTargetCustom(shortcut)) {
+ boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+ String label = mShortcutHelper.getFriendlyNameForUri(shortcut);
+ int resId = 0;
+ switch (shortcut) {
+ case LEFT_SHORTCUT:
+ resId = isRtl ? R.string.right_shortcut_hint : R.string.left_shortcut_hint;
+ break;
+ case RIGHT_SHORTCUT:
+ resId = isRtl ? R.string.left_shortcut_hint : R.string.right_shortcut_hint;
+ break;
+ }
+ return mContext.getString(resId, label);
+ } else {
+ return null;
}
+ }
- @Override
- public int getIntrinsicWidth() {
- return mIntrinsicWidth;
+ public String getLeftHint() {
+ String label = getIndexHint(LockscreenShortcutsHelper.Shortcuts.LEFT_SHORTCUT);
+ if (label == null) {
+ if (isLeftVoiceAssist()) {
+ label = mContext.getString(R.string.voice_hint);
+ } else {
+ label = mContext.getString(R.string.phone_hint);
+
+ }
}
+ return label;
+ }
- @Override
- public int getIntrinsicHeight() {
- return mIntrinsicHeight;
+ public String getRightHint() {
+ String label = getIndexHint(LockscreenShortcutsHelper.Shortcuts.RIGHT_SHORTCUT);
+ if (label == null) {
+ label = mContext.getString(R.string.camera_hint);
}
+ return label;
+ }
+
+ public boolean isTargetCustom(LockscreenShortcutsHelper.Shortcuts shortcut) {
+ return mShortcutHelper.isTargetCustom(shortcut);
+ }
+
+ @Override
+ public void onChange() {
+ updateCustomShortcuts();
}
}