Merge "Removes old/unused left/right button logic from bottom area." into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4c5423146c
@@ -59,26 +59,6 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.android.systemui.statusbar.KeyguardAffordanceView
|
|
||||||
android:id="@+id/camera_button"
|
|
||||||
android:layout_height="@dimen/keyguard_affordance_height"
|
|
||||||
android:layout_width="@dimen/keyguard_affordance_width"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:src="@drawable/ic_camera_alt_24dp"
|
|
||||||
android:scaleType="center"
|
|
||||||
android:contentDescription="@string/accessibility_camera_button"
|
|
||||||
android:tint="?attr/wallpaperTextColor" />
|
|
||||||
|
|
||||||
<com.android.systemui.statusbar.KeyguardAffordanceView
|
|
||||||
android:id="@+id/left_button"
|
|
||||||
android:layout_height="@dimen/keyguard_affordance_height"
|
|
||||||
android:layout_width="@dimen/keyguard_affordance_width"
|
|
||||||
android:layout_gravity="bottom|start"
|
|
||||||
android:src="@*android:drawable/ic_phone"
|
|
||||||
android:scaleType="center"
|
|
||||||
android:contentDescription="@string/accessibility_phone_button"
|
|
||||||
android:tint="?attr/wallpaperTextColor" />
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/wallet_button"
|
android:id="@+id/wallet_button"
|
||||||
android:layout_height="@dimen/keyguard_affordance_fixed_height"
|
android:layout_height="@dimen/keyguard_affordance_fixed_height"
|
||||||
|
|||||||
@@ -37,12 +37,6 @@
|
|||||||
<item>400</item>
|
<item>400</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- Show mic or phone affordance on Keyguard -->
|
|
||||||
<bool name="config_keyguardShowLeftAffordance">false</bool>
|
|
||||||
|
|
||||||
<!-- Show camera affordance on Keyguard -->
|
|
||||||
<bool name="config_keyguardShowCameraAffordance">false</bool>
|
|
||||||
|
|
||||||
<!-- decay duration (from size_max -> size), in ms -->
|
<!-- decay duration (from size_max -> size), in ms -->
|
||||||
<integer name="navigation_bar_deadzone_hold">333</integer>
|
<integer name="navigation_bar_deadzone_hold">333</integer>
|
||||||
<integer name="navigation_bar_deadzone_decay">333</integer>
|
<integer name="navigation_bar_deadzone_decay">333</integer>
|
||||||
|
|||||||
@@ -676,9 +676,6 @@
|
|||||||
<!-- The minimum background radius when swiping to a side for the camera / phone affordances. -->
|
<!-- The minimum background radius when swiping to a side for the camera / phone affordances. -->
|
||||||
<dimen name="keyguard_affordance_min_background_radius">30dp</dimen>
|
<dimen name="keyguard_affordance_min_background_radius">30dp</dimen>
|
||||||
|
|
||||||
<!-- The size of the touch targets on the keyguard for the affordances. -->
|
|
||||||
<dimen name="keyguard_affordance_touch_target_size">120dp</dimen>
|
|
||||||
|
|
||||||
<!-- The grow amount for the camera and phone circles when hinting -->
|
<!-- The grow amount for the camera and phone circles when hinting -->
|
||||||
<dimen name="hint_grow_amount_sideways">60dp</dimen>
|
<dimen name="hint_grow_amount_sideways">60dp</dimen>
|
||||||
|
|
||||||
|
|||||||
@@ -313,13 +313,6 @@
|
|||||||
<string name="accessibility_scanning_face">Scanning face</string>
|
<string name="accessibility_scanning_face">Scanning face</string>
|
||||||
<!-- Click action label for accessibility for the smart reply buttons (not shown on-screen).". [CHAR LIMIT=NONE] -->
|
<!-- Click action label for accessibility for the smart reply buttons (not shown on-screen).". [CHAR LIMIT=NONE] -->
|
||||||
<string name="accessibility_send_smart_reply">Send</string>
|
<string name="accessibility_send_smart_reply">Send</string>
|
||||||
<!-- Content description of the manage notification button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
|
|
||||||
<!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] -->
|
|
||||||
<string name="phone_label">open phone</string>
|
|
||||||
<!-- Click action label for accessibility for the voice assist button. This is not shown on-screen and is an accessibility label for the icon which launches the voice assist from the lock screen.[CHAR LIMIT=NONE] -->
|
|
||||||
<string name="voice_assist_label">open voice assist</string>
|
|
||||||
<!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] -->
|
|
||||||
<string name="camera_label">open camera</string>
|
|
||||||
<!-- Button name for "Cancel". [CHAR LIMIT=NONE] -->
|
<!-- Button name for "Cancel". [CHAR LIMIT=NONE] -->
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.camera
|
||||||
|
|
||||||
|
import android.app.ActivityManager
|
||||||
|
import android.app.ActivityManager.RunningTaskInfo
|
||||||
|
import android.app.ActivityOptions
|
||||||
|
import android.app.ActivityTaskManager
|
||||||
|
import android.content.ContentResolver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.ResolveInfo
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.RemoteException
|
||||||
|
import android.os.UserHandle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.WindowManager
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
|
import com.android.systemui.ActivityIntentHelper
|
||||||
|
import com.android.systemui.camera.CameraIntents.Companion.isSecureCameraIntent
|
||||||
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
|
import com.android.systemui.statusbar.StatusBarState
|
||||||
|
import com.android.systemui.statusbar.phone.CentralSurfaces
|
||||||
|
import com.android.systemui.statusbar.phone.PanelViewController
|
||||||
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with handling camera-related gestures (for example, double-tap the power button to launch
|
||||||
|
* the camera).
|
||||||
|
*/
|
||||||
|
class CameraGestureHelper @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val centralSurfaces: CentralSurfaces,
|
||||||
|
private val keyguardStateController: KeyguardStateController,
|
||||||
|
private val packageManager: PackageManager,
|
||||||
|
private val activityManager: ActivityManager,
|
||||||
|
private val activityStarter: ActivityStarter,
|
||||||
|
private val activityIntentHelper: ActivityIntentHelper,
|
||||||
|
private val cameraIntents: CameraIntentsWrapper,
|
||||||
|
private val contentResolver: ContentResolver,
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* Whether the camera application can be launched for the camera launch gesture.
|
||||||
|
*/
|
||||||
|
fun canCameraGestureBeLaunched(statusBarState: Int): Boolean {
|
||||||
|
if (!centralSurfaces.isCameraAllowedByAdmin) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolveInfo: ResolveInfo = packageManager.resolveActivityAsUser(
|
||||||
|
getStartCameraIntent(),
|
||||||
|
PackageManager.MATCH_DEFAULT_ONLY,
|
||||||
|
KeyguardUpdateMonitor.getCurrentUser()
|
||||||
|
)
|
||||||
|
val resolvedPackage = resolveInfo.activityInfo?.packageName
|
||||||
|
return (resolvedPackage != null &&
|
||||||
|
(statusBarState != StatusBarState.SHADE ||
|
||||||
|
!isForegroundApp(resolvedPackage)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launches the camera.
|
||||||
|
*
|
||||||
|
* @param source The source of the camera launch, to be passed to the camera app via [Intent]
|
||||||
|
*/
|
||||||
|
fun launchCamera(source: Int) {
|
||||||
|
val intent: Intent = getStartCameraIntent()
|
||||||
|
intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source)
|
||||||
|
val wouldLaunchResolverActivity = activityIntentHelper.wouldLaunchResolverActivity(
|
||||||
|
intent, KeyguardUpdateMonitor.getCurrentUser()
|
||||||
|
)
|
||||||
|
if (isSecureCameraIntent(intent) && !wouldLaunchResolverActivity) {
|
||||||
|
AsyncTask.execute {
|
||||||
|
// Normally an activity will set its requested rotation animation on its window.
|
||||||
|
// However when launching an activity causes the orientation to change this is too
|
||||||
|
// late. In these cases, the default animation is used. This doesn't look good for
|
||||||
|
// the camera (as it rotates the camera contents out of sync with physical reality).
|
||||||
|
// Therefore, we ask the WindowManager to force the cross-fade animation if an
|
||||||
|
// orientation change happens to occur during the launch.
|
||||||
|
val activityOptions = ActivityOptions.makeBasic()
|
||||||
|
activityOptions.setDisallowEnterPictureInPictureWhileLaunching(true)
|
||||||
|
activityOptions.rotationAnimationHint =
|
||||||
|
WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS
|
||||||
|
try {
|
||||||
|
ActivityTaskManager.getService().startActivityAsUser(
|
||||||
|
null,
|
||||||
|
context.basePackageName,
|
||||||
|
context.attributionTag,
|
||||||
|
intent,
|
||||||
|
intent.resolveTypeIfNeeded(contentResolver),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
Intent.FLAG_ACTIVITY_NEW_TASK,
|
||||||
|
null,
|
||||||
|
activityOptions.toBundle(),
|
||||||
|
UserHandle.CURRENT.identifier,
|
||||||
|
)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
Log.w(
|
||||||
|
PanelViewController.TAG,
|
||||||
|
"Unable to start camera activity",
|
||||||
|
e
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We need to delay starting the activity because ResolverActivity finishes itself if
|
||||||
|
// launched from behind the lock-screen.
|
||||||
|
activityStarter.startActivity(intent, false /* dismissShade */)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an [Intent] that can be used to start the camera app such that it occludes the
|
||||||
|
* lock-screen, if needed.
|
||||||
|
*/
|
||||||
|
private fun getStartCameraIntent(): Intent {
|
||||||
|
val isLockScreenDismissible = keyguardStateController.canDismissLockScreen()
|
||||||
|
val isSecure = keyguardStateController.isMethodSecure
|
||||||
|
return if (isSecure && !isLockScreenDismissible) {
|
||||||
|
cameraIntents.getSecureCameraIntent()
|
||||||
|
} else {
|
||||||
|
cameraIntents.getInsecureCameraIntent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if the application with the given package name is running in the foreground;
|
||||||
|
* `false` otherwise
|
||||||
|
*/
|
||||||
|
private fun isForegroundApp(packageName: String): Boolean {
|
||||||
|
val tasks: List<RunningTaskInfo> = activityManager.getRunningTasks(1)
|
||||||
|
return tasks.isNotEmpty() && packageName == tasks[0].topActivity.packageName
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val EXTRA_CAMERA_LAUNCH_SOURCE = "com.android.systemui.camera_launch_source"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.camera
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/** Injectable wrapper around [CameraIntents]. */
|
||||||
|
class CameraIntentsWrapper @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an [Intent] that can be used to start the camera, suitable for when the device is
|
||||||
|
* already unlocked
|
||||||
|
*/
|
||||||
|
fun getSecureCameraIntent(): Intent {
|
||||||
|
return CameraIntents.getSecureCameraIntent(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an [Intent] that can be used to start the camera, suitable for when the device is not
|
||||||
|
* already unlocked
|
||||||
|
*/
|
||||||
|
fun getInsecureCameraIntent(): Intent {
|
||||||
|
return CameraIntents.getInsecureCameraIntent(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -427,12 +427,6 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn
|
|||||||
|
|
||||||
void onHintFinished();
|
void onHintFinished();
|
||||||
|
|
||||||
void onCameraHintStarted();
|
|
||||||
|
|
||||||
void onVoiceAssistHintStarted();
|
|
||||||
|
|
||||||
void onPhoneHintStarted();
|
|
||||||
|
|
||||||
void onTrackingStopped(boolean expand);
|
void onTrackingStopped(boolean expand);
|
||||||
|
|
||||||
// TODO: Figure out way to remove these.
|
// TODO: Figure out way to remove these.
|
||||||
|
|||||||
@@ -388,8 +388,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
|
|||||||
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||||
mStatusBarKeyguardViewManager.reset(true /* hide */);
|
mStatusBarKeyguardViewManager.reset(true /* hide */);
|
||||||
}
|
}
|
||||||
mNotificationPanelViewController.launchCamera(
|
mNotificationPanelViewController.launchCamera(source);
|
||||||
mCentralSurfaces.isDeviceInteractive() /* animate */, source);
|
|
||||||
mCentralSurfaces.updateScrimController();
|
mCentralSurfaces.updateScrimController();
|
||||||
} else {
|
} else {
|
||||||
// We need to defer the camera launch until the screen comes on, since otherwise
|
// We need to defer the camera launch until the screen comes on, since otherwise
|
||||||
|
|||||||
@@ -1285,8 +1285,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
backdrop.setScaleY(scale);
|
backdrop.setScaleY(scale);
|
||||||
});
|
});
|
||||||
|
|
||||||
mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
|
|
||||||
|
|
||||||
// Set up the quick settings tile panel
|
// Set up the quick settings tile panel
|
||||||
final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
|
final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
@@ -3025,8 +3023,7 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInLaunchTransition() {
|
public boolean isInLaunchTransition() {
|
||||||
return mNotificationPanelViewController.isLaunchTransitionRunning()
|
return mNotificationPanelViewController.isLaunchTransitionFinished();
|
||||||
|| mNotificationPanelViewController.isLaunchTransitionFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3058,11 +3055,7 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
mCommandQueue.appTransitionStarting(mDisplayId, SystemClock.uptimeMillis(),
|
mCommandQueue.appTransitionStarting(mDisplayId, SystemClock.uptimeMillis(),
|
||||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
|
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
|
||||||
};
|
};
|
||||||
if (mNotificationPanelViewController.isLaunchTransitionRunning()) {
|
hideRunnable.run();
|
||||||
mNotificationPanelViewController.setLaunchTransitionEndRunnable(hideRunnable);
|
|
||||||
} else {
|
|
||||||
hideRunnable.run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelAfterLaunchTransitionRunnables() {
|
private void cancelAfterLaunchTransitionRunnables() {
|
||||||
@@ -3071,7 +3064,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
}
|
}
|
||||||
mLaunchTransitionEndRunnable = null;
|
mLaunchTransitionEndRunnable = null;
|
||||||
mLaunchTransitionCancelRunnable = null;
|
mLaunchTransitionCancelRunnable = null;
|
||||||
mNotificationPanelViewController.setLaunchTransitionEndRunnable(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3499,24 +3491,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
|
mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCameraHintStarted() {
|
|
||||||
mFalsingCollector.onCameraHintStarted();
|
|
||||||
mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVoiceAssistHintStarted() {
|
|
||||||
mFalsingCollector.onLeftAffordanceHintStarted();
|
|
||||||
mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPhoneHintStarted() {
|
|
||||||
mFalsingCollector.onLeftAffordanceHintStarted();
|
|
||||||
mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackingStopped(boolean expand) {
|
public void onTrackingStopped(boolean expand) {
|
||||||
}
|
}
|
||||||
@@ -3701,8 +3675,7 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
mWakeUpCoordinator.setFullyAwake(true);
|
mWakeUpCoordinator.setFullyAwake(true);
|
||||||
mWakeUpCoordinator.setWakingUp(false);
|
mWakeUpCoordinator.setWakingUp(false);
|
||||||
if (mLaunchCameraWhenFinishedWaking) {
|
if (mLaunchCameraWhenFinishedWaking) {
|
||||||
mNotificationPanelViewController.launchCamera(
|
mNotificationPanelViewController.launchCamera(mLastCameraLaunchSource);
|
||||||
false /* animate */, mLastCameraLaunchSource);
|
|
||||||
mLaunchCameraWhenFinishedWaking = false;
|
mLaunchCameraWhenFinishedWaking = false;
|
||||||
}
|
}
|
||||||
if (mLaunchEmergencyActionWhenFinishedWaking) {
|
if (mLaunchEmergencyActionWhenFinishedWaking) {
|
||||||
@@ -4344,9 +4317,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
if (!mUserSetup) {
|
if (!mUserSetup) {
|
||||||
animateCollapseQuickSettings();
|
animateCollapseQuickSettings();
|
||||||
}
|
}
|
||||||
if (mNotificationPanelViewController != null) {
|
|
||||||
mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
|
|
||||||
}
|
|
||||||
updateQsExpansionEnabled();
|
updateQsExpansionEnabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,587 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.systemui.statusbar.phone;
|
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorListenerAdapter;
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.VelocityTracker;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewConfiguration;
|
|
||||||
|
|
||||||
import com.android.systemui.R;
|
|
||||||
import com.android.systemui.animation.Interpolators;
|
|
||||||
import com.android.systemui.classifier.Classifier;
|
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
|
||||||
import com.android.systemui.statusbar.KeyguardAffordanceView;
|
|
||||||
import com.android.wm.shell.animation.FlingAnimationUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A touch handler of the keyguard which is responsible for launching phone and camera affordances.
|
|
||||||
*/
|
|
||||||
public class KeyguardAffordanceHelper {
|
|
||||||
|
|
||||||
public static final long HINT_PHASE1_DURATION = 200;
|
|
||||||
private static final long HINT_PHASE2_DURATION = 350;
|
|
||||||
private static final float BACKGROUND_RADIUS_SCALE_FACTOR = 0.25f;
|
|
||||||
private static final int HINT_CIRCLE_OPEN_DURATION = 500;
|
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
private final Callback mCallback;
|
|
||||||
|
|
||||||
private FlingAnimationUtils mFlingAnimationUtils;
|
|
||||||
private VelocityTracker mVelocityTracker;
|
|
||||||
private boolean mSwipingInProgress;
|
|
||||||
private float mInitialTouchX;
|
|
||||||
private float mInitialTouchY;
|
|
||||||
private float mTranslation;
|
|
||||||
private float mTranslationOnDown;
|
|
||||||
private int mTouchSlop;
|
|
||||||
private int mMinTranslationAmount;
|
|
||||||
private int mMinFlingVelocity;
|
|
||||||
private int mHintGrowAmount;
|
|
||||||
private KeyguardAffordanceView mLeftIcon;
|
|
||||||
private KeyguardAffordanceView mRightIcon;
|
|
||||||
private Animator mSwipeAnimator;
|
|
||||||
private final FalsingManager mFalsingManager;
|
|
||||||
private int mMinBackgroundRadius;
|
|
||||||
private boolean mMotionCancelled;
|
|
||||||
private int mTouchTargetSize;
|
|
||||||
private View mTargetedView;
|
|
||||||
private boolean mTouchSlopExeeded;
|
|
||||||
private AnimatorListenerAdapter mFlingEndListener = new AnimatorListenerAdapter() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
mSwipeAnimator = null;
|
|
||||||
mSwipingInProgress = false;
|
|
||||||
mTargetedView = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private Runnable mAnimationEndRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mCallback.onAnimationToSideEnded();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
KeyguardAffordanceHelper(Callback callback, Context context, FalsingManager falsingManager) {
|
|
||||||
mContext = context;
|
|
||||||
mCallback = callback;
|
|
||||||
initIcons();
|
|
||||||
updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false);
|
|
||||||
updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false);
|
|
||||||
mFalsingManager = falsingManager;
|
|
||||||
initDimens();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initDimens() {
|
|
||||||
final ViewConfiguration configuration = ViewConfiguration.get(mContext);
|
|
||||||
mTouchSlop = configuration.getScaledPagingTouchSlop();
|
|
||||||
mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
|
|
||||||
mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
|
|
||||||
R.dimen.keyguard_min_swipe_amount);
|
|
||||||
mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
|
|
||||||
R.dimen.keyguard_affordance_min_background_radius);
|
|
||||||
mTouchTargetSize = mContext.getResources().getDimensionPixelSize(
|
|
||||||
R.dimen.keyguard_affordance_touch_target_size);
|
|
||||||
mHintGrowAmount =
|
|
||||||
mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways);
|
|
||||||
mFlingAnimationUtils = new FlingAnimationUtils(mContext.getResources().getDisplayMetrics(),
|
|
||||||
0.4f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initIcons() {
|
|
||||||
mLeftIcon = mCallback.getLeftIcon();
|
|
||||||
mRightIcon = mCallback.getRightIcon();
|
|
||||||
updatePreviews();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePreviews() {
|
|
||||||
mLeftIcon.setPreviewView(mCallback.getLeftPreview());
|
|
||||||
mRightIcon.setPreviewView(mCallback.getRightPreview());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
int action = event.getActionMasked();
|
|
||||||
if (mMotionCancelled && action != MotionEvent.ACTION_DOWN) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final float y = event.getY();
|
|
||||||
final float x = event.getX();
|
|
||||||
|
|
||||||
boolean isUp = false;
|
|
||||||
switch (action) {
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
View targetView = getIconAtPosition(x, y);
|
|
||||||
if (targetView == null || (mTargetedView != null && mTargetedView != targetView)) {
|
|
||||||
mMotionCancelled = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (mTargetedView != null) {
|
|
||||||
cancelAnimation();
|
|
||||||
} else {
|
|
||||||
mTouchSlopExeeded = false;
|
|
||||||
}
|
|
||||||
startSwiping(targetView);
|
|
||||||
mInitialTouchX = x;
|
|
||||||
mInitialTouchY = y;
|
|
||||||
mTranslationOnDown = mTranslation;
|
|
||||||
initVelocityTracker();
|
|
||||||
trackMovement(event);
|
|
||||||
mMotionCancelled = false;
|
|
||||||
break;
|
|
||||||
case MotionEvent.ACTION_POINTER_DOWN:
|
|
||||||
mMotionCancelled = true;
|
|
||||||
endMotion(true /* forceSnapBack */, x, y);
|
|
||||||
break;
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
|
||||||
trackMovement(event);
|
|
||||||
float xDist = x - mInitialTouchX;
|
|
||||||
float yDist = y - mInitialTouchY;
|
|
||||||
float distance = (float) Math.hypot(xDist, yDist);
|
|
||||||
if (!mTouchSlopExeeded && distance > mTouchSlop) {
|
|
||||||
mTouchSlopExeeded = true;
|
|
||||||
}
|
|
||||||
if (mSwipingInProgress) {
|
|
||||||
if (mTargetedView == mRightIcon) {
|
|
||||||
distance = mTranslationOnDown - distance;
|
|
||||||
distance = Math.min(0, distance);
|
|
||||||
} else {
|
|
||||||
distance = mTranslationOnDown + distance;
|
|
||||||
distance = Math.max(0, distance);
|
|
||||||
}
|
|
||||||
setTranslation(distance, false /* isReset */, false /* animateReset */);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
isUp = true;
|
|
||||||
case MotionEvent.ACTION_CANCEL:
|
|
||||||
boolean hintOnTheRight = mTargetedView == mRightIcon;
|
|
||||||
trackMovement(event);
|
|
||||||
endMotion(!isUp, x, y);
|
|
||||||
if (!mTouchSlopExeeded && isUp) {
|
|
||||||
mCallback.onIconClicked(hintOnTheRight);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startSwiping(View targetView) {
|
|
||||||
mCallback.onSwipingStarted(targetView == mRightIcon);
|
|
||||||
mSwipingInProgress = true;
|
|
||||||
mTargetedView = targetView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private View getIconAtPosition(float x, float y) {
|
|
||||||
if (leftSwipePossible() && isOnIcon(mLeftIcon, x, y)) {
|
|
||||||
return mLeftIcon;
|
|
||||||
}
|
|
||||||
if (rightSwipePossible() && isOnIcon(mRightIcon, x, y)) {
|
|
||||||
return mRightIcon;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOnAffordanceIcon(float x, float y) {
|
|
||||||
return isOnIcon(mLeftIcon, x, y) || isOnIcon(mRightIcon, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOnIcon(View icon, float x, float y) {
|
|
||||||
float iconX = icon.getX() + icon.getWidth() / 2.0f;
|
|
||||||
float iconY = icon.getY() + icon.getHeight() / 2.0f;
|
|
||||||
double distance = Math.hypot(x - iconX, y - iconY);
|
|
||||||
return distance <= mTouchTargetSize / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void endMotion(boolean forceSnapBack, float lastX, float lastY) {
|
|
||||||
if (mSwipingInProgress) {
|
|
||||||
flingWithCurrentVelocity(forceSnapBack, lastX, lastY);
|
|
||||||
} else {
|
|
||||||
mTargetedView = null;
|
|
||||||
}
|
|
||||||
if (mVelocityTracker != null) {
|
|
||||||
mVelocityTracker.recycle();
|
|
||||||
mVelocityTracker = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean rightSwipePossible() {
|
|
||||||
return mRightIcon.getVisibility() == View.VISIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean leftSwipePossible() {
|
|
||||||
return mLeftIcon.getVisibility() == View.VISIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startHintAnimation(boolean right,
|
|
||||||
Runnable onFinishedListener) {
|
|
||||||
cancelAnimation();
|
|
||||||
startHintAnimationPhase1(right, onFinishedListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startHintAnimationPhase1(final boolean right, final Runnable onFinishedListener) {
|
|
||||||
final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
|
|
||||||
ValueAnimator animator = getAnimatorToRadius(right, mHintGrowAmount);
|
|
||||||
animator.addListener(new AnimatorListenerAdapter() {
|
|
||||||
private boolean mCancelled;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationCancel(Animator animation) {
|
|
||||||
mCancelled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
if (mCancelled) {
|
|
||||||
mSwipeAnimator = null;
|
|
||||||
mTargetedView = null;
|
|
||||||
onFinishedListener.run();
|
|
||||||
} else {
|
|
||||||
startUnlockHintAnimationPhase2(right, onFinishedListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
|
|
||||||
animator.setDuration(HINT_PHASE1_DURATION);
|
|
||||||
animator.start();
|
|
||||||
mSwipeAnimator = animator;
|
|
||||||
mTargetedView = targetView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Phase 2: Move back.
|
|
||||||
*/
|
|
||||||
private void startUnlockHintAnimationPhase2(boolean right, final Runnable onFinishedListener) {
|
|
||||||
ValueAnimator animator = getAnimatorToRadius(right, 0);
|
|
||||||
animator.addListener(new AnimatorListenerAdapter() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
mSwipeAnimator = null;
|
|
||||||
mTargetedView = null;
|
|
||||||
onFinishedListener.run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
animator.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
|
|
||||||
animator.setDuration(HINT_PHASE2_DURATION);
|
|
||||||
animator.setStartDelay(HINT_CIRCLE_OPEN_DURATION);
|
|
||||||
animator.start();
|
|
||||||
mSwipeAnimator = animator;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ValueAnimator getAnimatorToRadius(final boolean right, int radius) {
|
|
||||||
final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
|
|
||||||
ValueAnimator animator = ValueAnimator.ofFloat(targetView.getCircleRadius(), radius);
|
|
||||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
|
||||||
float newRadius = (float) animation.getAnimatedValue();
|
|
||||||
targetView.setCircleRadiusWithoutAnimation(newRadius);
|
|
||||||
float translation = getTranslationFromRadius(newRadius);
|
|
||||||
mTranslation = right ? -translation : translation;
|
|
||||||
updateIconsFromTranslation(targetView);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return animator;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelAnimation() {
|
|
||||||
if (mSwipeAnimator != null) {
|
|
||||||
mSwipeAnimator.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void flingWithCurrentVelocity(boolean forceSnapBack, float lastX, float lastY) {
|
|
||||||
float vel = getCurrentVelocity(lastX, lastY);
|
|
||||||
|
|
||||||
// We snap back if the current translation is not far enough
|
|
||||||
boolean snapBack = false;
|
|
||||||
if (mCallback.needsAntiFalsing()) {
|
|
||||||
snapBack = snapBack || mFalsingManager.isFalseTouch(
|
|
||||||
mTargetedView == mRightIcon
|
|
||||||
? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE);
|
|
||||||
}
|
|
||||||
snapBack = snapBack || isBelowFalsingThreshold();
|
|
||||||
|
|
||||||
// or if the velocity is in the opposite direction.
|
|
||||||
boolean velIsInWrongDirection = vel * mTranslation < 0;
|
|
||||||
snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection;
|
|
||||||
vel = snapBack ^ velIsInWrongDirection ? 0 : vel;
|
|
||||||
fling(vel, snapBack || forceSnapBack, mTranslation < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isBelowFalsingThreshold() {
|
|
||||||
return Math.abs(mTranslation) < Math.abs(mTranslationOnDown) + getMinTranslationAmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getMinTranslationAmount() {
|
|
||||||
float factor = mCallback.getAffordanceFalsingFactor();
|
|
||||||
return (int) (mMinTranslationAmount * factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fling(float vel, final boolean snapBack, boolean right) {
|
|
||||||
float target = right ? -mCallback.getMaxTranslationDistance()
|
|
||||||
: mCallback.getMaxTranslationDistance();
|
|
||||||
target = snapBack ? 0 : target;
|
|
||||||
|
|
||||||
ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
|
|
||||||
mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
|
|
||||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
|
||||||
mTranslation = (float) animation.getAnimatedValue();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
animator.addListener(mFlingEndListener);
|
|
||||||
if (!snapBack) {
|
|
||||||
startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable, right);
|
|
||||||
mCallback.onAnimationToSideStarted(right, mTranslation, vel);
|
|
||||||
} else {
|
|
||||||
reset(true);
|
|
||||||
}
|
|
||||||
animator.start();
|
|
||||||
mSwipeAnimator = animator;
|
|
||||||
if (snapBack) {
|
|
||||||
mCallback.onSwipingAborted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startFinishingCircleAnimation(float velocity, Runnable animationEndRunnable,
|
|
||||||
boolean right) {
|
|
||||||
KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
|
|
||||||
targetView.finishAnimation(velocity, animationEndRunnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setTranslation(float translation, boolean isReset, boolean animateReset) {
|
|
||||||
translation = rightSwipePossible() ? translation : Math.max(0, translation);
|
|
||||||
translation = leftSwipePossible() ? translation : Math.min(0, translation);
|
|
||||||
float absTranslation = Math.abs(translation);
|
|
||||||
if (translation != mTranslation || isReset) {
|
|
||||||
KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon;
|
|
||||||
KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon;
|
|
||||||
float alpha = absTranslation / getMinTranslationAmount();
|
|
||||||
|
|
||||||
// We interpolate the alpha of the other icons to 0
|
|
||||||
float fadeOutAlpha = 1.0f - alpha;
|
|
||||||
fadeOutAlpha = Math.max(fadeOutAlpha, 0.0f);
|
|
||||||
|
|
||||||
boolean animateIcons = isReset && animateReset;
|
|
||||||
boolean forceNoCircleAnimation = isReset && !animateReset;
|
|
||||||
float radius = getRadiusFromTranslation(absTranslation);
|
|
||||||
boolean slowAnimation = isReset && isBelowFalsingThreshold();
|
|
||||||
if (!isReset) {
|
|
||||||
updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(),
|
|
||||||
false, false, false, false);
|
|
||||||
} else {
|
|
||||||
updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(),
|
|
||||||
animateIcons, slowAnimation, true /* isReset */, forceNoCircleAnimation);
|
|
||||||
}
|
|
||||||
updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(),
|
|
||||||
animateIcons, slowAnimation, isReset, forceNoCircleAnimation);
|
|
||||||
|
|
||||||
mTranslation = translation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateIconsFromTranslation(KeyguardAffordanceView targetView) {
|
|
||||||
float absTranslation = Math.abs(mTranslation);
|
|
||||||
float alpha = absTranslation / getMinTranslationAmount();
|
|
||||||
|
|
||||||
// We interpolate the alpha of the other icons to 0
|
|
||||||
float fadeOutAlpha = 1.0f - alpha;
|
|
||||||
fadeOutAlpha = Math.max(0.0f, fadeOutAlpha);
|
|
||||||
|
|
||||||
// We interpolate the alpha of the targetView to 1
|
|
||||||
KeyguardAffordanceView otherView = targetView == mRightIcon ? mLeftIcon : mRightIcon;
|
|
||||||
updateIconAlpha(targetView, alpha + fadeOutAlpha * targetView.getRestingAlpha(), false);
|
|
||||||
updateIconAlpha(otherView, fadeOutAlpha * otherView.getRestingAlpha(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float getTranslationFromRadius(float circleSize) {
|
|
||||||
float translation = (circleSize - mMinBackgroundRadius)
|
|
||||||
/ BACKGROUND_RADIUS_SCALE_FACTOR;
|
|
||||||
return translation > 0.0f ? translation + mTouchSlop : 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private float getRadiusFromTranslation(float translation) {
|
|
||||||
if (translation <= mTouchSlop) {
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
return (translation - mTouchSlop) * BACKGROUND_RADIUS_SCALE_FACTOR + mMinBackgroundRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void animateHideLeftRightIcon() {
|
|
||||||
cancelAnimation();
|
|
||||||
updateIcon(mRightIcon, 0f, 0f, true, false, false, false);
|
|
||||||
updateIcon(mLeftIcon, 0f, 0f, true, false, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha,
|
|
||||||
boolean animate, boolean slowRadiusAnimation, boolean force,
|
|
||||||
boolean forceNoCircleAnimation) {
|
|
||||||
if (view.getVisibility() != View.VISIBLE && !force) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (forceNoCircleAnimation) {
|
|
||||||
view.setCircleRadiusWithoutAnimation(circleRadius);
|
|
||||||
} else {
|
|
||||||
view.setCircleRadius(circleRadius, slowRadiusAnimation);
|
|
||||||
}
|
|
||||||
updateIconAlpha(view, alpha, animate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateIconAlpha(KeyguardAffordanceView view, float alpha, boolean animate) {
|
|
||||||
float scale = getScale(alpha, view);
|
|
||||||
alpha = Math.min(1.0f, alpha);
|
|
||||||
view.setImageAlpha(alpha, animate);
|
|
||||||
view.setImageScale(scale, animate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float getScale(float alpha, KeyguardAffordanceView icon) {
|
|
||||||
float scale = alpha / icon.getRestingAlpha() * 0.2f +
|
|
||||||
KeyguardAffordanceView.MIN_ICON_SCALE_AMOUNT;
|
|
||||||
return Math.min(scale, KeyguardAffordanceView.MAX_ICON_SCALE_AMOUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void trackMovement(MotionEvent event) {
|
|
||||||
if (mVelocityTracker != null) {
|
|
||||||
mVelocityTracker.addMovement(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initVelocityTracker() {
|
|
||||||
if (mVelocityTracker != null) {
|
|
||||||
mVelocityTracker.recycle();
|
|
||||||
}
|
|
||||||
mVelocityTracker = VelocityTracker.obtain();
|
|
||||||
}
|
|
||||||
|
|
||||||
private float getCurrentVelocity(float lastX, float lastY) {
|
|
||||||
if (mVelocityTracker == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
mVelocityTracker.computeCurrentVelocity(1000);
|
|
||||||
float aX = mVelocityTracker.getXVelocity();
|
|
||||||
float aY = mVelocityTracker.getYVelocity();
|
|
||||||
float bX = lastX - mInitialTouchX;
|
|
||||||
float bY = lastY - mInitialTouchY;
|
|
||||||
float bLen = (float) Math.hypot(bX, bY);
|
|
||||||
// Project the velocity onto the distance vector: a * b / |b|
|
|
||||||
float projectedVelocity = (aX * bX + aY * bY) / bLen;
|
|
||||||
if (mTargetedView == mRightIcon) {
|
|
||||||
projectedVelocity = -projectedVelocity;
|
|
||||||
}
|
|
||||||
return projectedVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onConfigurationChanged() {
|
|
||||||
initDimens();
|
|
||||||
initIcons();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onRtlPropertiesChanged() {
|
|
||||||
initIcons();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset(boolean animate) {
|
|
||||||
cancelAnimation();
|
|
||||||
setTranslation(0.0f, true /* isReset */, animate);
|
|
||||||
mMotionCancelled = true;
|
|
||||||
if (mSwipingInProgress) {
|
|
||||||
mCallback.onSwipingAborted();
|
|
||||||
mSwipingInProgress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSwipingInProgress() {
|
|
||||||
return mSwipingInProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void launchAffordance(boolean animate, boolean left) {
|
|
||||||
if (mSwipingInProgress) {
|
|
||||||
// We don't want to mess with the state if the user is actually swiping already.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
KeyguardAffordanceView targetView = left ? mLeftIcon : mRightIcon;
|
|
||||||
KeyguardAffordanceView otherView = left ? mRightIcon : mLeftIcon;
|
|
||||||
startSwiping(targetView);
|
|
||||||
|
|
||||||
// Do not animate the circle expanding if the affordance isn't visible,
|
|
||||||
// otherwise the circle will be meaningless.
|
|
||||||
if (targetView.getVisibility() != View.VISIBLE) {
|
|
||||||
animate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animate) {
|
|
||||||
fling(0, false, !left);
|
|
||||||
updateIcon(otherView, 0.0f, 0, true, false, true, false);
|
|
||||||
} else {
|
|
||||||
mCallback.onAnimationToSideStarted(!left, mTranslation, 0);
|
|
||||||
mTranslation = left ? mCallback.getMaxTranslationDistance()
|
|
||||||
: mCallback.getMaxTranslationDistance();
|
|
||||||
updateIcon(otherView, 0.0f, 0.0f, false, false, true, false);
|
|
||||||
targetView.instantFinishAnimation();
|
|
||||||
mFlingEndListener.onAnimationEnd(null);
|
|
||||||
mAnimationEndRunnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Callback {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the callback when an animation to a side page was started.
|
|
||||||
*
|
|
||||||
* @param rightPage Is the page animated to the right page?
|
|
||||||
*/
|
|
||||||
void onAnimationToSideStarted(boolean rightPage, float translation, float vel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the callback the animation to a side page has ended.
|
|
||||||
*/
|
|
||||||
void onAnimationToSideEnded();
|
|
||||||
|
|
||||||
float getMaxTranslationDistance();
|
|
||||||
|
|
||||||
void onSwipingStarted(boolean rightIcon);
|
|
||||||
|
|
||||||
void onSwipingAborted();
|
|
||||||
|
|
||||||
void onIconClicked(boolean rightIcon);
|
|
||||||
|
|
||||||
KeyguardAffordanceView getLeftIcon();
|
|
||||||
|
|
||||||
KeyguardAffordanceView getRightIcon();
|
|
||||||
|
|
||||||
View getLeftPreview();
|
|
||||||
|
|
||||||
View getRightPreview();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The factor the minimum swipe amount should be multiplied with.
|
|
||||||
*/
|
|
||||||
float getAffordanceFalsingFactor();
|
|
||||||
|
|
||||||
boolean needsAntiFalsing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,47 +16,30 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.phone;
|
package com.android.systemui.statusbar.phone;
|
||||||
|
|
||||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
|
|
||||||
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
|
||||||
|
|
||||||
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
|
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
|
||||||
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
||||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
|
|
||||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
|
|
||||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
|
|
||||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_UNLOCK;
|
|
||||||
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
|
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
|
||||||
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE;
|
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE;
|
||||||
|
|
||||||
import android.app.ActivityOptions;
|
|
||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.service.quickaccesswallet.GetWalletCardsError;
|
import android.service.quickaccesswallet.GetWalletCardsError;
|
||||||
import android.service.quickaccesswallet.GetWalletCardsResponse;
|
import android.service.quickaccesswallet.GetWalletCardsResponse;
|
||||||
import android.service.quickaccesswallet.QuickAccessWalletClient;
|
import android.service.quickaccesswallet.QuickAccessWalletClient;
|
||||||
import android.telecom.TelecomManager;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -64,81 +47,35 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
|
||||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
|
||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.systemui.ActivityIntentHelper;
|
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.assist.AssistManager;
|
|
||||||
import com.android.systemui.camera.CameraIntents;
|
|
||||||
import com.android.systemui.controls.ControlsServiceInfo;
|
|
||||||
import com.android.systemui.controls.dagger.ControlsComponent;
|
import com.android.systemui.controls.dagger.ControlsComponent;
|
||||||
import com.android.systemui.controls.management.ControlsListingController;
|
import com.android.systemui.controls.management.ControlsListingController;
|
||||||
import com.android.systemui.controls.ui.ControlsActivity;
|
import com.android.systemui.controls.ui.ControlsActivity;
|
||||||
import com.android.systemui.controls.ui.ControlsUiController;
|
import com.android.systemui.controls.ui.ControlsUiController;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
import com.android.systemui.plugins.FalsingManager;
|
||||||
import com.android.systemui.plugins.IntentButtonProvider;
|
|
||||||
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
|
|
||||||
import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
|
|
||||||
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
|
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
|
||||||
import com.android.systemui.statusbar.KeyguardAffordanceView;
|
|
||||||
import com.android.systemui.statusbar.policy.AccessibilityController;
|
|
||||||
import com.android.systemui.statusbar.policy.ExtensionController;
|
|
||||||
import com.android.systemui.statusbar.policy.ExtensionController.Extension;
|
|
||||||
import com.android.systemui.statusbar.policy.FlashlightController;
|
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.statusbar.policy.PreviewInflater;
|
|
||||||
import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory;
|
|
||||||
import com.android.systemui.tuner.TunerService;
|
|
||||||
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
|
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
|
||||||
* text.
|
* text.
|
||||||
*/
|
*/
|
||||||
public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
|
public class KeyguardBottomAreaView extends FrameLayout {
|
||||||
KeyguardStateController.Callback,
|
|
||||||
AccessibilityController.AccessibilityStateChangedCallback {
|
|
||||||
|
|
||||||
final static String TAG = "CentralSurfaces/KeyguardBottomAreaView";
|
private static final String TAG = "CentralSurfaces/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_LIFT_TRIGGER = "lift_to_launch_ml";
|
|
||||||
|
|
||||||
public static final String EXTRA_CAMERA_LAUNCH_SOURCE
|
|
||||||
= "com.android.systemui.camera_launch_source";
|
|
||||||
|
|
||||||
private static final String LEFT_BUTTON_PLUGIN
|
|
||||||
= "com.android.systemui.action.PLUGIN_LOCKSCREEN_LEFT_BUTTON";
|
|
||||||
private static final String RIGHT_BUTTON_PLUGIN
|
|
||||||
= "com.android.systemui.action.PLUGIN_LOCKSCREEN_RIGHT_BUTTON";
|
|
||||||
|
|
||||||
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 static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
|
||||||
|
|
||||||
// TODO(b/179494051): May no longer be needed
|
|
||||||
private final boolean mShowLeftAffordance;
|
|
||||||
private final boolean mShowCameraAffordance;
|
|
||||||
|
|
||||||
private KeyguardAffordanceView mRightAffordanceView;
|
|
||||||
private KeyguardAffordanceView mLeftAffordanceView;
|
|
||||||
|
|
||||||
private ImageView mWalletButton;
|
private ImageView mWalletButton;
|
||||||
private ImageView mQRCodeScannerButton;
|
private ImageView mQRCodeScannerButton;
|
||||||
private ImageView mControlsButton;
|
private ImageView mControlsButton;
|
||||||
private boolean mHasCard = false;
|
private boolean mHasCard = false;
|
||||||
private WalletCardRetriever mCardRetriever = new WalletCardRetriever();
|
private final WalletCardRetriever mCardRetriever = new WalletCardRetriever();
|
||||||
private QuickAccessWalletController mQuickAccessWalletController;
|
private QuickAccessWalletController mQuickAccessWalletController;
|
||||||
private QRCodeScannerController mQRCodeScannerController;
|
private QRCodeScannerController mQRCodeScannerController;
|
||||||
private ControlsComponent mControlsComponent;
|
private ControlsComponent mControlsComponent;
|
||||||
@@ -148,54 +85,42 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
private ViewGroup mIndicationArea;
|
private ViewGroup mIndicationArea;
|
||||||
private TextView mIndicationText;
|
private TextView mIndicationText;
|
||||||
private TextView mIndicationTextBottom;
|
private TextView mIndicationTextBottom;
|
||||||
private ViewGroup mPreviewContainer;
|
|
||||||
private ViewGroup mOverlayContainer;
|
private ViewGroup mOverlayContainer;
|
||||||
|
|
||||||
private View mLeftPreview;
|
|
||||||
private View mCameraPreview;
|
|
||||||
|
|
||||||
private ActivityStarter mActivityStarter;
|
private ActivityStarter mActivityStarter;
|
||||||
private KeyguardStateController mKeyguardStateController;
|
private KeyguardStateController mKeyguardStateController;
|
||||||
private FlashlightController mFlashlightController;
|
|
||||||
private PreviewInflater mPreviewInflater;
|
|
||||||
private AccessibilityController mAccessibilityController;
|
|
||||||
private CentralSurfaces mCentralSurfaces;
|
private CentralSurfaces mCentralSurfaces;
|
||||||
private KeyguardAffordanceHelper mAffordanceHelper;
|
|
||||||
private FalsingManager mFalsingManager;
|
private FalsingManager mFalsingManager;
|
||||||
private boolean mUserSetupComplete;
|
|
||||||
|
|
||||||
private boolean mLeftIsVoiceAssist;
|
|
||||||
private Drawable mLeftAssistIcon;
|
|
||||||
|
|
||||||
private IntentButton mRightButton = new DefaultRightButton();
|
|
||||||
private Extension<IntentButton> mRightExtension;
|
|
||||||
private String mRightButtonStr;
|
|
||||||
private IntentButton mLeftButton = new DefaultLeftButton();
|
|
||||||
private Extension<IntentButton> mLeftExtension;
|
|
||||||
private String mLeftButtonStr;
|
|
||||||
private boolean mDozing;
|
private boolean mDozing;
|
||||||
private int mIndicationBottomMargin;
|
private int mIndicationBottomMargin;
|
||||||
private int mIndicationPadding;
|
private int mIndicationPadding;
|
||||||
private float mDarkAmount;
|
private float mDarkAmount;
|
||||||
private int mBurnInXOffset;
|
private int mBurnInXOffset;
|
||||||
private int mBurnInYOffset;
|
private int mBurnInYOffset;
|
||||||
private ActivityIntentHelper mActivityIntentHelper;
|
|
||||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
|
||||||
|
|
||||||
private ControlsListingController.ControlsListingCallback mListingCallback =
|
private final ControlsListingController.ControlsListingCallback mListingCallback =
|
||||||
new ControlsListingController.ControlsListingCallback() {
|
serviceInfos -> post(() -> {
|
||||||
public void onServicesUpdated(List<ControlsServiceInfo> serviceInfos) {
|
boolean available = !serviceInfos.isEmpty();
|
||||||
post(() -> {
|
|
||||||
boolean available = !serviceInfos.isEmpty();
|
|
||||||
|
|
||||||
if (available != mControlServicesAvailable) {
|
if (available != mControlServicesAvailable) {
|
||||||
mControlServicesAvailable = available;
|
mControlServicesAvailable = available;
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateAffordanceColors();
|
updateAffordanceColors();
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
|
private final KeyguardStateController.Callback mKeyguardStateCallback =
|
||||||
|
new KeyguardStateController.Callback() {
|
||||||
|
@Override
|
||||||
|
public void onKeyguardShowingChanged() {
|
||||||
|
if (mKeyguardStateController.isShowing()) {
|
||||||
|
if (mQuickAccessWalletController != null) {
|
||||||
|
mQuickAccessWalletController.queryWalletCards(mCardRetriever);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public KeyguardBottomAreaView(Context context) {
|
public KeyguardBottomAreaView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -212,43 +137,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
|
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
|
||||||
int defStyleRes) {
|
int defStyleRes) {
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
mShowLeftAffordance = getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance);
|
|
||||||
mShowCameraAffordance = getResources()
|
|
||||||
.getBoolean(R.bool.config_keyguardShowCameraAffordance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
|
|
||||||
@Override
|
|
||||||
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
|
|
||||||
super.onInitializeAccessibilityNodeInfo(host, info);
|
|
||||||
String label = null;
|
|
||||||
if (host == mRightAffordanceView) {
|
|
||||||
label = getResources().getString(R.string.camera_label);
|
|
||||||
} else if (host == mLeftAffordanceView) {
|
|
||||||
if (mLeftIsVoiceAssist) {
|
|
||||||
label = getResources().getString(R.string.voice_assist_label);
|
|
||||||
} else {
|
|
||||||
label = getResources().getString(R.string.phone_label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info.addAction(new AccessibilityAction(ACTION_CLICK, label));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean performAccessibilityAction(View host, int action, Bundle args) {
|
|
||||||
if (action == ACTION_CLICK) {
|
|
||||||
if (host == mRightAffordanceView) {
|
|
||||||
launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
|
|
||||||
return true;
|
|
||||||
} else if (host == mLeftAffordanceView) {
|
|
||||||
launchLeftAffordance();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.performAccessibilityAction(host, action, args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void initFrom(KeyguardBottomAreaView oldBottomArea) {
|
public void initFrom(KeyguardBottomAreaView oldBottomArea) {
|
||||||
setCentralSurfaces(oldBottomArea.mCentralSurfaces);
|
setCentralSurfaces(oldBottomArea.mCentralSurfaces);
|
||||||
|
|
||||||
@@ -279,11 +169,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext),
|
|
||||||
new ActivityIntentHelper(mContext));
|
|
||||||
mOverlayContainer = findViewById(R.id.overlay_container);
|
mOverlayContainer = findViewById(R.id.overlay_container);
|
||||||
mRightAffordanceView = findViewById(R.id.camera_button);
|
|
||||||
mLeftAffordanceView = findViewById(R.id.left_button);
|
|
||||||
mWalletButton = findViewById(R.id.wallet_button);
|
mWalletButton = findViewById(R.id.wallet_button);
|
||||||
mQRCodeScannerButton = findViewById(R.id.qr_code_scanner_button);
|
mQRCodeScannerButton = findViewById(R.id.qr_code_scanner_button);
|
||||||
mControlsButton = findViewById(R.id.controls_button);
|
mControlsButton = findViewById(R.id.controls_button);
|
||||||
@@ -295,18 +181,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
R.dimen.keyguard_indication_margin_bottom);
|
R.dimen.keyguard_indication_margin_bottom);
|
||||||
mBurnInYOffset = getResources().getDimensionPixelSize(
|
mBurnInYOffset = getResources().getDimensionPixelSize(
|
||||||
R.dimen.default_burn_in_prevention_offset);
|
R.dimen.default_burn_in_prevention_offset);
|
||||||
updateCameraVisibility();
|
|
||||||
mKeyguardStateController = Dependency.get(KeyguardStateController.class);
|
mKeyguardStateController = Dependency.get(KeyguardStateController.class);
|
||||||
mKeyguardStateController.addCallback(this);
|
mKeyguardStateController.addCallback(mKeyguardStateCallback);
|
||||||
setClipChildren(false);
|
setClipChildren(false);
|
||||||
setClipToPadding(false);
|
setClipToPadding(false);
|
||||||
mRightAffordanceView.setOnClickListener(this);
|
|
||||||
mLeftAffordanceView.setOnClickListener(this);
|
|
||||||
initAccessibility();
|
|
||||||
mActivityStarter = Dependency.get(ActivityStarter.class);
|
mActivityStarter = Dependency.get(ActivityStarter.class);
|
||||||
mFlashlightController = Dependency.get(FlashlightController.class);
|
|
||||||
mAccessibilityController = Dependency.get(AccessibilityController.class);
|
|
||||||
mActivityIntentHelper = new ActivityIntentHelper(getContext());
|
|
||||||
|
|
||||||
mIndicationPadding = getResources().getDimensionPixelSize(
|
mIndicationPadding = getResources().getDimensionPixelSize(
|
||||||
R.dimen.keyguard_indication_area_padding);
|
R.dimen.keyguard_indication_area_padding);
|
||||||
@@ -315,51 +194,18 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the container where the previews are rendered.
|
|
||||||
*/
|
|
||||||
public void setPreviewContainer(ViewGroup previewContainer) {
|
|
||||||
mPreviewContainer = previewContainer;
|
|
||||||
inflateCameraPreview();
|
|
||||||
updateLeftAffordance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onAttachedToWindow() {
|
protected void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
mAccessibilityController.addStateChangedCallback(this);
|
|
||||||
mRightExtension = Dependency.get(ExtensionController.class).newExtension(IntentButton.class)
|
|
||||||
.withPlugin(IntentButtonProvider.class, RIGHT_BUTTON_PLUGIN,
|
|
||||||
p -> p.getIntentButton())
|
|
||||||
.withTunerFactory(new LockButtonFactory(mContext, LOCKSCREEN_RIGHT_BUTTON))
|
|
||||||
.withDefault(() -> new DefaultRightButton())
|
|
||||||
.withCallback(button -> setRightButton(button))
|
|
||||||
.build();
|
|
||||||
mLeftExtension = Dependency.get(ExtensionController.class).newExtension(IntentButton.class)
|
|
||||||
.withPlugin(IntentButtonProvider.class, LEFT_BUTTON_PLUGIN,
|
|
||||||
p -> p.getIntentButton())
|
|
||||||
.withTunerFactory(new LockButtonFactory(mContext, LOCKSCREEN_LEFT_BUTTON))
|
|
||||||
.withDefault(() -> new DefaultLeftButton())
|
|
||||||
.withCallback(button -> setLeftButton(button))
|
|
||||||
.build();
|
|
||||||
final IntentFilter filter = new IntentFilter();
|
final IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
|
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
|
||||||
getContext().registerReceiverAsUser(mDevicePolicyReceiver,
|
mKeyguardStateController.addCallback(mKeyguardStateCallback);
|
||||||
UserHandle.ALL, filter, null, null);
|
|
||||||
mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
|
|
||||||
mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
|
|
||||||
mKeyguardStateController.addCallback(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
mKeyguardStateController.removeCallback(this);
|
mKeyguardStateController.removeCallback(mKeyguardStateCallback);
|
||||||
mAccessibilityController.removeStateChangedCallback(this);
|
|
||||||
mRightExtension.destroy();
|
|
||||||
mLeftExtension.destroy();
|
|
||||||
getContext().unregisterReceiver(mDevicePolicyReceiver);
|
|
||||||
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
|
|
||||||
|
|
||||||
if (mQuickAccessWalletController != null) {
|
if (mQuickAccessWalletController != null) {
|
||||||
mQuickAccessWalletController.unregisterWalletChangeObservers(
|
mQuickAccessWalletController.unregisterWalletChangeObservers(
|
||||||
@@ -378,11 +224,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initAccessibility() {
|
|
||||||
mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
|
|
||||||
mRightAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onConfigurationChanged(Configuration newConfig) {
|
protected void onConfigurationChanged(Configuration newConfig) {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
@@ -404,19 +245,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
getResources().getDimensionPixelSize(
|
getResources().getDimensionPixelSize(
|
||||||
com.android.internal.R.dimen.text_size_small_material));
|
com.android.internal.R.dimen.text_size_small_material));
|
||||||
|
|
||||||
ViewGroup.LayoutParams lp = mRightAffordanceView.getLayoutParams();
|
ViewGroup.LayoutParams lp = mWalletButton.getLayoutParams();
|
||||||
lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
|
|
||||||
lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
|
|
||||||
mRightAffordanceView.setLayoutParams(lp);
|
|
||||||
updateRightAffordanceIcon();
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
lp = mWalletButton.getLayoutParams();
|
|
||||||
lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width);
|
lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width);
|
||||||
lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height);
|
lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height);
|
||||||
mWalletButton.setLayoutParams(lp);
|
mWalletButton.setLayoutParams(lp);
|
||||||
@@ -439,74 +268,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
updateAffordanceColors();
|
updateAffordanceColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRightAffordanceIcon() {
|
|
||||||
IconState state = mRightButton.getIcon();
|
|
||||||
mRightAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
|
|
||||||
if (state.drawable != mRightAffordanceView.getDrawable()
|
|
||||||
|| state.tint != mRightAffordanceView.shouldTint()) {
|
|
||||||
mRightAffordanceView.setImageDrawable(state.drawable, state.tint);
|
|
||||||
}
|
|
||||||
mRightAffordanceView.setContentDescription(state.contentDescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCentralSurfaces(CentralSurfaces centralSurfaces) {
|
public void setCentralSurfaces(CentralSurfaces centralSurfaces) {
|
||||||
mCentralSurfaces = centralSurfaces;
|
mCentralSurfaces = centralSurfaces;
|
||||||
updateCameraVisibility(); // in case onFinishInflate() was called too early
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAffordanceHelper(KeyguardAffordanceHelper affordanceHelper) {
|
|
||||||
mAffordanceHelper = affordanceHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserSetupComplete(boolean userSetupComplete) {
|
|
||||||
mUserSetupComplete = userSetupComplete;
|
|
||||||
updateCameraVisibility();
|
|
||||||
updateLeftAffordanceIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Intent getCameraIntent() {
|
|
||||||
return mRightButton.getIntent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the intent to launch the camera application.
|
|
||||||
*/
|
|
||||||
public ResolveInfo resolveCameraIntent() {
|
|
||||||
return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
|
|
||||||
PackageManager.MATCH_DEFAULT_ONLY,
|
|
||||||
KeyguardUpdateMonitor.getCurrentUser());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCameraVisibility() {
|
|
||||||
if (mRightAffordanceView == null) {
|
|
||||||
// Things are not set up yet; reply hazy, ask again later
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mRightAffordanceView.setVisibility(!mDozing && mShowCameraAffordance
|
|
||||||
&& mRightButton.getIcon().isVisible ? View.VISIBLE : View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an alternate icon for the left assist affordance (replace the mic icon)
|
|
||||||
*/
|
|
||||||
public void setLeftAssistIcon(Drawable drawable) {
|
|
||||||
mLeftAssistIcon = drawable;
|
|
||||||
updateLeftAffordanceIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateLeftAffordanceIcon() {
|
|
||||||
if (!mShowLeftAffordance || mDozing) {
|
|
||||||
mLeftAffordanceView.setVisibility(GONE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IconState state = mLeftButton.getIcon();
|
|
||||||
mLeftAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE);
|
|
||||||
if (state.drawable != mLeftAffordanceView.getDrawable()
|
|
||||||
|| state.tint != mLeftAffordanceView.shouldTint()) {
|
|
||||||
mLeftAffordanceView.setImageDrawable(state.drawable, state.tint);
|
|
||||||
}
|
|
||||||
mLeftAffordanceView.setContentDescription(state.contentDescription);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateWalletVisibility() {
|
private void updateWalletVisibility() {
|
||||||
@@ -552,73 +315,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLeftVoiceAssist() {
|
|
||||||
return mLeftIsVoiceAssist;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPhoneVisible() {
|
|
||||||
PackageManager pm = mContext.getPackageManager();
|
|
||||||
return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
|
|
||||||
&& pm.resolveActivity(PHONE_INTENT, 0) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
|
|
||||||
mRightAffordanceView.setClickable(touchExplorationEnabled);
|
|
||||||
mLeftAffordanceView.setClickable(touchExplorationEnabled);
|
|
||||||
mRightAffordanceView.setFocusable(accessibilityEnabled);
|
|
||||||
mLeftAffordanceView.setFocusable(accessibilityEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v == mRightAffordanceView) {
|
|
||||||
launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
|
|
||||||
} else if (v == mLeftAffordanceView) {
|
|
||||||
launchLeftAffordance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void launchCamera(String source) {
|
|
||||||
final Intent intent = getCameraIntent();
|
|
||||||
intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
|
|
||||||
boolean wouldLaunchResolverActivity = mActivityIntentHelper.wouldLaunchResolverActivity(
|
|
||||||
intent, KeyguardUpdateMonitor.getCurrentUser());
|
|
||||||
if (CameraIntents.isSecureCameraIntent(intent) && !wouldLaunchResolverActivity) {
|
|
||||||
AsyncTask.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Normally an activity will set it's requested rotation
|
|
||||||
// animation on its window. However when launching an activity
|
|
||||||
// causes the orientation to change this is too late. In these cases
|
|
||||||
// the default animation is used. This doesn't look good for
|
|
||||||
// the camera (as it rotates the camera contents out of sync
|
|
||||||
// with physical reality). So, we ask the WindowManager to
|
|
||||||
// force the crossfade animation if an orientation change
|
|
||||||
// happens to occur during the launch.
|
|
||||||
ActivityOptions o = ActivityOptions.makeBasic();
|
|
||||||
o.setDisallowEnterPictureInPictureWhileLaunching(true);
|
|
||||||
o.setRotationAnimationHint(
|
|
||||||
WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
|
|
||||||
try {
|
|
||||||
ActivityTaskManager.getService().startActivityAsUser(
|
|
||||||
null, getContext().getBasePackageName(),
|
|
||||||
getContext().getAttributionTag(), intent,
|
|
||||||
intent.resolveTypeIfNeeded(getContext().getContentResolver()),
|
|
||||||
null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(),
|
|
||||||
UserHandle.CURRENT.getIdentifier());
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, "Unable to start camera activity", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// We need to delay starting the activity because ResolverActivity finishes itself if
|
|
||||||
// launched behind lockscreen.
|
|
||||||
mActivityStarter.startActivity(intent, false /* dismissShade */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDarkAmount(float darkAmount) {
|
public void setDarkAmount(float darkAmount) {
|
||||||
if (darkAmount == mDarkAmount) {
|
if (darkAmount == mDarkAmount) {
|
||||||
return;
|
return;
|
||||||
@@ -627,77 +323,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
dozeTimeTick();
|
dozeTimeTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void launchLeftAffordance() {
|
|
||||||
if (mLeftIsVoiceAssist) {
|
|
||||||
launchVoiceAssist();
|
|
||||||
} else {
|
|
||||||
launchPhone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void launchVoiceAssist() {
|
|
||||||
Runnable runnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Dependency.get(AssistManager.class).launchVoiceAssistFromKeyguard();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!mKeyguardStateController.canDismissLockScreen()) {
|
|
||||||
Dependency.get(Dependency.BACKGROUND_EXECUTOR).execute(runnable);
|
|
||||||
} else {
|
|
||||||
boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
|
|
||||||
&& Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
|
|
||||||
mCentralSurfaces.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
|
|
||||||
dismissShade, false /* afterKeyguardGone */, true /* deferred */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canLaunchVoiceAssist() {
|
|
||||||
return Dependency.get(AssistManager.class).canVoiceAssistBeLaunchedFromKeyguard();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void launchPhone() {
|
|
||||||
final TelecomManager tm = TelecomManager.from(mContext);
|
|
||||||
if (tm.isInCall()) {
|
|
||||||
AsyncTask.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
tm.showInCallScreen(false /* showDialpad */);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
boolean dismissShade = !TextUtils.isEmpty(mLeftButtonStr)
|
|
||||||
&& Dependency.get(TunerService.class).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
|
|
||||||
mActivityStarter.startActivity(mLeftButton.getIntent(), dismissShade);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onVisibilityChanged(View changedView, int visibility) {
|
|
||||||
super.onVisibilityChanged(changedView, visibility);
|
|
||||||
if (changedView == this && visibility == VISIBLE) {
|
|
||||||
updateCameraVisibility();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyguardAffordanceView getLeftView() {
|
|
||||||
return mLeftAffordanceView;
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyguardAffordanceView getRightView() {
|
|
||||||
return mRightAffordanceView;
|
|
||||||
}
|
|
||||||
|
|
||||||
public View getLeftPreview() {
|
|
||||||
return mLeftPreview;
|
|
||||||
}
|
|
||||||
|
|
||||||
public View getRightPreview() {
|
|
||||||
return mCameraPreview;
|
|
||||||
}
|
|
||||||
|
|
||||||
public View getIndicationArea() {
|
public View getIndicationArea() {
|
||||||
return mIndicationArea;
|
return mIndicationArea;
|
||||||
}
|
}
|
||||||
@@ -707,66 +332,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUnlockedChanged() {
|
|
||||||
updateCameraVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onKeyguardShowingChanged() {
|
|
||||||
if (mKeyguardStateController.isShowing()) {
|
|
||||||
if (mQuickAccessWalletController != null) {
|
|
||||||
mQuickAccessWalletController.queryWalletCards(mCardRetriever);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void inflateCameraPreview() {
|
|
||||||
if (mPreviewContainer == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
View previewBefore = mCameraPreview;
|
|
||||||
boolean visibleBefore = false;
|
|
||||||
if (previewBefore != null) {
|
|
||||||
mPreviewContainer.removeView(previewBefore);
|
|
||||||
visibleBefore = previewBefore.getVisibility() == View.VISIBLE;
|
|
||||||
}
|
|
||||||
mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
|
|
||||||
if (mCameraPreview != null) {
|
|
||||||
mPreviewContainer.addView(mCameraPreview);
|
|
||||||
mCameraPreview.setVisibility(visibleBefore ? View.VISIBLE : View.INVISIBLE);
|
|
||||||
}
|
|
||||||
if (mAffordanceHelper != null) {
|
|
||||||
mAffordanceHelper.updatePreviews();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateLeftPreview() {
|
|
||||||
if (mPreviewContainer == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
View previewBefore = mLeftPreview;
|
|
||||||
if (previewBefore != null) {
|
|
||||||
mPreviewContainer.removeView(previewBefore);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mLeftIsVoiceAssist) {
|
|
||||||
if (Dependency.get(AssistManager.class).getVoiceInteractorComponentName() != null) {
|
|
||||||
mLeftPreview = mPreviewInflater.inflatePreviewFromService(
|
|
||||||
Dependency.get(AssistManager.class).getVoiceInteractorComponentName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mLeftPreview = mPreviewInflater.inflatePreview(mLeftButton.getIntent());
|
|
||||||
}
|
|
||||||
if (mLeftPreview != null) {
|
|
||||||
mPreviewContainer.addView(mLeftPreview);
|
|
||||||
mLeftPreview.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
if (mAffordanceHelper != null) {
|
|
||||||
mAffordanceHelper.updatePreviews();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startFinishDozeAnimation() {
|
public void startFinishDozeAnimation() {
|
||||||
long delay = 0;
|
long delay = 0;
|
||||||
if (mWalletButton.getVisibility() == View.VISIBLE) {
|
if (mWalletButton.getVisibility() == View.VISIBLE) {
|
||||||
@@ -778,13 +343,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
if (mControlsButton.getVisibility() == View.VISIBLE) {
|
if (mControlsButton.getVisibility() == View.VISIBLE) {
|
||||||
startFinishDozeAnimationElement(mControlsButton, delay);
|
startFinishDozeAnimationElement(mControlsButton, delay);
|
||||||
}
|
}
|
||||||
if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
|
|
||||||
startFinishDozeAnimationElement(mLeftAffordanceView, delay);
|
|
||||||
delay += DOZE_ANIMATION_STAGGER_DELAY;
|
|
||||||
}
|
|
||||||
if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
|
|
||||||
startFinishDozeAnimationElement(mRightAffordanceView, delay);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startFinishDozeAnimationElement(View element, long delay) {
|
private void startFinishDozeAnimationElement(View element, long delay) {
|
||||||
@@ -798,58 +356,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
.setDuration(DOZE_ANIMATION_ELEMENT_DURATION);
|
.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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
|
|
||||||
new KeyguardUpdateMonitorCallback() {
|
|
||||||
@Override
|
|
||||||
public void onUserSwitchComplete(int userId) {
|
|
||||||
updateCameraVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUserUnlocked() {
|
|
||||||
inflateCameraPreview();
|
|
||||||
updateCameraVisibility();
|
|
||||||
updateLeftAffordance();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void updateLeftAffordance() {
|
|
||||||
updateLeftAffordanceIcon();
|
|
||||||
updateLeftPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setRightButton(IntentButton button) {
|
|
||||||
mRightButton = button;
|
|
||||||
updateRightAffordanceIcon();
|
|
||||||
updateCameraVisibility();
|
|
||||||
inflateCameraPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setLeftButton(IntentButton button) {
|
|
||||||
mLeftButton = button;
|
|
||||||
if (!(mLeftButton instanceof DefaultLeftButton)) {
|
|
||||||
mLeftIsVoiceAssist = false;
|
|
||||||
}
|
|
||||||
updateLeftAffordance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDozing(boolean dozing, boolean animate) {
|
public void setDozing(boolean dozing, boolean animate) {
|
||||||
mDozing = dozing;
|
mDozing = dozing;
|
||||||
|
|
||||||
updateCameraVisibility();
|
|
||||||
updateLeftAffordanceIcon();
|
|
||||||
updateWalletVisibility();
|
updateWalletVisibility();
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateQRCodeButtonVisibility();
|
updateQRCodeButtonVisibility();
|
||||||
@@ -888,77 +397,12 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
* Sets the alpha of the indication areas and affordances, excluding the lock icon.
|
* Sets the alpha of the indication areas and affordances, excluding the lock icon.
|
||||||
*/
|
*/
|
||||||
public void setAffordanceAlpha(float alpha) {
|
public void setAffordanceAlpha(float alpha) {
|
||||||
mLeftAffordanceView.setAlpha(alpha);
|
|
||||||
mRightAffordanceView.setAlpha(alpha);
|
|
||||||
mIndicationArea.setAlpha(alpha);
|
mIndicationArea.setAlpha(alpha);
|
||||||
mWalletButton.setAlpha(alpha);
|
mWalletButton.setAlpha(alpha);
|
||||||
mQRCodeScannerButton.setAlpha(alpha);
|
mQRCodeScannerButton.setAlpha(alpha);
|
||||||
mControlsButton.setAlpha(alpha);
|
mControlsButton.setAlpha(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DefaultLeftButton implements IntentButton {
|
|
||||||
|
|
||||||
private IconState mIconState = new IconState();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IconState getIcon() {
|
|
||||||
mLeftIsVoiceAssist = canLaunchVoiceAssist();
|
|
||||||
if (mLeftIsVoiceAssist) {
|
|
||||||
mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance;
|
|
||||||
if (mLeftAssistIcon == null) {
|
|
||||||
mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
|
|
||||||
} else {
|
|
||||||
mIconState.drawable = mLeftAssistIcon;
|
|
||||||
}
|
|
||||||
mIconState.contentDescription = mContext.getString(
|
|
||||||
R.string.accessibility_voice_assist_button);
|
|
||||||
} else {
|
|
||||||
mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance
|
|
||||||
&& isPhoneVisible();
|
|
||||||
mIconState.drawable = mContext.getDrawable(
|
|
||||||
com.android.internal.R.drawable.ic_phone);
|
|
||||||
mIconState.contentDescription = mContext.getString(
|
|
||||||
R.string.accessibility_phone_button);
|
|
||||||
}
|
|
||||||
return mIconState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Intent getIntent() {
|
|
||||||
return PHONE_INTENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DefaultRightButton implements IntentButton {
|
|
||||||
|
|
||||||
private IconState mIconState = new IconState();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IconState getIcon() {
|
|
||||||
boolean isCameraDisabled = (mCentralSurfaces != null)
|
|
||||||
&& !mCentralSurfaces.isCameraAllowedByAdmin();
|
|
||||||
mIconState.isVisible = !isCameraDisabled
|
|
||||||
&& mShowCameraAffordance
|
|
||||||
&& mUserSetupComplete
|
|
||||||
&& resolveCameraIntent() != null;
|
|
||||||
mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
|
|
||||||
mIconState.contentDescription =
|
|
||||||
mContext.getString(R.string.accessibility_camera_button);
|
|
||||||
return mIconState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Intent getIntent() {
|
|
||||||
boolean canDismissLs = mKeyguardStateController.canDismissLockScreen();
|
|
||||||
boolean secure = mKeyguardStateController.isMethodSecure();
|
|
||||||
if (secure && !canDismissLs) {
|
|
||||||
return CameraIntents.getSecureCameraIntent(getContext());
|
|
||||||
} else {
|
|
||||||
return CameraIntents.getInsecureCameraIntent(getContext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
||||||
int bottom = insets.getDisplayCutout() != null
|
int bottom = insets.getDisplayCutout() != null
|
||||||
|
|||||||
@@ -50,8 +50,6 @@ import android.app.ActivityManager;
|
|||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.StatusBarManager;
|
import android.app.StatusBarManager;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
@@ -117,6 +115,7 @@ import com.android.systemui.animation.ActivityLaunchAnimator;
|
|||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.animation.LaunchAnimator;
|
import com.android.systemui.animation.LaunchAnimator;
|
||||||
import com.android.systemui.biometrics.AuthController;
|
import com.android.systemui.biometrics.AuthController;
|
||||||
|
import com.android.systemui.camera.CameraGestureHelper;
|
||||||
import com.android.systemui.classifier.Classifier;
|
import com.android.systemui.classifier.Classifier;
|
||||||
import com.android.systemui.classifier.FalsingCollector;
|
import com.android.systemui.classifier.FalsingCollector;
|
||||||
import com.android.systemui.controls.dagger.ControlsComponent;
|
import com.android.systemui.controls.dagger.ControlsComponent;
|
||||||
@@ -145,7 +144,6 @@ import com.android.systemui.screenrecord.RecordingController;
|
|||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.GestureRecorder;
|
import com.android.systemui.statusbar.GestureRecorder;
|
||||||
import com.android.systemui.statusbar.KeyguardAffordanceView;
|
|
||||||
import com.android.systemui.statusbar.KeyguardIndicationController;
|
import com.android.systemui.statusbar.KeyguardIndicationController;
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
@@ -252,9 +250,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
private final OnOverscrollTopChangedListener
|
private final OnOverscrollTopChangedListener
|
||||||
mOnOverscrollTopChangedListener =
|
mOnOverscrollTopChangedListener =
|
||||||
new OnOverscrollTopChangedListener();
|
new OnOverscrollTopChangedListener();
|
||||||
private final KeyguardAffordanceHelperCallback
|
|
||||||
mKeyguardAffordanceHelperCallback =
|
|
||||||
new KeyguardAffordanceHelperCallback();
|
|
||||||
private final OnEmptySpaceClickListener
|
private final OnEmptySpaceClickListener
|
||||||
mOnEmptySpaceClickListener =
|
mOnEmptySpaceClickListener =
|
||||||
new OnEmptySpaceClickListener();
|
new OnEmptySpaceClickListener();
|
||||||
@@ -338,8 +333,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
// Current max allowed keyguard notifications determined by measuring the panel
|
// Current max allowed keyguard notifications determined by measuring the panel
|
||||||
private int mMaxAllowedKeyguardNotifications;
|
private int mMaxAllowedKeyguardNotifications;
|
||||||
|
|
||||||
private ViewGroup mPreviewContainer;
|
|
||||||
private KeyguardAffordanceHelper mAffordanceHelper;
|
|
||||||
private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
|
private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
|
||||||
private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
|
private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
|
||||||
private KeyguardStatusBarView mKeyguardStatusBar;
|
private KeyguardStatusBarView mKeyguardStatusBar;
|
||||||
@@ -437,8 +430,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
*/
|
*/
|
||||||
private boolean mQsAnimatorExpand;
|
private boolean mQsAnimatorExpand;
|
||||||
private boolean mIsLaunchTransitionFinished;
|
private boolean mIsLaunchTransitionFinished;
|
||||||
private boolean mIsLaunchTransitionRunning;
|
|
||||||
private Runnable mLaunchAnimationEndRunnable;
|
|
||||||
private boolean mOnlyAffordanceInThisMotion;
|
private boolean mOnlyAffordanceInThisMotion;
|
||||||
private ValueAnimator mQsSizeChangeAnimator;
|
private ValueAnimator mQsSizeChangeAnimator;
|
||||||
|
|
||||||
@@ -455,10 +446,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
private boolean mClosingWithAlphaFadeOut;
|
private boolean mClosingWithAlphaFadeOut;
|
||||||
private boolean mHeadsUpAnimatingAway;
|
private boolean mHeadsUpAnimatingAway;
|
||||||
private boolean mLaunchingAffordance;
|
private boolean mLaunchingAffordance;
|
||||||
private boolean mAffordanceHasPreview;
|
|
||||||
private final FalsingManager mFalsingManager;
|
private final FalsingManager mFalsingManager;
|
||||||
private final FalsingCollector mFalsingCollector;
|
private final FalsingCollector mFalsingCollector;
|
||||||
private String mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
|
|
||||||
|
|
||||||
private Runnable mHeadsUpExistenceChangedRunnable = () -> {
|
private Runnable mHeadsUpExistenceChangedRunnable = () -> {
|
||||||
setHeadsUpAnimatingAway(false);
|
setHeadsUpAnimatingAway(false);
|
||||||
@@ -491,7 +480,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
private float mLinearDarkAmount;
|
private float mLinearDarkAmount;
|
||||||
|
|
||||||
private boolean mPulsing;
|
private boolean mPulsing;
|
||||||
private boolean mUserSetupComplete;
|
|
||||||
private boolean mHideIconsDuringLaunchAnimation = true;
|
private boolean mHideIconsDuringLaunchAnimation = true;
|
||||||
private int mStackScrollerMeasuringPass;
|
private int mStackScrollerMeasuringPass;
|
||||||
/**
|
/**
|
||||||
@@ -707,6 +695,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final CameraGestureHelper mCameraGestureHelper;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public NotificationPanelViewController(NotificationPanelView view,
|
public NotificationPanelViewController(NotificationPanelView view,
|
||||||
@Main Resources resources,
|
@Main Resources resources,
|
||||||
@@ -777,7 +767,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
NotificationStackSizeCalculator notificationStackSizeCalculator,
|
NotificationStackSizeCalculator notificationStackSizeCalculator,
|
||||||
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
|
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
|
||||||
ShadeTransitionController shadeTransitionController,
|
ShadeTransitionController shadeTransitionController,
|
||||||
SystemClock systemClock) {
|
SystemClock systemClock,
|
||||||
|
CameraGestureHelper cameraGestureHelper) {
|
||||||
super(view,
|
super(view,
|
||||||
falsingManager,
|
falsingManager,
|
||||||
dozeLog,
|
dozeLog,
|
||||||
@@ -961,6 +952,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
mCameraGestureHelper = cameraGestureHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -1008,8 +1000,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mOnEmptySpaceClickListener);
|
mOnEmptySpaceClickListener);
|
||||||
addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp);
|
addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp);
|
||||||
mKeyguardBottomArea = mView.findViewById(R.id.keyguard_bottom_area);
|
mKeyguardBottomArea = mView.findViewById(R.id.keyguard_bottom_area);
|
||||||
mPreviewContainer = mView.findViewById(R.id.preview_container);
|
|
||||||
mKeyguardBottomArea.setPreviewContainer(mPreviewContainer);
|
|
||||||
|
|
||||||
initBottomArea();
|
initBottomArea();
|
||||||
|
|
||||||
@@ -1033,7 +1023,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
|
|
||||||
mView.setRtlChangeListener(layoutDirection -> {
|
mView.setRtlChangeListener(layoutDirection -> {
|
||||||
if (layoutDirection != mOldLayoutDirection) {
|
if (layoutDirection != mOldLayoutDirection) {
|
||||||
mAffordanceHelper.onRtlPropertiesChanged();
|
|
||||||
mOldLayoutDirection = layoutDirection;
|
mOldLayoutDirection = layoutDirection;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1267,7 +1256,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mKeyguardBottomArea = (KeyguardBottomAreaView) mLayoutInflater.inflate(
|
mKeyguardBottomArea = (KeyguardBottomAreaView) mLayoutInflater.inflate(
|
||||||
R.layout.keyguard_bottom_area, mView, false);
|
R.layout.keyguard_bottom_area, mView, false);
|
||||||
mKeyguardBottomArea.initFrom(oldBottomArea);
|
mKeyguardBottomArea.initFrom(oldBottomArea);
|
||||||
mKeyguardBottomArea.setPreviewContainer(mPreviewContainer);
|
|
||||||
mView.addView(mKeyguardBottomArea, index);
|
mView.addView(mKeyguardBottomArea, index);
|
||||||
initBottomArea();
|
initBottomArea();
|
||||||
mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea);
|
mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea);
|
||||||
@@ -1304,11 +1292,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initBottomArea() {
|
private void initBottomArea() {
|
||||||
mAffordanceHelper = new KeyguardAffordanceHelper(
|
|
||||||
mKeyguardAffordanceHelperCallback, mView.getContext(), mFalsingManager);
|
|
||||||
mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
|
|
||||||
mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces);
|
mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces);
|
||||||
mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
|
|
||||||
mKeyguardBottomArea.setFalsingManager(mFalsingManager);
|
mKeyguardBottomArea.setFalsingManager(mFalsingManager);
|
||||||
mKeyguardBottomArea.initWallet(mQuickAccessWalletController);
|
mKeyguardBottomArea.initWallet(mQuickAccessWalletController);
|
||||||
mKeyguardBottomArea.initControls(mControlsComponent);
|
mKeyguardBottomArea.initControls(mControlsComponent);
|
||||||
@@ -1673,10 +1657,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
public void resetViews(boolean animate) {
|
public void resetViews(boolean animate) {
|
||||||
mIsLaunchTransitionFinished = false;
|
mIsLaunchTransitionFinished = false;
|
||||||
mBlockTouches = false;
|
mBlockTouches = false;
|
||||||
if (!mLaunchingAffordance) {
|
|
||||||
mAffordanceHelper.reset(false);
|
|
||||||
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
|
|
||||||
}
|
|
||||||
mCentralSurfaces.getGutsManager().closeAndSaveGuts(true /* leavebehind */, true /* force */,
|
mCentralSurfaces.getGutsManager().closeAndSaveGuts(true /* leavebehind */, true /* force */,
|
||||||
true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
|
true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
|
||||||
if (animate && !isFullyCollapsed()) {
|
if (animate && !isFullyCollapsed()) {
|
||||||
@@ -2219,11 +2199,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
return isFullyCollapsed() || mBarState != StatusBarState.SHADE;
|
return isFullyCollapsed() || mBarState != StatusBarState.SHADE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldGestureIgnoreXTouchSlop(float x, float y) {
|
|
||||||
return !mAffordanceHelper.isOnAffordanceIcon(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onQsTouch(MotionEvent event) {
|
private void onQsTouch(MotionEvent event) {
|
||||||
int pointerIndex = event.findPointerIndex(mTrackingPointer);
|
int pointerIndex = event.findPointerIndex(mTrackingPointer);
|
||||||
if (pointerIndex < 0) {
|
if (pointerIndex < 0) {
|
||||||
@@ -3388,9 +3363,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mQsExpandImmediate = true;
|
mQsExpandImmediate = true;
|
||||||
setShowShelfOnly(true);
|
setShowShelfOnly(true);
|
||||||
}
|
}
|
||||||
if (mBarState == KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
|
|
||||||
mAffordanceHelper.animateHideLeftRightIcon();
|
|
||||||
}
|
|
||||||
mNotificationStackScrollLayoutController.onPanelTrackingStarted();
|
mNotificationStackScrollLayoutController.onPanelTrackingStarted();
|
||||||
cancelPendingPanelCollapse();
|
cancelPendingPanelCollapse();
|
||||||
}
|
}
|
||||||
@@ -3404,12 +3376,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
true /* animate */);
|
true /* animate */);
|
||||||
}
|
}
|
||||||
mNotificationStackScrollLayoutController.onPanelTrackingStopped();
|
mNotificationStackScrollLayoutController.onPanelTrackingStopped();
|
||||||
if (expand && (mBarState == KEYGUARD
|
|
||||||
|| mBarState == StatusBarState.SHADE_LOCKED)) {
|
|
||||||
if (!mHintAnimationRunning) {
|
|
||||||
mAffordanceHelper.reset(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we unlocked from a swipe, the user's finger might still be down after the
|
// If we unlocked from a swipe, the user's finger might still be down after the
|
||||||
// unlock animation ends. We need to wait until ACTION_UP to enable blurs again.
|
// unlock animation ends. We need to wait until ACTION_UP to enable blurs again.
|
||||||
@@ -3482,10 +3448,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
return mIsLaunchTransitionFinished;
|
return mIsLaunchTransitionFinished;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLaunchTransitionRunning() {
|
|
||||||
return mIsLaunchTransitionRunning;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIsLaunchAnimationRunning(boolean running) {
|
public void setIsLaunchAnimationRunning(boolean running) {
|
||||||
boolean wasRunning = mIsLaunchAnimationRunning;
|
boolean wasRunning = mIsLaunchAnimationRunning;
|
||||||
@@ -3504,10 +3466,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLaunchTransitionEndRunnable(Runnable r) {
|
|
||||||
mLaunchAnimationEndRunnable = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDozingVisibilities(boolean animate) {
|
private void updateDozingVisibilities(boolean animate) {
|
||||||
mKeyguardBottomArea.setDozing(mDozing, animate);
|
mKeyguardBottomArea.setDozing(mDozing, animate);
|
||||||
if (!mDozing && animate) {
|
if (!mDozing && animate) {
|
||||||
@@ -3686,30 +3644,13 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
&& mBarState == StatusBarState.SHADE;
|
&& mBarState == StatusBarState.SHADE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void launchCamera(boolean animate, int source) {
|
/** Launches the camera. */
|
||||||
if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
|
public void launchCamera(int source) {
|
||||||
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP;
|
|
||||||
} else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) {
|
|
||||||
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE;
|
|
||||||
} else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) {
|
|
||||||
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Default.
|
|
||||||
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are launching it when we are occluded already we don't want it to animate,
|
|
||||||
// nor setting these flags, since the occluded state doesn't change anymore, hence it's
|
|
||||||
// never reset.
|
|
||||||
if (!isFullyCollapsed()) {
|
if (!isFullyCollapsed()) {
|
||||||
setLaunchingAffordance(true);
|
setLaunchingAffordance(true);
|
||||||
} else {
|
|
||||||
animate = false;
|
|
||||||
}
|
}
|
||||||
mAffordanceHasPreview = mKeyguardBottomArea.getRightPreview() != null;
|
|
||||||
mAffordanceHelper.launchAffordance(
|
mCameraGestureHelper.launchCamera(source);
|
||||||
animate, mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAffordanceLaunchEnded() {
|
public void onAffordanceLaunchEnded() {
|
||||||
@@ -3722,9 +3663,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
*/
|
*/
|
||||||
private void setLaunchingAffordance(boolean launchingAffordance) {
|
private void setLaunchingAffordance(boolean launchingAffordance) {
|
||||||
mLaunchingAffordance = launchingAffordance;
|
mLaunchingAffordance = launchingAffordance;
|
||||||
mKeyguardAffordanceHelperCallback.getLeftIcon().setLaunchingAffordance(launchingAffordance);
|
|
||||||
mKeyguardAffordanceHelperCallback.getRightIcon().setLaunchingAffordance(
|
|
||||||
launchingAffordance);
|
|
||||||
mKeyguardBypassController.setLaunchingAffordance(launchingAffordance);
|
mKeyguardBypassController.setLaunchingAffordance(launchingAffordance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3732,34 +3670,14 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
* Return true when a bottom affordance is launching an occluded activity with a splash screen.
|
* Return true when a bottom affordance is launching an occluded activity with a splash screen.
|
||||||
*/
|
*/
|
||||||
public boolean isLaunchingAffordanceWithPreview() {
|
public boolean isLaunchingAffordanceWithPreview() {
|
||||||
return mLaunchingAffordance && mAffordanceHasPreview;
|
return mLaunchingAffordance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the camera application can be launched for the camera launch gesture.
|
* Whether the camera application can be launched for the camera launch gesture.
|
||||||
*/
|
*/
|
||||||
public boolean canCameraGestureBeLaunched() {
|
public boolean canCameraGestureBeLaunched() {
|
||||||
if (!mCentralSurfaces.isCameraAllowedByAdmin()) {
|
return mCameraGestureHelper.canCameraGestureBeLaunched(mBarState);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent();
|
|
||||||
String
|
|
||||||
packageToLaunch =
|
|
||||||
(resolveInfo == null || resolveInfo.activityInfo == null) ? null
|
|
||||||
: resolveInfo.activityInfo.packageName;
|
|
||||||
return packageToLaunch != null && (mBarState != StatusBarState.SHADE || !isForegroundApp(
|
|
||||||
packageToLaunch)) && !mAffordanceHelper.isSwipingInProgress();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if the applications with the package name is running in foreground.
|
|
||||||
*
|
|
||||||
* @param pkgName application package name.
|
|
||||||
*/
|
|
||||||
private boolean isForegroundApp(String pkgName) {
|
|
||||||
List<ActivityManager.RunningTaskInfo> tasks = mActivityManager.getRunningTasks(1);
|
|
||||||
return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hideStatusBarIconsWhenExpanded() {
|
public boolean hideStatusBarIconsWhenExpanded() {
|
||||||
@@ -3838,9 +3756,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
@Override
|
@Override
|
||||||
public void setTouchAndAnimationDisabled(boolean disabled) {
|
public void setTouchAndAnimationDisabled(boolean disabled) {
|
||||||
super.setTouchAndAnimationDisabled(disabled);
|
super.setTouchAndAnimationDisabled(disabled);
|
||||||
if (disabled && mAffordanceHelper.isSwipingInProgress() && !mIsLaunchTransitionRunning) {
|
|
||||||
mAffordanceHelper.reset(false /* animate */);
|
|
||||||
}
|
|
||||||
mNotificationStackScrollLayoutController.setAnimationsEnabled(!disabled);
|
mNotificationStackScrollLayoutController.setAnimationsEnabled(!disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3923,11 +3838,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
return mKeyguardBottomArea;
|
return mKeyguardBottomArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserSetupComplete(boolean userSetupComplete) {
|
|
||||||
mUserSetupComplete = userSetupComplete;
|
|
||||||
mKeyguardBottomArea.setUserSetupComplete(userSetupComplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyLaunchAnimationProgress(float linearProgress) {
|
public void applyLaunchAnimationProgress(float linearProgress) {
|
||||||
boolean hideIcons = LaunchAnimator.getProgress(ActivityLaunchAnimator.TIMINGS,
|
boolean hideIcons = LaunchAnimator.getProgress(ActivityLaunchAnimator.TIMINGS,
|
||||||
linearProgress, ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
|
linearProgress, ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
|
||||||
@@ -4281,10 +4191,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mMetricsLogger.count(COUNTER_PANEL_OPEN_PEEK, 1);
|
mMetricsLogger.count(COUNTER_PANEL_OPEN_PEEK, 1);
|
||||||
}
|
}
|
||||||
boolean handled = false;
|
boolean handled = false;
|
||||||
if ((!mIsExpanding || mHintAnimationRunning) && !mQsExpanded
|
|
||||||
&& mBarState != StatusBarState.SHADE && !mDozing) {
|
|
||||||
handled |= mAffordanceHelper.onTouchEvent(event);
|
|
||||||
}
|
|
||||||
if (mOnlyAffordanceInThisMotion) {
|
if (mOnlyAffordanceInThisMotion) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4527,139 +4433,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KeyguardAffordanceHelperCallback implements KeyguardAffordanceHelper.Callback {
|
|
||||||
@Override
|
|
||||||
public void onAnimationToSideStarted(boolean rightPage, float translation, float vel) {
|
|
||||||
boolean
|
|
||||||
start =
|
|
||||||
mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? rightPage
|
|
||||||
: !rightPage;
|
|
||||||
mIsLaunchTransitionRunning = true;
|
|
||||||
mLaunchAnimationEndRunnable = null;
|
|
||||||
float displayDensity = mCentralSurfaces.getDisplayDensity();
|
|
||||||
int lengthDp = Math.abs((int) (translation / displayDensity));
|
|
||||||
int velocityDp = Math.abs((int) (vel / displayDensity));
|
|
||||||
if (start) {
|
|
||||||
mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_DIALER, lengthDp, velocityDp);
|
|
||||||
mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_DIALER);
|
|
||||||
mFalsingCollector.onLeftAffordanceOn();
|
|
||||||
if (mFalsingCollector.shouldEnforceBouncer()) {
|
|
||||||
mCentralSurfaces.executeRunnableDismissingKeyguard(
|
|
||||||
() -> mKeyguardBottomArea.launchLeftAffordance(), null,
|
|
||||||
true /* dismissShade */, false /* afterKeyguardGone */,
|
|
||||||
true /* deferred */);
|
|
||||||
} else {
|
|
||||||
mKeyguardBottomArea.launchLeftAffordance();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE.equals(
|
|
||||||
mLastCameraLaunchSource)) {
|
|
||||||
mLockscreenGestureLogger.write(
|
|
||||||
MetricsEvent.ACTION_LS_CAMERA, lengthDp, velocityDp);
|
|
||||||
mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_CAMERA);
|
|
||||||
}
|
|
||||||
mFalsingCollector.onCameraOn();
|
|
||||||
if (mFalsingCollector.shouldEnforceBouncer()) {
|
|
||||||
mCentralSurfaces.executeRunnableDismissingKeyguard(
|
|
||||||
() -> mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource), null,
|
|
||||||
true /* dismissShade */, false /* afterKeyguardGone */,
|
|
||||||
true /* deferred */);
|
|
||||||
} else {
|
|
||||||
mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mCentralSurfaces.startLaunchTransitionTimeout();
|
|
||||||
mBlockTouches = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationToSideEnded() {
|
|
||||||
mIsLaunchTransitionRunning = false;
|
|
||||||
mIsLaunchTransitionFinished = true;
|
|
||||||
if (mLaunchAnimationEndRunnable != null) {
|
|
||||||
mLaunchAnimationEndRunnable.run();
|
|
||||||
mLaunchAnimationEndRunnable = null;
|
|
||||||
}
|
|
||||||
mCentralSurfaces.readyForKeyguardDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getMaxTranslationDistance() {
|
|
||||||
return (float) Math.hypot(mView.getWidth(), getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSwipingStarted(boolean rightIcon) {
|
|
||||||
mFalsingCollector.onAffordanceSwipingStarted(rightIcon);
|
|
||||||
mView.requestDisallowInterceptTouchEvent(true);
|
|
||||||
mOnlyAffordanceInThisMotion = true;
|
|
||||||
mQsTracking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSwipingAborted() {
|
|
||||||
mFalsingCollector.onAffordanceSwipingAborted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onIconClicked(boolean rightIcon) {
|
|
||||||
if (mHintAnimationRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mHintAnimationRunning = true;
|
|
||||||
mAffordanceHelper.startHintAnimation(rightIcon, () -> {
|
|
||||||
mHintAnimationRunning = false;
|
|
||||||
mCentralSurfaces.onHintFinished();
|
|
||||||
});
|
|
||||||
rightIcon =
|
|
||||||
mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? !rightIcon
|
|
||||||
: rightIcon;
|
|
||||||
if (rightIcon) {
|
|
||||||
mCentralSurfaces.onCameraHintStarted();
|
|
||||||
} else {
|
|
||||||
if (mKeyguardBottomArea.isLeftVoiceAssist()) {
|
|
||||||
mCentralSurfaces.onVoiceAssistHintStarted();
|
|
||||||
} else {
|
|
||||||
mCentralSurfaces.onPhoneHintStarted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public KeyguardAffordanceView getLeftIcon() {
|
|
||||||
return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
|
|
||||||
? mKeyguardBottomArea.getRightView() : mKeyguardBottomArea.getLeftView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public KeyguardAffordanceView getRightIcon() {
|
|
||||||
return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
|
|
||||||
? mKeyguardBottomArea.getLeftView() : mKeyguardBottomArea.getRightView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getLeftPreview() {
|
|
||||||
return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
|
|
||||||
? mKeyguardBottomArea.getRightPreview() : mKeyguardBottomArea.getLeftPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getRightPreview() {
|
|
||||||
return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
|
|
||||||
? mKeyguardBottomArea.getLeftPreview() : mKeyguardBottomArea.getRightPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getAffordanceFalsingFactor() {
|
|
||||||
return mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean needsAntiFalsing() {
|
|
||||||
return mBarState == KEYGUARD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class OnEmptySpaceClickListener implements
|
private class OnEmptySpaceClickListener implements
|
||||||
NotificationStackScrollLayout.OnEmptySpaceClickListener {
|
NotificationStackScrollLayout.OnEmptySpaceClickListener {
|
||||||
@Override
|
@Override
|
||||||
@@ -5118,15 +4891,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OnConfigurationChangedListener extends
|
|
||||||
PanelViewController.OnConfigurationChangedListener {
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged(Configuration newConfig) {
|
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
mAffordanceHelper.onConfigurationChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class OnApplyWindowInsetsListener implements View.OnApplyWindowInsetsListener {
|
private class OnApplyWindowInsetsListener implements View.OnApplyWindowInsetsListener {
|
||||||
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
|
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
|
||||||
// the same types of insets that are handled in NotificationShadeWindowView
|
// the same types of insets that are handled in NotificationShadeWindowView
|
||||||
|
|||||||
@@ -484,8 +484,6 @@ public abstract class PanelViewController {
|
|||||||
|
|
||||||
protected abstract boolean shouldGestureWaitForTouchSlop();
|
protected abstract boolean shouldGestureWaitForTouchSlop();
|
||||||
|
|
||||||
protected abstract boolean shouldGestureIgnoreXTouchSlop(float x, float y);
|
|
||||||
|
|
||||||
protected void onTrackingStopped(boolean expand) {
|
protected void onTrackingStopped(boolean expand) {
|
||||||
mTracking = false;
|
mTracking = false;
|
||||||
mCentralSurfaces.onTrackingStopped(expand);
|
mCentralSurfaces.onTrackingStopped(expand);
|
||||||
@@ -1333,7 +1331,7 @@ public abstract class PanelViewController {
|
|||||||
|
|
||||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||||
mGestureWaitForTouchSlop = shouldGestureWaitForTouchSlop();
|
mGestureWaitForTouchSlop = shouldGestureWaitForTouchSlop();
|
||||||
mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
|
mIgnoreXTouchSlop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (event.getActionMasked()) {
|
switch (event.getActionMasked()) {
|
||||||
|
|||||||
@@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.systemui.statusbar.policy;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
|
||||||
import com.android.systemui.ActivityIntentHelper;
|
|
||||||
import com.android.systemui.statusbar.phone.KeyguardPreviewContainer;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class to inflate previews for phone and camera affordance.
|
|
||||||
*/
|
|
||||||
public class PreviewInflater {
|
|
||||||
|
|
||||||
private static final String TAG = "PreviewInflater";
|
|
||||||
|
|
||||||
private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout";
|
|
||||||
private final ActivityIntentHelper mActivityIntentHelper;
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private LockPatternUtils mLockPatternUtils;
|
|
||||||
|
|
||||||
public PreviewInflater(Context context, LockPatternUtils lockPatternUtils,
|
|
||||||
ActivityIntentHelper activityIntentHelper) {
|
|
||||||
mContext = context;
|
|
||||||
mLockPatternUtils = lockPatternUtils;
|
|
||||||
mActivityIntentHelper = activityIntentHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public View inflatePreview(Intent intent) {
|
|
||||||
WidgetInfo info = getWidgetInfo(intent);
|
|
||||||
return inflatePreview(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
public View inflatePreviewFromService(ComponentName componentName) {
|
|
||||||
WidgetInfo info = getWidgetInfoFromService(componentName);
|
|
||||||
return inflatePreview(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private KeyguardPreviewContainer inflatePreview(WidgetInfo info) {
|
|
||||||
if (info == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
View v = inflateWidgetView(info);
|
|
||||||
if (v == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
KeyguardPreviewContainer container = new KeyguardPreviewContainer(mContext, null);
|
|
||||||
container.addView(v);
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
private View inflateWidgetView(WidgetInfo widgetInfo) {
|
|
||||||
View widgetView = null;
|
|
||||||
try {
|
|
||||||
Context appContext = mContext.createPackageContext(
|
|
||||||
widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED);
|
|
||||||
LayoutInflater appInflater = (LayoutInflater)
|
|
||||||
appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
appInflater = appInflater.cloneInContext(appContext);
|
|
||||||
widgetView = appInflater.inflate(widgetInfo.layoutId, null, false);
|
|
||||||
} catch (PackageManager.NameNotFoundException|RuntimeException e) {
|
|
||||||
Log.w(TAG, "Error creating widget view", e);
|
|
||||||
}
|
|
||||||
return widgetView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private WidgetInfo getWidgetInfoFromService(ComponentName componentName) {
|
|
||||||
PackageManager packageManager = mContext.getPackageManager();
|
|
||||||
// Look for the preview specified in the service meta-data
|
|
||||||
try {
|
|
||||||
Bundle metaData = packageManager.getServiceInfo(
|
|
||||||
componentName, PackageManager.GET_META_DATA).metaData;
|
|
||||||
return getWidgetInfoFromMetaData(componentName.getPackageName(), metaData);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
Log.w(TAG, "Failed to load preview; " + componentName.flattenToShortString()
|
|
||||||
+ " not found", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private WidgetInfo getWidgetInfoFromMetaData(String contextPackage,
|
|
||||||
Bundle metaData) {
|
|
||||||
if (metaData == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int layoutId = metaData.getInt(META_DATA_KEYGUARD_LAYOUT);
|
|
||||||
if (layoutId == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
WidgetInfo info = new WidgetInfo();
|
|
||||||
info.contextPackage = contextPackage;
|
|
||||||
info.layoutId = layoutId;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
private WidgetInfo getWidgetInfo(Intent intent) {
|
|
||||||
PackageManager packageManager = mContext.getPackageManager();
|
|
||||||
int flags = PackageManager.MATCH_DEFAULT_ONLY
|
|
||||||
| PackageManager.MATCH_DIRECT_BOOT_AWARE
|
|
||||||
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
|
|
||||||
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
|
|
||||||
intent, flags, KeyguardUpdateMonitor.getCurrentUser());
|
|
||||||
if (appList.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
|
|
||||||
flags | PackageManager.GET_META_DATA,
|
|
||||||
KeyguardUpdateMonitor.getCurrentUser());
|
|
||||||
if (mActivityIntentHelper.wouldLaunchResolverActivity(resolved, appList)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (resolved == null || resolved.activityInfo == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getWidgetInfoFromMetaData(resolved.activityInfo.packageName,
|
|
||||||
resolved.activityInfo.metaData);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class WidgetInfo {
|
|
||||||
String contextPackage;
|
|
||||||
int layoutId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -848,7 +848,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
mCentralSurfaces.showKeyguardImpl();
|
mCentralSurfaces.showKeyguardImpl();
|
||||||
|
|
||||||
// Starting a pulse should change the scrim controller to the pulsing state
|
// Starting a pulse should change the scrim controller to the pulsing state
|
||||||
when(mNotificationPanelViewController.isLaunchTransitionRunning()).thenReturn(true);
|
|
||||||
when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(true);
|
when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(true);
|
||||||
mCentralSurfaces.updateScrimController();
|
mCentralSurfaces.updateScrimController();
|
||||||
verify(mScrimController).transitionTo(eq(ScrimState.UNLOCKED), any());
|
verify(mScrimController).transitionTo(eq(ScrimState.UNLOCKED), any());
|
||||||
@@ -885,7 +884,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
mCentralSurfaces.showKeyguardImpl();
|
mCentralSurfaces.showKeyguardImpl();
|
||||||
|
|
||||||
// Starting a pulse should change the scrim controller to the pulsing state
|
// Starting a pulse should change the scrim controller to the pulsing state
|
||||||
when(mNotificationPanelViewController.isLaunchTransitionRunning()).thenReturn(true);
|
|
||||||
when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(false);
|
when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(false);
|
||||||
mCentralSurfaces.updateScrimController();
|
mCentralSurfaces.updateScrimController();
|
||||||
verify(mScrimController).transitionTo(eq(ScrimState.KEYGUARD));
|
verify(mScrimController).transitionTo(eq(ScrimState.KEYGUARD));
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import com.android.systemui.statusbar.policy.AccessibilityController
|
|||||||
import com.android.systemui.statusbar.policy.FlashlightController
|
import com.android.systemui.statusbar.policy.FlashlightController
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.tuner.TunerService
|
import com.android.systemui.tuner.TunerService
|
||||||
|
import java.util.concurrent.Executor
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
import java.util.concurrent.Executor
|
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -51,6 +51,5 @@ class KeyguardBottomAreaTest : SysuiTestCase() {
|
|||||||
null, false) as KeyguardBottomAreaView
|
null, false) as KeyguardBottomAreaView
|
||||||
|
|
||||||
other.initFrom(mKeyguardBottomArea)
|
other.initFrom(mKeyguardBottomArea)
|
||||||
other.launchVoiceAssist()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ import com.android.systemui.DejankUtils;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.biometrics.AuthController;
|
import com.android.systemui.biometrics.AuthController;
|
||||||
|
import com.android.systemui.camera.CameraGestureHelper;
|
||||||
import com.android.systemui.classifier.FalsingCollectorFake;
|
import com.android.systemui.classifier.FalsingCollectorFake;
|
||||||
import com.android.systemui.classifier.FalsingManagerFake;
|
import com.android.systemui.classifier.FalsingManagerFake;
|
||||||
import com.android.systemui.controls.dagger.ControlsComponent;
|
import com.android.systemui.controls.dagger.ControlsComponent;
|
||||||
@@ -106,7 +107,6 @@ import com.android.systemui.plugins.qs.QS;
|
|||||||
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
|
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
|
||||||
import com.android.systemui.screenrecord.RecordingController;
|
import com.android.systemui.screenrecord.RecordingController;
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.KeyguardAffordanceView;
|
|
||||||
import com.android.systemui.statusbar.KeyguardIndicationController;
|
import com.android.systemui.statusbar.KeyguardIndicationController;
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
@@ -401,8 +401,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
|
when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
|
||||||
.thenReturn(mHeadsUpCallback);
|
.thenReturn(mHeadsUpCallback);
|
||||||
when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
|
when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
|
||||||
when(mKeyguardBottomArea.getLeftView()).thenReturn(mock(KeyguardAffordanceView.class));
|
|
||||||
when(mKeyguardBottomArea.getRightView()).thenReturn(mock(KeyguardAffordanceView.class));
|
|
||||||
when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class));
|
when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class));
|
||||||
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
|
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
|
||||||
when(mView.findViewById(R.id.keyguard_status_view))
|
when(mView.findViewById(R.id.keyguard_status_view))
|
||||||
@@ -544,7 +542,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
mNotificationStackSizeCalculator,
|
mNotificationStackSizeCalculator,
|
||||||
mUnlockedScreenOffAnimationController,
|
mUnlockedScreenOffAnimationController,
|
||||||
mShadeTransitionController,
|
mShadeTransitionController,
|
||||||
mSystemClock);
|
mSystemClock,
|
||||||
|
mock(CameraGestureHelper.class));
|
||||||
mNotificationPanelViewController.initDependencies(
|
mNotificationPanelViewController.initDependencies(
|
||||||
mCentralSurfaces,
|
mCentralSurfaces,
|
||||||
() -> {},
|
() -> {},
|
||||||
|
|||||||
Reference in New Issue
Block a user