Skip to content

Commit e281e53

Browse files
Dil3mm4luk1337
authored andcommitted
SystemUI: Handle cases that we can't address within FODCircleView
So, briefly, what went on in this pow-wow is: - created a callback to efficiently monitor calls to FODCircleView impl (LuK1337 had a lot of patience) - addressed FOD visibility on statusbar expansion/collapse checking top activity package name and class within StatusBar.java - addressed FOD visibility if an app gets launched after statusbar expansion from a notif - addressed FOD visibility over every launcher animation, where every stands for: back to home, open recents, back gesture, assistant gesture (tested against any navigation type available) - reduced animation time to 125ms Change-Id: I407d7dff6398bc7c6ecc4bfda7b9cb31af90bfd4
1 parent e44a64e commit e281e53

10 files changed

Lines changed: 185 additions & 8 deletions

File tree

data/etc/com.android.systemui.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<permission name="android.permission.GET_APP_OPS_STATS"/>
3131
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
3232
<permission name="android.permission.MANAGE_DEBUGGING"/>
33+
<permission name="android.permission.MANAGE_FINGERPRINT" />
3334
<permission name="android.permission.MANAGE_SENSOR_PRIVACY"/>
3435
<permission name="android.permission.MANAGE_USB"/>
3536
<permission name="android.permission.MANAGE_USERS"/>

packages/SystemUI/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
138138
<uses-permission android:name="android.permission.RESET_FINGERPRINT_LOCKOUT" />
139139
<uses-permission android:name="android.permission.MANAGE_BIOMETRIC" />
140+
<uses-permission android:name="android.permission.MANAGE_FINGERPRINT" />
140141
<uses-permission android:name="android.permission.MANAGE_SLICE_PERMISSIONS" />
141142
<uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
142143
<uses-permission android:name="android.permission.GET_RUNTIME_PERMISSIONS" />

packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
import java.util.TimerTask;
5454

5555
public class FODCircleView extends ImageView {
56-
private static final int FADE_ANIM_DURATION = 250;
56+
private static final int FADE_ANIM_DURATION = 125;
5757

5858
private final int mPositionX;
5959
private final int mPositionY;

packages/SystemUI/src/com/android/systemui/biometrics/FODCircleViewImpl.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@
2222
import android.view.View;
2323

2424
import com.android.systemui.SystemUI;
25+
import com.android.systemui.biometrics.FODCircleViewImplCallback;
2526
import com.android.systemui.statusbar.CommandQueue;
27+
import com.android.systemui.util.Assert;
2628

2729
import lineageos.app.LineageContextConstants;
2830

31+
import java.lang.ref.WeakReference;
32+
import java.util.ArrayList;
2933
import javax.inject.Inject;
3034
import javax.inject.Singleton;
3135

@@ -34,8 +38,13 @@ public class FODCircleViewImpl extends SystemUI implements CommandQueue.Callback
3438
private static final String TAG = "FODCircleViewImpl";
3539

3640
private FODCircleView mFodCircleView;
41+
42+
private final ArrayList<WeakReference<FODCircleViewImplCallback>>
43+
mCallbacks = new ArrayList<>();
3744
private final CommandQueue mCommandQueue;
3845

46+
private boolean mIsFODVisible;
47+
3948
@Inject
4049
public FODCircleViewImpl(Context context, CommandQueue commandQueue) {
4150
super(context);
@@ -52,6 +61,12 @@ public void start() {
5261
mCommandQueue.addCallback(this);
5362
try {
5463
mFodCircleView = new FODCircleView(mContext);
64+
for (int i = 0; i < mCallbacks.size(); i++) {
65+
FODCircleViewImplCallback cb = mCallbacks.get(i).get();
66+
if (cb != null) {
67+
cb.onFODStart();
68+
}
69+
}
5570
} catch (RuntimeException e) {
5671
Slog.e(TAG, "Failed to initialize FODCircleView", e);
5772
}
@@ -60,14 +75,54 @@ public void start() {
6075
@Override
6176
public void showInDisplayFingerprintView() {
6277
if (mFodCircleView != null) {
78+
for (int i = 0; i < mCallbacks.size(); i++) {
79+
FODCircleViewImplCallback cb = mCallbacks.get(i).get();
80+
if (cb != null) {
81+
cb.onFODStatusChange(true);
82+
}
83+
}
84+
mIsFODVisible = true;
6385
mFodCircleView.show();
6486
}
6587
}
6688

6789
@Override
6890
public void hideInDisplayFingerprintView() {
6991
if (mFodCircleView != null) {
92+
for (int i = 0; i < mCallbacks.size(); i++) {
93+
FODCircleViewImplCallback cb = mCallbacks.get(i).get();
94+
if (cb != null) {
95+
cb.onFODStatusChange(false);
96+
}
97+
}
98+
mIsFODVisible = false;
7099
mFodCircleView.hide();
71100
}
72101
}
102+
103+
public void registerCallback(FODCircleViewImplCallback callback) {
104+
Assert.isMainThread();
105+
Slog.v(TAG, "*** register callback for " + callback);
106+
for (int i = 0; i < mCallbacks.size(); i++) {
107+
if (mCallbacks.get(i).get() == callback) {
108+
Slog.e(TAG, "Object tried to add another callback",
109+
new Exception("Called by"));
110+
return;
111+
}
112+
}
113+
mCallbacks.add(new WeakReference<>(callback));
114+
removeCallback(null);
115+
sendUpdates(callback);
116+
}
117+
118+
public void removeCallback(FODCircleViewImplCallback callback) {
119+
Assert.isMainThread();
120+
Slog.v(TAG, "*** unregister callback for " + callback);
121+
mCallbacks.removeIf(el -> el.get() == callback);
122+
}
123+
124+
private void sendUpdates(FODCircleViewImplCallback callback) {
125+
callback.onFODStart();
126+
callback.onFODStatusChange(mIsFODVisible);
127+
}
73128
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (C) 2021 The LineageOS Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.systemui.biometrics;
18+
19+
public class FODCircleViewImplCallback {
20+
21+
public void onFODStart() {}
22+
23+
public void onFODStatusChange(boolean isVisible) {}
24+
25+
}

packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
import android.animation.AnimatorListenerAdapter;
2121
import android.animation.ValueAnimator;
2222
import android.app.ActivityManager;
23+
import android.content.Context;
2324
import android.graphics.Matrix;
2425
import android.graphics.Rect;
26+
import android.hardware.fingerprint.IFingerprintService;
2527
import android.os.RemoteException;
28+
import android.os.ServiceManager;
2629
import android.util.MathUtils;
2730
import android.view.IRemoteAnimationFinishedCallback;
2831
import android.view.IRemoteAnimationRunner;
@@ -34,6 +37,7 @@
3437

3538
import com.android.internal.policy.ScreenDecorationsUtils;
3639
import com.android.systemui.Interpolators;
40+
import com.android.systemui.biometrics.FODCircleViewImpl;
3741
import com.android.systemui.statusbar.NotificationShadeDepthController;
3842
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
3943
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -70,14 +74,17 @@ public class ActivityLaunchAnimator {
7074
private boolean mAnimationPending;
7175
private boolean mAnimationRunning;
7276
private boolean mIsLaunchForActivity;
77+
private IFingerprintService mFingerprintService;
78+
private FODCircleViewImpl mFODCircleViewImpl;
7379

7480
public ActivityLaunchAnimator(
7581
NotificationShadeWindowViewController notificationShadeWindowViewController,
7682
Callback callback,
7783
NotificationPanelViewController notificationPanel,
7884
NotificationShadeDepthController depthController,
7985
NotificationListContainer container,
80-
Executor mainExecutor) {
86+
Executor mainExecutor,
87+
FODCircleViewImpl fodCircleViewImpl) {
8188
mNotificationPanel = notificationPanel;
8289
mNotificationContainer = container;
8390
mDepthController = depthController;
@@ -87,6 +94,9 @@ public ActivityLaunchAnimator(
8794
mWindowCornerRadius = ScreenDecorationsUtils
8895
.getWindowCornerRadius(mNotificationShadeWindowViewController.getView()
8996
.getResources());
97+
mFODCircleViewImpl = fodCircleViewImpl;
98+
mFingerprintService = IFingerprintService.Stub.asInterface(
99+
ServiceManager.getService(Context.FINGERPRINT_SERVICE));
90100
}
91101

92102
public RemoteAnimationAdapter getLaunchAnimation(
@@ -263,6 +273,15 @@ private void setExpandAnimationRunning(boolean running) {
263273
mNotificationShadeWindowViewController.setExpandAnimationRunning(running);
264274
mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null);
265275
mAnimationRunning = running;
276+
boolean isFPClientActive = false;
277+
try {
278+
isFPClientActive = mFingerprintService.isClientActive();
279+
} catch (Exception e) {
280+
// do nothing.
281+
}
282+
if (!isFPClientActive) {
283+
mFODCircleViewImpl.hideInDisplayFingerprintView();
284+
}
266285
if (!running) {
267286
mCallback.onExpandAnimationFinished(mIsFullScreenLaunch);
268287
applyParamsToNotification(null);

packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import android.graphics.Point;
7777
import android.graphics.PointF;
7878
import android.hardware.display.DisplayManager;
79+
import android.hardware.fingerprint.IFingerprintService;
7980
import android.media.AudioAttributes;
8081
import android.metrics.LogMaker;
8182
import android.net.Uri;
@@ -150,6 +151,8 @@
150151
import com.android.systemui.SystemUI;
151152
import com.android.systemui.SystemUIFactory;
152153
import com.android.systemui.assist.AssistManager;
154+
import com.android.systemui.biometrics.FODCircleViewImpl;
155+
import com.android.systemui.biometrics.FODCircleViewImplCallback;
153156
import com.android.systemui.broadcast.BroadcastDispatcher;
154157
import com.android.systemui.bubbles.BubbleController;
155158
import com.android.systemui.charging.WirelessChargingAnimation;
@@ -238,6 +241,7 @@
238241
import java.io.FileDescriptor;
239242
import java.io.PrintWriter;
240243
import java.io.StringWriter;
244+
import java.util.List;
241245
import java.util.Map;
242246
import java.util.Optional;
243247
import java.util.concurrent.Executor;
@@ -633,6 +637,33 @@ public void onCancelled() {
633637
}
634638
};
635639

640+
private ActivityManager mActivityManager;
641+
private boolean mFodVisibility;
642+
private boolean mIsDreaming;
643+
private FODCircleViewImpl mFODCircleViewImpl;
644+
private String mTopPkgClass;
645+
private FODCircleViewImplCallback mFODCircleViewImplCallback =
646+
new FODCircleViewImplCallback() {
647+
@Override
648+
public void onFODStatusChange(boolean isVisible) {
649+
boolean isFPClientActive = false;
650+
try {
651+
isFPClientActive = mFingerprintService.isClientActive();
652+
} catch (Exception e) {
653+
// do nothing.
654+
}
655+
mFodVisibility = isVisible;
656+
if (!isFPClientActive) {
657+
// if the client is not active, we have to nullify mTopPkgClass before
658+
// checking it against current foreground activity
659+
mTopPkgClass = null;
660+
return;
661+
} else if (isVisible && !mIsKeyguard && !mIsDreaming) {
662+
mTopPkgClass = getForegroundPackageNameAndClass();
663+
}
664+
}
665+
};
666+
636667
private KeyguardUserSwitcher mKeyguardUserSwitcher;
637668
private final UserSwitcherController mUserSwitcherController;
638669
private final NetworkController mNetworkController;
@@ -661,6 +692,7 @@ public void onCancelled() {
661692
new KeyguardUpdateMonitorCallback() {
662693
@Override
663694
public void onDreamingStateChanged(boolean dreaming) {
695+
mIsDreaming = dreaming;
664696
if (dreaming) {
665697
maybeEscalateHeadsUp();
666698
}
@@ -685,6 +717,7 @@ public void onStrongAuthStateChanged(int userId) {
685717
private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
686718
private final BubbleController mBubbleController;
687719
private final BubbleController.BubbleExpandListener mBubbleExpandListener;
720+
private final IFingerprintService mFingerprintService;
688721

689722
private ActivityIntentHelper mActivityIntentHelper;
690723

@@ -774,7 +807,8 @@ public StatusBar(
774807
DismissCallbackRegistry dismissCallbackRegistry,
775808
Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
776809
StatusBarTouchableRegionManager statusBarTouchableRegionManager,
777-
TunerService tunerService) {
810+
TunerService tunerService,
811+
FODCircleViewImpl fodCircleViewImpl) {
778812
super(context);
779813
mNotificationsController = notificationsController;
780814
mLightBarController = lightBarController;
@@ -852,6 +886,7 @@ public StatusBar(
852886
mIconPolicy = phoneStatusBarPolicy;
853887
mDismissCallbackRegistry = dismissCallbackRegistry;
854888
mTunerService = tunerService;
889+
mFODCircleViewImpl = fodCircleViewImpl;
855890

856891
mBubbleExpandListener =
857892
(isExpanding, key) -> {
@@ -861,6 +896,9 @@ public StatusBar(
861896

862897

863898
DateTimeView.setReceiverHandler(timeTickHandler);
899+
900+
mFingerprintService = IFingerprintService.Stub.asInterface(
901+
ServiceManager.getService(Context.FINGERPRINT_SERVICE));
864902
}
865903

866904
@Override
@@ -1059,6 +1097,8 @@ public void onHoldStatusBarOpenChange() {
10591097
}
10601098
}
10611099
}, OverlayPlugin.class, true /* Allow multiple plugins */);
1100+
mActivityManager = mContext.getSystemService(ActivityManager.class);
1101+
mFODCircleViewImpl.registerCallback(mFODCircleViewImplCallback);
10621102
}
10631103

10641104
// ================================================================================
@@ -1367,7 +1407,8 @@ private void setUpPresenter() {
13671407
mActivityLaunchAnimator = new ActivityLaunchAnimator(
13681408
mNotificationShadeWindowViewController, this, mNotificationPanelViewController,
13691409
mNotificationShadeDepthControllerLazy.get(),
1370-
(NotificationListContainer) mStackScroller, mContext.getMainExecutor());
1410+
(NotificationListContainer) mStackScroller, mContext.getMainExecutor(),
1411+
mFODCircleViewImpl);
13711412

13721413
// TODO: inject this.
13731414
mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanelViewController,
@@ -1882,6 +1923,12 @@ public void setPanelExpanded(boolean isExpanded) {
18821923
clearNotificationEffects();
18831924
}
18841925

1926+
if (isExpanded && mFodVisibility) {
1927+
mFODCircleViewImpl.hideInDisplayFingerprintView();
1928+
} else if (!isExpanded && getForegroundPackageNameAndClass().equals(mTopPkgClass)) {
1929+
mFODCircleViewImpl.showInDisplayFingerprintView();
1930+
}
1931+
18851932
if (!isExpanded) {
18861933
mRemoteInputManager.onPanelCollapsed();
18871934
}
@@ -2603,6 +2650,11 @@ public void onAnimationEnded() {
26032650
@Override
26042651
public void onRecentsAnimationStateChanged(boolean running) {
26052652
setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, running);
2653+
if (!running && getForegroundPackageNameAndClass().equals(mTopPkgClass)) {
2654+
mFODCircleViewImpl.showInDisplayFingerprintView();
2655+
} else {
2656+
mFODCircleViewImpl.hideInDisplayFingerprintView();
2657+
}
26062658
}
26072659

26082660
protected BarTransitions getStatusBarTransitions() {
@@ -4628,4 +4680,18 @@ private boolean isTransientShown() {
46284680
public void suppressAmbientDisplay(boolean suppressed) {
46294681
mDozeServiceHost.setDozeSuppressed(suppressed);
46304682
}
4683+
4684+
private String getForegroundPackageNameAndClass() {
4685+
List<ActivityManager.RunningTaskInfo> tasks = mActivityManager.getRunningTasks(1);
4686+
if (tasks.isEmpty()) {
4687+
return null;
4688+
}
4689+
ActivityManager.RunningTaskInfo currentTask = tasks.get(0);
4690+
ComponentName currentActivity = currentTask.topActivity;
4691+
if (currentActivity.getPackageName() != null) {
4692+
return currentActivity.getPackageName().trim() +
4693+
currentActivity.getShortClassName().trim();
4694+
}
4695+
return null;
4696+
}
46314697
}

0 commit comments

Comments
 (0)