Remove communal support from SystemUI.
This changelist removes support for deprecated communal mode functionality from SystemUI. Test: atest NotificationPanelViewControllerTest Bug: 202873080 Change-Id: Id86754003222e8229f901d3aeb7c2f8ef8a333aa
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<!-- This is a view that shows general status information in Keyguard. -->
|
||||
<com.android.systemui.communal.CommunalHostView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/communal_host"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
@@ -26,9 +26,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<include layout="@layout/communal_host_view"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/keyguard_qs_user_switch_stub"
|
||||
android:layout="@layout/keyguard_qs_user_switch"
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.graphics.Rect;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.keyguard.KeyguardClockSwitch.ClockSize;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||
@@ -63,7 +62,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
KeyguardClockSwitchController keyguardClockSwitchController,
|
||||
KeyguardStateController keyguardStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
CommunalStateController communalStateController,
|
||||
ConfigurationController configurationController,
|
||||
DozeParameters dozeParameters,
|
||||
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
||||
@@ -75,9 +73,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
mConfigurationController = configurationController;
|
||||
mDozeParameters = dozeParameters;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
|
||||
keyguardStateController, dozeParameters, screenOffAnimationController,
|
||||
/* animateYPos= */ true, /* visibleOnCommunal= */ false);
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
|
||||
dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
|
||||
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
|
||||
import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||
@@ -39,30 +38,24 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
public class KeyguardVisibilityHelper {
|
||||
|
||||
private View mView;
|
||||
private final CommunalStateController mCommunalStateController;
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final DozeParameters mDozeParameters;
|
||||
private final ScreenOffAnimationController mScreenOffAnimationController;
|
||||
private final boolean mVisibleOnCommunal;
|
||||
private boolean mAnimateYPos;
|
||||
private boolean mKeyguardViewVisibilityAnimating;
|
||||
private boolean mLastOccludedState = false;
|
||||
private final AnimationProperties mAnimationProperties = new AnimationProperties();
|
||||
|
||||
public KeyguardVisibilityHelper(View view,
|
||||
CommunalStateController communalStateController,
|
||||
KeyguardStateController keyguardStateController,
|
||||
DozeParameters dozeParameters,
|
||||
ScreenOffAnimationController screenOffAnimationController,
|
||||
boolean animateYPos,
|
||||
boolean visibleOnCommunal) {
|
||||
boolean animateYPos) {
|
||||
mView = view;
|
||||
mCommunalStateController = communalStateController;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mDozeParameters = dozeParameters;
|
||||
mScreenOffAnimationController = screenOffAnimationController;
|
||||
mAnimateYPos = animateYPos;
|
||||
mVisibleOnCommunal = visibleOnCommunal;
|
||||
}
|
||||
|
||||
public boolean isVisibilityAnimating() {
|
||||
@@ -81,13 +74,6 @@ public class KeyguardVisibilityHelper {
|
||||
boolean isOccluded = mKeyguardStateController.isOccluded();
|
||||
mKeyguardViewVisibilityAnimating = false;
|
||||
|
||||
// If the communal view is showing, hide immediately
|
||||
if (!mVisibleOnCommunal && mCommunalStateController.getCommunalViewShowing()) {
|
||||
mView.setVisibility(View.GONE);
|
||||
mView.setAlpha(1f);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD
|
||||
&& statusBarState != KEYGUARD) || goingToFullShade) {
|
||||
mKeyguardViewVisibilityAnimating = true;
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Container for communal presentation. Containing communal-related view to this parent view allows
|
||||
* for aggregate measurement/layout adjustments and capturing said values before the communal views
|
||||
* might be available.
|
||||
*/
|
||||
public class CommunalHostView extends FrameLayout {
|
||||
public CommunalHostView(@NonNull Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public CommunalHostView(@NonNull Context context,
|
||||
@Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CommunalHostView(@NonNull Context context, @Nullable AttributeSet attrs,
|
||||
int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
}
|
||||
@@ -1,396 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.KeyguardVisibilityHelper;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
|
||||
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Injectable controller for {@link CommunalHostView}.
|
||||
*/
|
||||
public class CommunalHostViewController extends ViewController<CommunalHostView> {
|
||||
private static final String TAG = "CommunalController";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
private static final String STATE_LIST_FORMAT = "[%s]";
|
||||
private static final AnimationProperties COMMUNAL_ANIMATION_PROPERTIES =
|
||||
new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
|
||||
|
||||
private final Executor mMainExecutor;
|
||||
private final CommunalStateController mCommunalStateController;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final StatusBarStateController mStatusBarStateController;
|
||||
private WeakReference<CommunalSource> mCurrentSource;
|
||||
private Optional<ShowRequest> mLastRequest = Optional.empty();
|
||||
private int mState;
|
||||
private float mQsExpansion;
|
||||
private float mShadeExpansion;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@IntDef({STATE_KEYGUARD_SHOWING, STATE_DOZING, STATE_BOUNCER_SHOWING, STATE_KEYGUARD_OCCLUDED})
|
||||
public @interface State {}
|
||||
|
||||
private static final int STATE_KEYGUARD_SHOWING = 1 << 0;
|
||||
private static final int STATE_DOZING = 1 << 1;
|
||||
private static final int STATE_BOUNCER_SHOWING = 1 << 2;
|
||||
private static final int STATE_KEYGUARD_OCCLUDED = 1 << 3;
|
||||
|
||||
// Only show communal view when keyguard is showing and not dozing.
|
||||
private static final int SHOW_COMMUNAL_VIEW_REQUIRED_STATES = STATE_KEYGUARD_SHOWING;
|
||||
private static final int SHOW_COMMUNAL_VIEW_INVALID_STATES =
|
||||
STATE_DOZING | STATE_KEYGUARD_OCCLUDED;
|
||||
|
||||
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
|
||||
|
||||
private ViewController<? extends View> mCommunalViewController;
|
||||
|
||||
private static class ShowRequest {
|
||||
private boolean mShouldShow;
|
||||
private WeakReference<CommunalSource> mSource;
|
||||
|
||||
ShowRequest(boolean shouldShow, WeakReference<CommunalSource> source) {
|
||||
mShouldShow = shouldShow;
|
||||
mSource = source;
|
||||
}
|
||||
|
||||
CommunalSource getSource() {
|
||||
return mSource != null ? mSource.get() : null;
|
||||
}
|
||||
|
||||
boolean shouldShow() {
|
||||
return mShouldShow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ShowRequest)) return false;
|
||||
ShowRequest that = (ShowRequest) o;
|
||||
return mShouldShow == that.mShouldShow && Objects.equals(getSource(), that.getSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mShouldShow, mSource);
|
||||
}
|
||||
}
|
||||
|
||||
private KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onKeyguardBouncerChanged(boolean bouncer) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onKeyguardBouncerChanged:" + bouncer);
|
||||
}
|
||||
|
||||
setState(STATE_BOUNCER_SHOWING, bouncer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyguardOccludedChanged(boolean occluded) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onKeyguardOccludedChanged" + occluded);
|
||||
}
|
||||
|
||||
setState(STATE_KEYGUARD_OCCLUDED, occluded);
|
||||
}
|
||||
};
|
||||
|
||||
private KeyguardStateController.Callback mKeyguardCallback =
|
||||
new KeyguardStateController.Callback() {
|
||||
@Override
|
||||
public void onKeyguardShowingChanged() {
|
||||
final boolean isShowing = mKeyguardStateController.isShowing();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setKeyguardShowing:" + isShowing);
|
||||
}
|
||||
|
||||
setState(STATE_KEYGUARD_SHOWING, isShowing);
|
||||
}
|
||||
};
|
||||
|
||||
private StatusBarStateController.StateListener mDozeCallback =
|
||||
new StatusBarStateController.StateListener() {
|
||||
@Override
|
||||
public void onDozingChanged(boolean isDozing) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setDozing:" + isDozing);
|
||||
}
|
||||
|
||||
setState(STATE_DOZING, isDozing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int newState) {
|
||||
updateCommunalViewOccluded();
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
protected CommunalHostViewController(@Main Executor mainExecutor,
|
||||
CommunalStateController communalStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
KeyguardStateController keyguardStateController,
|
||||
DozeParameters dozeParameters,
|
||||
ScreenOffAnimationController screenOffAnimationController,
|
||||
StatusBarStateController statusBarStateController, CommunalHostView view) {
|
||||
super(view);
|
||||
mCommunalStateController = communalStateController;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mMainExecutor = mainExecutor;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
|
||||
keyguardStateController, dozeParameters, screenOffAnimationController,
|
||||
/* animateYPos= */ false, /* visibleOnCommunal= */ true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility of the keyguard status view based on some new state.
|
||||
*/
|
||||
public void setKeyguardStatusViewVisibility(
|
||||
int statusBarState,
|
||||
boolean keyguardFadingAway,
|
||||
boolean goingToFullShade,
|
||||
int oldStatusBarState) {
|
||||
mKeyguardVisibilityHelper.setViewVisibility(
|
||||
statusBarState, keyguardFadingAway, goingToFullShade, oldStatusBarState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set keyguard status view alpha.
|
||||
*/
|
||||
public void setAlpha(float alpha) {
|
||||
if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
|
||||
mView.setAlpha(alpha);
|
||||
|
||||
// Some communal view implementations, such as SurfaceViews, do not behave correctly
|
||||
// inheriting the alpha of their parent. Directly set child alpha here to work around
|
||||
// this.
|
||||
for (int i = mView.getChildCount() - 1; i >= 0; --i) {
|
||||
mView.getChildAt(i).setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onInit() {
|
||||
setState(STATE_KEYGUARD_SHOWING, mKeyguardStateController.isShowing());
|
||||
setState(STATE_DOZING, mStatusBarStateController.isDozing());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
mKeyguardStateController.addCallback(mKeyguardCallback);
|
||||
mStatusBarStateController.addCallback(mDozeCallback);
|
||||
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
mKeyguardStateController.removeCallback(mKeyguardCallback);
|
||||
mStatusBarStateController.removeCallback(mDozeCallback);
|
||||
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
|
||||
}
|
||||
|
||||
private void setState(@State int stateFlag, boolean enabled) {
|
||||
final int existingState = mState;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setState flag:" + describeState(stateFlag) + " enabled:" + enabled);
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
mState |= stateFlag;
|
||||
} else {
|
||||
mState &= ~stateFlag;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "updated state:" + describeState());
|
||||
}
|
||||
|
||||
if (existingState != mState) {
|
||||
showSource();
|
||||
}
|
||||
|
||||
updateCommunalViewOccluded();
|
||||
}
|
||||
|
||||
private String describeState(@State int stateFlag) {
|
||||
switch(stateFlag) {
|
||||
case STATE_DOZING:
|
||||
return "dozing";
|
||||
case STATE_BOUNCER_SHOWING:
|
||||
return "bouncer_showing";
|
||||
case STATE_KEYGUARD_SHOWING:
|
||||
return "keyguard_showing";
|
||||
default:
|
||||
return "UNDEFINED_STATE";
|
||||
}
|
||||
}
|
||||
|
||||
private String describeState() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
if ((mState & STATE_KEYGUARD_SHOWING) == STATE_KEYGUARD_SHOWING) {
|
||||
stringBuilder.append(String.format(STATE_LIST_FORMAT,
|
||||
describeState(STATE_KEYGUARD_SHOWING)));
|
||||
}
|
||||
if ((mState & STATE_DOZING) == STATE_DOZING) {
|
||||
stringBuilder.append(String.format(STATE_LIST_FORMAT,
|
||||
describeState(STATE_DOZING)));
|
||||
}
|
||||
if ((mState & STATE_BOUNCER_SHOWING) == STATE_BOUNCER_SHOWING) {
|
||||
stringBuilder.append(String.format(STATE_LIST_FORMAT,
|
||||
describeState(STATE_BOUNCER_SHOWING)));
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private void showSource() {
|
||||
final ShowRequest request = new ShowRequest(
|
||||
(mState & SHOW_COMMUNAL_VIEW_REQUIRED_STATES) == SHOW_COMMUNAL_VIEW_REQUIRED_STATES
|
||||
&& (mState & SHOW_COMMUNAL_VIEW_INVALID_STATES) == 0
|
||||
&& mCurrentSource != null,
|
||||
mCurrentSource);
|
||||
|
||||
if (mLastRequest.isPresent() && Objects.equals(mLastRequest.get(), request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLastRequest = Optional.of(request);
|
||||
|
||||
// Make sure all necessary states are present for showing communal and all invalid states
|
||||
// are absent
|
||||
mMainExecutor.execute(() -> {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "showSource. currentSource:" + request.getSource());
|
||||
}
|
||||
|
||||
if (request.shouldShow()) {
|
||||
mView.removeAllViews();
|
||||
|
||||
// Make view visible.
|
||||
mView.setVisibility(View.VISIBLE);
|
||||
|
||||
final Context context = mView.getContext();
|
||||
|
||||
final ListenableFuture<CommunalSource.CommunalViewResult> listenableFuture =
|
||||
request.getSource().requestCommunalView(context);
|
||||
|
||||
if (listenableFuture == null) {
|
||||
Log.e(TAG, "could not request communal view");
|
||||
return;
|
||||
}
|
||||
|
||||
listenableFuture.addListener(() -> {
|
||||
try {
|
||||
final CommunalSource.CommunalViewResult result = listenableFuture.get();
|
||||
result.view.setLayoutParams(new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
mView.addView(result.view);
|
||||
|
||||
mCommunalViewController = result.viewController;
|
||||
mCommunalViewController.init();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "could not obtain communal view through callback:" + e);
|
||||
}
|
||||
}, mMainExecutor);
|
||||
} else {
|
||||
mView.removeAllViews();
|
||||
mView.setVisibility(View.INVISIBLE);
|
||||
mCommunalStateController.setCommunalViewShowing(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs {@link CommunalHostViewController} to display provided source.
|
||||
*
|
||||
* @param source The new {@link CommunalSource}, {@code null} if not set.
|
||||
*/
|
||||
public void show(WeakReference<CommunalSource> source) {
|
||||
mCurrentSource = source;
|
||||
showSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update position of the view with an optional animation
|
||||
*/
|
||||
public void updatePosition(int y, boolean animate) {
|
||||
PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, COMMUNAL_ANIMATION_PROPERTIES,
|
||||
animate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the quick settings is expanded.
|
||||
* @param expansionFraction the percentage the QS shade has been expanded.
|
||||
*/
|
||||
public void updateQsExpansion(float expansionFraction) {
|
||||
mQsExpansion = expansionFraction;
|
||||
updateCommunalViewOccluded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the main shade is expanded.
|
||||
* @param shadeExpansion the percentage the main shade has expanded.
|
||||
*/
|
||||
public void updateShadeExpansion(float shadeExpansion) {
|
||||
mShadeExpansion = shadeExpansion;
|
||||
updateCommunalViewOccluded();
|
||||
}
|
||||
|
||||
private void updateCommunalViewOccluded() {
|
||||
final boolean bouncerShowing = (mState & STATE_BOUNCER_SHOWING) == STATE_BOUNCER_SHOWING;
|
||||
final int statusBarState = mStatusBarStateController.getState();
|
||||
final boolean shadeExpanded = statusBarState == StatusBarState.SHADE
|
||||
|| statusBarState == StatusBarState.SHADE_LOCKED;
|
||||
|
||||
mCommunalStateController.setCommunalViewOccluded(
|
||||
bouncerShowing || shadeExpanded || mQsExpansion > 0.0f || mShadeExpansion > 0.0f);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
|
||||
|
||||
/**
|
||||
* {@link CommunalHostViewPositionAlgorithm} calculates the position of the communal view given
|
||||
* input such as the notification panel position.
|
||||
*/
|
||||
public class CommunalHostViewPositionAlgorithm {
|
||||
private static final String TAG = "CommunalPositionAlg";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
/**
|
||||
* @see NotificationPanelViewController#getExpandedFraction()
|
||||
*/
|
||||
private float mPanelExpansion;
|
||||
|
||||
/**
|
||||
* Height of {@link CommunalHostView}.
|
||||
*/
|
||||
private int mCommunalHeight;
|
||||
|
||||
/**
|
||||
* A data container for the result of the position algorithm.
|
||||
*/
|
||||
public static class Result {
|
||||
/**
|
||||
* The y translation of the clock.
|
||||
*/
|
||||
public int communalY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the conditions under which the result should be calculated from.
|
||||
* @param panelExpansion The percentage the keyguard panel has been moved upwards.
|
||||
* @param communalHeight The height of the communal panel.
|
||||
*/
|
||||
public void setup(float panelExpansion, int communalHeight) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setup. panelExpansion:" + panelExpansion);
|
||||
}
|
||||
mPanelExpansion = panelExpansion;
|
||||
mCommunalHeight = communalHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the position based on factors input through {link {@link #setup(float, int)}}.
|
||||
* @param result The resulting calculations.
|
||||
*/
|
||||
public void run(Result result) {
|
||||
// The panel expansion relates to the keyguard expansion. At full expansion, the communal
|
||||
// view should be aligned at the top (0). Otherwise, it should be shifted offscreen by the
|
||||
// unexpanded amount.
|
||||
result.communalY = (int) ((1 - mPanelExpansion) * -mCommunalHeight);
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* {@link CommunalSource} defines an interface for working with a source for communal data. Clients
|
||||
* may request a communal surface that can be shown within a {@link android.view.SurfaceView}.
|
||||
* Callbacks may also be registered to listen to state changes.
|
||||
*/
|
||||
public interface CommunalSource {
|
||||
/**
|
||||
* {@link Connector} defines an interface for {@link CommunalSource} instances to be generated.
|
||||
*/
|
||||
interface Connector {
|
||||
Connection connect(Connection.Callback callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Connection} defines an interface for an entity which holds the necessary components
|
||||
* for establishing and maintaining a connection to the communal source.
|
||||
*/
|
||||
interface Connection {
|
||||
/**
|
||||
* {@link Callback} defines an interface for clients to be notified when a source is ready
|
||||
*/
|
||||
interface Callback {
|
||||
void onSourceEstablished(Optional<CommunalSource> source);
|
||||
void onDisconnected();
|
||||
}
|
||||
|
||||
void disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Observer} interface specifies an entity which {@link CommunalSource} listeners
|
||||
* can be informed of changes to the source, which will require updating. Note that this deals
|
||||
* with changes to the source itself, not content which will be updated through the
|
||||
* {@link CommunalSource} interface.
|
||||
*/
|
||||
interface Observer {
|
||||
interface Callback {
|
||||
void onSourceChanged();
|
||||
}
|
||||
|
||||
void addCallback(Callback callback);
|
||||
void removeCallback(Callback callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CommunalViewResult} is handed back from {@link #requestCommunalView(Context)} and
|
||||
* contains the view to be displayed and its associated controller.
|
||||
*/
|
||||
class CommunalViewResult {
|
||||
/**
|
||||
* The resulting communal view.
|
||||
*/
|
||||
public final View view;
|
||||
/**
|
||||
* The controller for the communal view.
|
||||
*/
|
||||
public final ViewController<? extends View> viewController;
|
||||
|
||||
/**
|
||||
* The default constructor for {@link CommunalViewResult}.
|
||||
* @param view The communal view.
|
||||
* @param viewController The communal view's controller.
|
||||
*/
|
||||
public CommunalViewResult(View view, ViewController<? extends View> viewController) {
|
||||
this.view = view;
|
||||
this.viewController = viewController;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a communal surface that can be displayed inside {@link CommunalHostView}.
|
||||
*
|
||||
* @param context The {@link View} {@link Context} to build the resulting view from
|
||||
* @return A future that can be listened upon for the resulting {@link CommunalViewResult}. The
|
||||
* value will be {@code null} in case of a failure.
|
||||
*/
|
||||
ListenableFuture<CommunalViewResult> requestCommunalView(Context context);
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import static com.android.systemui.communal.dagger.CommunalModule.COMMUNAL_CONDITIONS;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.util.condition.Monitor;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* A Monitor for reporting a {@link CommunalSource} presence.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class CommunalSourceMonitor {
|
||||
private static final String TAG = "CommunalSourceMonitor";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
// A list of {@link Callback} that have registered to receive updates.
|
||||
private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();
|
||||
private final Monitor mConditionsMonitor;
|
||||
private final Executor mExecutor;
|
||||
|
||||
private CommunalSource mCurrentSource;
|
||||
|
||||
// Whether all conditions for communal mode to show have been met.
|
||||
private boolean mAllCommunalConditionsMet = false;
|
||||
|
||||
// Whether the class is currently listening for condition changes.
|
||||
private boolean mListeningForConditions = false;
|
||||
|
||||
private final Monitor.Callback mConditionsCallback =
|
||||
allConditionsMet -> {
|
||||
if (mAllCommunalConditionsMet != allConditionsMet) {
|
||||
if (DEBUG) Log.d(TAG, "communal conditions changed: " + allConditionsMet);
|
||||
|
||||
mAllCommunalConditionsMet = allConditionsMet;
|
||||
executeOnSourceAvailableCallbacks();
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
@Inject
|
||||
public CommunalSourceMonitor(@Main Executor executor,
|
||||
@Named(COMMUNAL_CONDITIONS) Monitor communalConditionsMonitor) {
|
||||
mExecutor = executor;
|
||||
mConditionsMonitor = communalConditionsMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current {@link CommunalSource}, informing any callbacks. Any existing
|
||||
* {@link CommunalSource} will be disconnected.
|
||||
*
|
||||
* @param source The new {@link CommunalSource}.
|
||||
*/
|
||||
public void setSource(CommunalSource source) {
|
||||
mCurrentSource = source;
|
||||
|
||||
if (mAllCommunalConditionsMet) {
|
||||
executeOnSourceAvailableCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
private void executeOnSourceAvailableCallbacks() {
|
||||
mExecutor.execute(() -> {
|
||||
// If the new source is valid, inform registered Callbacks of its presence.
|
||||
Iterator<WeakReference<Callback>> itr = mCallbacks.iterator();
|
||||
while (itr.hasNext()) {
|
||||
Callback cb = itr.next().get();
|
||||
if (cb == null) {
|
||||
itr.remove();
|
||||
} else {
|
||||
cb.onSourceAvailable(
|
||||
(mAllCommunalConditionsMet && mCurrentSource != null)
|
||||
? new WeakReference<>(mCurrentSource) : null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link Callback} to receive {@link CommunalSource} updates.
|
||||
*
|
||||
* @param callback The {@link Callback} to add.
|
||||
*/
|
||||
public void addCallback(Callback callback) {
|
||||
mExecutor.execute(() -> {
|
||||
mCallbacks.add(new WeakReference<>(callback));
|
||||
|
||||
// Inform the callback of any already present CommunalSource.
|
||||
if (mAllCommunalConditionsMet && mCurrentSource != null) {
|
||||
callback.onSourceAvailable(new WeakReference<>(mCurrentSource));
|
||||
}
|
||||
|
||||
if (!mListeningForConditions) {
|
||||
mConditionsMonitor.addCallback(mConditionsCallback);
|
||||
mListeningForConditions = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified {@link Callback} from receive future updates if present.
|
||||
*
|
||||
* @param callback The {@link Callback} to add.
|
||||
*/
|
||||
public void removeCallback(Callback callback) {
|
||||
mExecutor.execute(() -> {
|
||||
mCallbacks.removeIf(el -> el.get() == callback);
|
||||
|
||||
if (mCallbacks.isEmpty() && mListeningForConditions) {
|
||||
mConditionsMonitor.removeCallback(mConditionsCallback);
|
||||
mListeningForConditions = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface implemented to be notified when new {@link CommunalSource} become available.
|
||||
*/
|
||||
public interface Callback {
|
||||
/**
|
||||
* Called when a new {@link CommunalSource} has been registered. This will also be invoked
|
||||
* when a {@link Callback} is first registered and a {@link CommunalSource} is already
|
||||
* registered.
|
||||
*
|
||||
* @param source The new {@link CommunalSource}.
|
||||
*/
|
||||
void onSourceAvailable(WeakReference<CommunalSource> source);
|
||||
}
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.CoreStartable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
import com.android.systemui.util.time.SystemClock;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* The {@link CommunalSourcePrimer} is responsible for priming SystemUI with a pre-configured
|
||||
* Communal source. The SystemUI service binds to the component to retrieve the
|
||||
* {@link CommunalSource}. {@link CommunalSourcePrimer} has no effect
|
||||
* if there is no pre-defined value.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class CommunalSourcePrimer extends CoreStartable {
|
||||
private static final String TAG = "CommunalSourcePrimer";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private final SystemClock mSystemClock;
|
||||
private final DelayableExecutor mMainExecutor;
|
||||
private final CommunalSourceMonitor mMonitor;
|
||||
private final int mBaseReconnectDelayMs;
|
||||
private final int mMaxReconnectAttempts;
|
||||
private final int mMinConnectionDuration;
|
||||
|
||||
private int mReconnectAttempts = 0;
|
||||
private Runnable mCurrentReconnectCancelable;
|
||||
|
||||
private final Optional<CommunalSource.Observer> mObserver;
|
||||
private final Optional<CommunalSource.Connector> mConnector;
|
||||
|
||||
private CommunalSource.Connection mCurrentConnection;
|
||||
|
||||
private final Runnable mConnectRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCurrentReconnectCancelable = null;
|
||||
connect();
|
||||
}
|
||||
};
|
||||
|
||||
private final CommunalSource.Observer.Callback mObserverCallback = () -> {
|
||||
initiateConnectionAttempt();
|
||||
};
|
||||
|
||||
@Inject
|
||||
public CommunalSourcePrimer(Context context, @Main Resources resources,
|
||||
SystemClock clock,
|
||||
DelayableExecutor mainExecutor,
|
||||
CommunalSourceMonitor monitor,
|
||||
Optional<CommunalSource.Connector> connector,
|
||||
Optional<CommunalSource.Observer> observer) {
|
||||
super(context);
|
||||
mSystemClock = clock;
|
||||
mMainExecutor = mainExecutor;
|
||||
mMonitor = monitor;
|
||||
mConnector = connector;
|
||||
mObserver = observer;
|
||||
|
||||
mMaxReconnectAttempts = resources.getInteger(
|
||||
R.integer.config_communalSourceMaxReconnectAttempts);
|
||||
mBaseReconnectDelayMs = resources.getInteger(
|
||||
R.integer.config_communalSourceReconnectBaseDelay);
|
||||
mMinConnectionDuration = resources.getInteger(
|
||||
R.integer.config_connectionMinDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
}
|
||||
|
||||
private void initiateConnectionAttempt() {
|
||||
// Reset attempts
|
||||
mReconnectAttempts = 0;
|
||||
mMonitor.setSource(null);
|
||||
|
||||
// The first attempt is always a direct invocation rather than delayed.
|
||||
connect();
|
||||
}
|
||||
|
||||
private void scheduleConnectionAttempt() {
|
||||
// always clear cancelable if present.
|
||||
if (mCurrentReconnectCancelable != null) {
|
||||
mCurrentReconnectCancelable.run();
|
||||
mCurrentReconnectCancelable = null;
|
||||
}
|
||||
|
||||
if (mReconnectAttempts >= mMaxReconnectAttempts) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "exceeded max connection attempts.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final long reconnectDelayMs =
|
||||
(long) Math.scalb(mBaseReconnectDelayMs, mReconnectAttempts);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"scheduling connection attempt in " + reconnectDelayMs + "milliseconds");
|
||||
}
|
||||
|
||||
mCurrentReconnectCancelable = mMainExecutor.executeDelayed(mConnectRunnable,
|
||||
reconnectDelayMs);
|
||||
|
||||
mReconnectAttempts++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBootCompleted() {
|
||||
if (mObserver.isPresent()) {
|
||||
mObserver.get().addCallback(mObserverCallback);
|
||||
}
|
||||
initiateConnectionAttempt();
|
||||
}
|
||||
|
||||
private void connect() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "attempting to connect to communal source");
|
||||
}
|
||||
|
||||
if (mCurrentConnection != null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "canceling in-flight connection");
|
||||
}
|
||||
mCurrentConnection.disconnect();
|
||||
}
|
||||
|
||||
mCurrentConnection = mConnector.get().connect(new CommunalSource.Connection.Callback() {
|
||||
private long mStartTime;
|
||||
|
||||
@Override
|
||||
public void onSourceEstablished(Optional<CommunalSource> optionalSource) {
|
||||
mStartTime = mSystemClock.currentTimeMillis();
|
||||
|
||||
if (optionalSource.isPresent()) {
|
||||
final CommunalSource source = optionalSource.get();
|
||||
mMonitor.setSource(source);
|
||||
} else {
|
||||
scheduleConnectionAttempt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
if (mSystemClock.currentTimeMillis() - mStartTime > mMinConnectionDuration) {
|
||||
initiateConnectionAttempt();
|
||||
} else {
|
||||
scheduleConnectionAttempt();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.statusbar.policy.CallbackController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* CommunalStateController enables publishing and listening to communal-related state changes.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class CommunalStateController implements
|
||||
CallbackController<CommunalStateController.Callback> {
|
||||
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
|
||||
private boolean mCommunalViewOccluded;
|
||||
private boolean mCommunalViewShowing;
|
||||
|
||||
/**
|
||||
* Callback for communal events.
|
||||
*/
|
||||
public interface Callback {
|
||||
/**
|
||||
* Called when the visibility of the communal view changes.
|
||||
*/
|
||||
default void onCommunalViewShowingChanged() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the occlusion of the communal view changes.
|
||||
*/
|
||||
default void onCommunalViewOccludedChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Inject
|
||||
public CommunalStateController() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the communal view is showing.
|
||||
* @param communalViewShowing {@code true} if the view is showing, {@code false} otherwise.
|
||||
*/
|
||||
public void setCommunalViewShowing(boolean communalViewShowing) {
|
||||
if (mCommunalViewShowing == communalViewShowing) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCommunalViewShowing = communalViewShowing;
|
||||
|
||||
final ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
|
||||
for (Callback callback : callbacks) {
|
||||
callback.onCommunalViewShowingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the communal view is occluded (but otherwise still showing).
|
||||
* @param communalViewOccluded {@code true} if the view is occluded, {@code false} otherwise.
|
||||
*/
|
||||
public void setCommunalViewOccluded(boolean communalViewOccluded) {
|
||||
if (mCommunalViewOccluded == communalViewOccluded) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCommunalViewOccluded = communalViewOccluded;
|
||||
|
||||
ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
|
||||
for (int i = 0; i < callbacks.size(); i++) {
|
||||
callbacks.get(i).onCommunalViewOccludedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the communal view is showing.
|
||||
* @return {@code true} if the view is showing, {@code false} otherwise.
|
||||
*/
|
||||
public boolean getCommunalViewShowing() {
|
||||
return mCommunalViewShowing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the communal view is occluded.
|
||||
* @return {@code true} if the view is occluded, {@code false} otherwise.
|
||||
*/
|
||||
public boolean getCommunalViewOccluded() {
|
||||
return mCommunalViewOccluded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCallback(@NonNull Callback callback) {
|
||||
Objects.requireNonNull(callback, "Callback must not be null. b/128895449");
|
||||
if (!mCallbacks.contains(callback)) {
|
||||
mCallbacks.add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallback(@NonNull Callback callback) {
|
||||
Objects.requireNonNull(callback, "Callback must not be null. b/128895449");
|
||||
mCallbacks.remove(callback);
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.PatternMatcher;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* {@link PackageObserver} allows for monitoring the system for changes relating to a particular
|
||||
* package. This can be used by {@link CommunalSource} clients to detect when a related package
|
||||
* has changed and reloading is necessary.
|
||||
*/
|
||||
public class PackageObserver implements CommunalSource.Observer {
|
||||
private static final String TAG = "PackageObserver";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "package added receiver - onReceive");
|
||||
}
|
||||
|
||||
final Iterator<WeakReference<Callback>> iter = mCallbacks.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final Callback callback = iter.next().get();
|
||||
if (callback != null) {
|
||||
callback.onSourceChanged();
|
||||
} else {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final String mPackageName;
|
||||
private final Context mContext;
|
||||
|
||||
public PackageObserver(Context context, String packageName) {
|
||||
mContext = context;
|
||||
mPackageName = packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCallback(Callback callback) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "addCallback:" + callback);
|
||||
}
|
||||
mCallbacks.add(new WeakReference<>(callback));
|
||||
|
||||
// Only register for listening to package additions on first callback.
|
||||
if (mCallbacks.size() > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addDataScheme("package");
|
||||
filter.addDataSchemeSpecificPart(mPackageName, PatternMatcher.PATTERN_LITERAL);
|
||||
// Note that we directly register the receiver here as data schemes are not supported by
|
||||
// BroadcastDispatcher.
|
||||
mContext.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallback(Callback callback) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "removeCallback:" + callback);
|
||||
}
|
||||
final boolean removed = mCallbacks.removeIf(el -> el.get() == callback);
|
||||
|
||||
if (removed && mCallbacks.isEmpty()) {
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.communal.conditions;
|
||||
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
|
||||
import com.android.systemui.util.condition.Condition;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Monitors the communal setting, and informs any listeners with updates.
|
||||
*/
|
||||
public class CommunalSettingCondition extends Condition {
|
||||
private final SecureSettings mSecureSettings;
|
||||
private final ContentObserver mCommunalSettingContentObserver;
|
||||
|
||||
@Inject
|
||||
public CommunalSettingCondition(@MainThread Handler mainHandler,
|
||||
SecureSettings secureSettings) {
|
||||
mSecureSettings = secureSettings;
|
||||
|
||||
mCommunalSettingContentObserver = new ContentObserver(mainHandler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
final boolean communalSettingEnabled = mSecureSettings.getIntForUser(
|
||||
Settings.Secure.COMMUNAL_MODE_ENABLED, 0, UserHandle.USER_SYSTEM) == 1;
|
||||
updateCondition(communalSettingEnabled);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
mSecureSettings.registerContentObserverForUser(Settings.Secure.COMMUNAL_MODE_ENABLED,
|
||||
false /*notifyForDescendants*/, mCommunalSettingContentObserver,
|
||||
UserHandle.USER_SYSTEM);
|
||||
|
||||
// Fetches setting immediately.
|
||||
mCommunalSettingContentObserver.onChange(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stop() {
|
||||
mSecureSettings.unregisterContentObserver(mCommunalSettingContentObserver);
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* 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.communal.dagger;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.communal.CommunalSource;
|
||||
import com.android.systemui.communal.PackageObserver;
|
||||
import com.android.systemui.communal.conditions.CommunalSettingCondition;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.util.condition.Condition;
|
||||
import com.android.systemui.util.condition.Monitor;
|
||||
import com.android.systemui.util.condition.dagger.MonitorComponent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.ElementsIntoSet;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import dagger.multibindings.StringKey;
|
||||
|
||||
/**
|
||||
* Dagger Module providing Communal-related functionality.
|
||||
*/
|
||||
@Module(subcomponents = {
|
||||
CommunalViewComponent.class,
|
||||
})
|
||||
public interface CommunalModule {
|
||||
String COMMUNAL_CONDITIONS = "communal_conditions";
|
||||
|
||||
/** */
|
||||
@Provides
|
||||
static Optional<CommunalSource.Observer> provideCommunalSourcePackageObserver(
|
||||
Context context, @Main Resources resources) {
|
||||
final String componentName = resources.getString(R.string.config_communalSourceComponent);
|
||||
|
||||
if (TextUtils.isEmpty(componentName)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new PackageObserver(context,
|
||||
ComponentName.unflattenFromString(componentName).getPackageName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of conditions that need to be fulfilled in order for Communal Mode to display.
|
||||
*/
|
||||
@Provides
|
||||
@ElementsIntoSet
|
||||
@Named(COMMUNAL_CONDITIONS)
|
||||
static Set<Condition> provideCommunalConditions(
|
||||
CommunalSettingCondition communalSettingCondition) {
|
||||
return new HashSet<>(Collections.singletonList(communalSettingCondition));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO(b/205638389): Remove when there is a base implementation of
|
||||
* {@link CommunalSource.Connector}. Currently a place holder to allow a map to be present.
|
||||
*/
|
||||
@Provides
|
||||
@IntoMap
|
||||
@Nullable
|
||||
@StringKey("empty")
|
||||
static CommunalSource.Connector provideEmptyCommunalSourceConnector() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** */
|
||||
@Provides
|
||||
static Optional<CommunalSource.Connector> provideCommunalSourceConnector(
|
||||
@Main Resources resources,
|
||||
Map<Class<?>, Provider<CommunalSource.Connector>> connectorCreators) {
|
||||
final String className = resources.getString(R.string.config_communalSourceConnector);
|
||||
|
||||
if (TextUtils.isEmpty(className)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
Provider<CommunalSource.Connector> provider = connectorCreators.get(clazz);
|
||||
return provider != null ? Optional.of(provider.get()) : Optional.empty();
|
||||
} catch (ClassNotFoundException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/** */
|
||||
@Provides
|
||||
@Named(COMMUNAL_CONDITIONS)
|
||||
static Monitor provideCommunalSourceMonitor(
|
||||
@Named(COMMUNAL_CONDITIONS) Set<Condition> communalConditions,
|
||||
MonitorComponent.Factory factory) {
|
||||
final MonitorComponent component = factory.create(communalConditions, new HashSet<>());
|
||||
return component.getMonitor();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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.communal.dagger;
|
||||
|
||||
import com.android.systemui.communal.CommunalHostView;
|
||||
import com.android.systemui.communal.CommunalHostViewController;
|
||||
|
||||
import dagger.BindsInstance;
|
||||
import dagger.Subcomponent;
|
||||
|
||||
/**
|
||||
* Subcomponent for working with {@link CommunalHostView}.
|
||||
*/
|
||||
@Subcomponent
|
||||
public interface CommunalViewComponent {
|
||||
/** Simple factory for {@link CommunalViewComponent}. */
|
||||
@Subcomponent.Factory
|
||||
interface Factory {
|
||||
CommunalViewComponent build(@BindsInstance CommunalHostView view);
|
||||
}
|
||||
|
||||
/** Builds a {@link CommunalHostViewController}. */
|
||||
CommunalHostViewController getCommunalHostViewController();
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import com.android.systemui.assist.AssistModule;
|
||||
import com.android.systemui.biometrics.UdfpsHbmProvider;
|
||||
import com.android.systemui.biometrics.dagger.BiometricsModule;
|
||||
import com.android.systemui.classifier.FalsingModule;
|
||||
import com.android.systemui.communal.dagger.CommunalModule;
|
||||
import com.android.systemui.controls.dagger.ControlsModule;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.demomode.dagger.DemoModeModule;
|
||||
@@ -66,8 +65,8 @@ import com.android.systemui.statusbar.notification.people.PeopleHubModule;
|
||||
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
|
||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
|
||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
|
||||
import com.android.systemui.statusbar.phone.ShadeController;
|
||||
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
||||
import com.android.systemui.statusbar.phone.ShadeController;
|
||||
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
@@ -106,7 +105,6 @@ import dagger.Provides;
|
||||
AssistModule.class,
|
||||
BiometricsModule.class,
|
||||
ClockModule.class,
|
||||
CommunalModule.class,
|
||||
DreamModule.class,
|
||||
ControlsModule.class,
|
||||
DemoModeModule.class,
|
||||
|
||||
@@ -27,7 +27,7 @@ import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
/**
|
||||
* Dagger Module providing Communal-related functionality.
|
||||
* Dagger Module providing Dream-related functionality.
|
||||
*/
|
||||
@Module(includes = {
|
||||
DreamTouchModule.class,
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* 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.statusbar.notification.collection.coordinator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* {@link CommunalCoordinator} prevents notifications from showing on the keyguard when the communal
|
||||
* view is present.
|
||||
*/
|
||||
@CoordinatorScope
|
||||
public class CommunalCoordinator implements Coordinator {
|
||||
final Executor mExecutor;
|
||||
final CommunalStateController mCommunalStateController;
|
||||
final NotificationEntryManager mNotificationEntryManager;
|
||||
final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
|
||||
|
||||
@Inject
|
||||
public CommunalCoordinator(@Main Executor executor,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
||||
CommunalStateController communalStateController) {
|
||||
mExecutor = executor;
|
||||
mNotificationEntryManager = notificationEntryManager;
|
||||
mNotificationLockscreenUserManager = notificationLockscreenUserManager;
|
||||
mCommunalStateController = communalStateController;
|
||||
}
|
||||
|
||||
final NotifFilter mFilter = new NotifFilter("CommunalCoordinator") {
|
||||
@Override
|
||||
public boolean shouldFilterOut(@NonNull NotificationEntry entry, long now) {
|
||||
return mCommunalStateController.getCommunalViewShowing();
|
||||
}
|
||||
};
|
||||
|
||||
final CommunalStateController.Callback mStateCallback = new CommunalStateController.Callback() {
|
||||
@Override
|
||||
public void onCommunalViewShowingChanged() {
|
||||
mExecutor.execute(() -> {
|
||||
mFilter.invalidateList();
|
||||
mNotificationEntryManager.updateNotifications("Communal mode state changed");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void attach(@NonNull NotifPipeline pipeline) {
|
||||
pipeline.addPreGroupFilter(mFilter);
|
||||
mCommunalStateController.addCallback(mStateCallback);
|
||||
if (!pipeline.isNewPipelineEnabled()) {
|
||||
mNotificationLockscreenUserManager.addKeyguardNotificationSuppressor(
|
||||
entry -> mCommunalStateController.getCommunalViewShowing());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,6 @@ class NotifCoordinatorsImpl @Inject constructor(
|
||||
bubbleCoordinator: BubbleCoordinator,
|
||||
headsUpCoordinator: HeadsUpCoordinator,
|
||||
gutsCoordinator: GutsCoordinator,
|
||||
communalCoordinator: CommunalCoordinator,
|
||||
conversationCoordinator: ConversationCoordinator,
|
||||
debugModeCoordinator: DebugModeCoordinator,
|
||||
groupCountCoordinator: GroupCountCoordinator,
|
||||
@@ -86,7 +85,6 @@ class NotifCoordinatorsImpl @Inject constructor(
|
||||
mCoordinators.add(appOpsCoordinator)
|
||||
mCoordinators.add(deviceProvisionedCoordinator)
|
||||
mCoordinators.add(bubbleCoordinator)
|
||||
mCoordinators.add(communalCoordinator)
|
||||
mCoordinators.add(debugModeCoordinator)
|
||||
mCoordinators.add(conversationCoordinator)
|
||||
mCoordinators.add(groupCountCoordinator)
|
||||
|
||||
@@ -120,13 +120,6 @@ import com.android.systemui.animation.LaunchAnimator;
|
||||
import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.classifier.Classifier;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.communal.CommunalHostView;
|
||||
import com.android.systemui.communal.CommunalHostViewController;
|
||||
import com.android.systemui.communal.CommunalHostViewPositionAlgorithm;
|
||||
import com.android.systemui.communal.CommunalSource;
|
||||
import com.android.systemui.communal.CommunalSourceMonitor;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.communal.dagger.CommunalViewComponent;
|
||||
import com.android.systemui.controls.dagger.ControlsComponent;
|
||||
import com.android.systemui.dagger.qualifiers.DisplayId;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
@@ -209,7 +202,6 @@ import com.android.wm.shell.animation.FlingAnimationUtils;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -309,13 +301,10 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
private final PulseExpansionHandler mPulseExpansionHandler;
|
||||
private final KeyguardBypassController mKeyguardBypassController;
|
||||
private final KeyguardUpdateMonitor mUpdateMonitor;
|
||||
private final CommunalSourceMonitor mCommunalSourceMonitor;
|
||||
private final CommunalStateController mCommunalStateController;
|
||||
private final ConversationNotificationManager mConversationNotificationManager;
|
||||
private final AuthController mAuthController;
|
||||
private final MediaHierarchyManager mMediaHierarchyManager;
|
||||
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
private final CommunalViewComponent.Factory mCommunalViewComponentFactory;
|
||||
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
|
||||
private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
|
||||
private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
|
||||
@@ -350,8 +339,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
@VisibleForTesting QS mQs;
|
||||
private FrameLayout mQsFrame;
|
||||
private QsFrameTranslateController mQsFrameTranslateController;
|
||||
@Nullable
|
||||
private CommunalHostViewController mCommunalViewController;
|
||||
private KeyguardStatusViewController mKeyguardStatusViewController;
|
||||
private LockIconViewController mLockIconViewController;
|
||||
private NotificationsQuickSettingsContainer mNotificationContainerParent;
|
||||
@@ -364,8 +351,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
private VelocityTracker mQsVelocityTracker;
|
||||
private boolean mQsTracking;
|
||||
|
||||
private CommunalHostView mCommunalView;
|
||||
|
||||
/**
|
||||
* If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
|
||||
* the expansion for quick settings.
|
||||
@@ -413,12 +398,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
private final KeyguardClockPositionAlgorithm.Result
|
||||
mClockPositionResult =
|
||||
new KeyguardClockPositionAlgorithm.Result();
|
||||
private final CommunalHostViewPositionAlgorithm
|
||||
mCommunalPositionAlgorithm =
|
||||
new CommunalHostViewPositionAlgorithm();
|
||||
private final CommunalHostViewPositionAlgorithm.Result
|
||||
mCommunalPositionResult =
|
||||
new CommunalHostViewPositionAlgorithm.Result();
|
||||
private boolean mIsExpanding;
|
||||
|
||||
private boolean mBlockTouches;
|
||||
@@ -523,10 +502,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
mPanelAlphaAnimator.getProperty(), Interpolators.ALPHA_IN);
|
||||
private final NotificationEntryManager mEntryManager;
|
||||
|
||||
private final CommunalSourceMonitor.Callback mCommunalSourceMonitorCallback;
|
||||
|
||||
private WeakReference<CommunalSource> mCommunalSource;
|
||||
|
||||
private final CommandQueue mCommandQueue;
|
||||
private final NotificationLockscreenUserManager mLockscreenUserManager;
|
||||
private final UserManager mUserManager;
|
||||
@@ -688,32 +663,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
}
|
||||
};
|
||||
|
||||
private final CommunalStateController.Callback mCommunalStateCallback =
|
||||
new CommunalStateController.Callback() {
|
||||
@Override
|
||||
public void onCommunalViewShowingChanged() {
|
||||
mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
|
||||
mBarState,
|
||||
mKeyguardStateController.isKeyguardFadingAway(),
|
||||
mStatusBarStateController.goingToFullShade(),
|
||||
mBarState);
|
||||
if (mKeyguardUserSwitcherController != null) {
|
||||
mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility(
|
||||
mBarState,
|
||||
mKeyguardStateController.isKeyguardFadingAway(),
|
||||
mStatusBarStateController.goingToFullShade(),
|
||||
mBarState);
|
||||
}
|
||||
if (mKeyguardQsUserSwitchController != null) {
|
||||
mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility(
|
||||
mBarState,
|
||||
mKeyguardStateController.isKeyguardFadingAway(),
|
||||
mStatusBarStateController.goingToFullShade(),
|
||||
mBarState);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final FalsingTapListener mFalsingTapListener = new FalsingTapListener() {
|
||||
@Override
|
||||
public void onDoubleTapRequired() {
|
||||
@@ -739,7 +688,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
FalsingCollector falsingCollector,
|
||||
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
CommunalStateController communalStateController,
|
||||
KeyguardStateController keyguardStateController,
|
||||
StatusBarStateController statusBarStateController,
|
||||
StatusBarWindowStateController statusBarWindowStateController,
|
||||
@@ -749,7 +697,7 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
LatencyTracker latencyTracker, PowerManager powerManager,
|
||||
AccessibilityManager accessibilityManager, @DisplayId int displayId,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
CommunalSourceMonitor communalSourceMonitor, MetricsLogger metricsLogger,
|
||||
MetricsLogger metricsLogger,
|
||||
ActivityManager activityManager,
|
||||
ConfigurationController configurationController,
|
||||
Provider<FlingAnimationUtils.Builder> flingAnimationUtilsBuilder,
|
||||
@@ -763,7 +711,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
|
||||
KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
|
||||
KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
|
||||
CommunalViewComponent.Factory communalViewComponentFactory,
|
||||
LockscreenShadeTransitionController lockscreenShadeTransitionController,
|
||||
NotificationGroupManagerLegacy groupManager,
|
||||
NotificationIconAreaController notificationIconAreaController,
|
||||
@@ -832,8 +779,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
|
||||
mGroupManager = groupManager;
|
||||
mNotificationIconAreaController = notificationIconAreaController;
|
||||
mCommunalStateController = communalStateController;
|
||||
mCommunalViewComponentFactory = communalViewComponentFactory;
|
||||
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
|
||||
mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
|
||||
mDepthController = notificationShadeDepthController;
|
||||
@@ -877,7 +822,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
mThemeResId = mView.getContext().getThemeResId();
|
||||
mKeyguardBypassController = bypassController;
|
||||
mUpdateMonitor = keyguardUpdateMonitor;
|
||||
mCommunalSourceMonitor = communalSourceMonitor;
|
||||
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
|
||||
lockscreenShadeTransitionController.setNotificationPanelController(this);
|
||||
DynamicPrivacyControlListener
|
||||
@@ -924,9 +868,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
mNotificationPanelUnfoldAnimationController = unfoldComponent.map(
|
||||
SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController);
|
||||
|
||||
mCommunalSourceMonitorCallback = (source) -> {
|
||||
mUiExecutor.execute(() -> setCommunalSource(source));
|
||||
};
|
||||
mQsFrameTranslateController = qsFrameTranslateController;
|
||||
updateUserSwitcherFlags();
|
||||
onFinishInflate();
|
||||
@@ -962,7 +903,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
private void onFinishInflate() {
|
||||
loadDimens();
|
||||
mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header);
|
||||
mCommunalView = mView.findViewById(R.id.communal_host);
|
||||
|
||||
FrameLayout userAvatarContainer = null;
|
||||
KeyguardUserSwitcherView keyguardUserSwitcherView = null;
|
||||
@@ -984,20 +924,11 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
.getKeyguardStatusBarViewController();
|
||||
mKeyguardStatusBarViewController.init();
|
||||
|
||||
if (mCommunalView != null) {
|
||||
CommunalViewComponent communalViewComponent =
|
||||
mCommunalViewComponentFactory.build(mCommunalView);
|
||||
mCommunalViewController =
|
||||
communalViewComponent.getCommunalHostViewController();
|
||||
mCommunalViewController.init();
|
||||
}
|
||||
|
||||
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
|
||||
updateViewControllers(
|
||||
mView.findViewById(R.id.keyguard_status_view),
|
||||
userAvatarContainer,
|
||||
keyguardUserSwitcherView,
|
||||
mCommunalView);
|
||||
keyguardUserSwitcherView);
|
||||
|
||||
NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
|
||||
R.id.notification_stack_scroller);
|
||||
@@ -1088,8 +1019,7 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
|
||||
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
|
||||
FrameLayout userAvatarView,
|
||||
KeyguardUserSwitcherView keyguardUserSwitcherView,
|
||||
CommunalHostView communalView) {
|
||||
KeyguardUserSwitcherView keyguardUserSwitcherView) {
|
||||
// Re-associate the KeyguardStatusViewController
|
||||
KeyguardStatusViewComponent statusViewComponent =
|
||||
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
|
||||
@@ -1282,7 +1212,7 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
showKeyguardUserSwitcher /* enabled */);
|
||||
|
||||
updateViewControllers(mView.findViewById(R.id.keyguard_status_view), userAvatarView,
|
||||
keyguardUserSwitcherView, mCommunalView);
|
||||
keyguardUserSwitcherView);
|
||||
|
||||
// Update keyguard bottom area
|
||||
int index = mView.indexOfChild(mKeyguardBottomArea);
|
||||
@@ -1428,10 +1358,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
int stackScrollerPadding;
|
||||
boolean onKeyguard = isOnKeyguard();
|
||||
|
||||
if (onKeyguard) {
|
||||
updateCommunalViewAppearance();
|
||||
}
|
||||
|
||||
if (onKeyguard || forceClockUpdate) {
|
||||
updateClockAppearance();
|
||||
}
|
||||
@@ -1457,22 +1383,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
mAnimateNextPositionUpdate = false;
|
||||
}
|
||||
|
||||
private void updateCommunalViewAppearance() {
|
||||
if (mCommunalViewController == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
float expandedFraction =
|
||||
mScreenOffAnimationController.shouldExpandNotifications()
|
||||
? 1.0f : getExpandedFraction();
|
||||
mCommunalPositionAlgorithm.setup(expandedFraction, mCommunalView.getHeight());
|
||||
mCommunalPositionAlgorithm.run(mCommunalPositionResult);
|
||||
boolean animate =
|
||||
mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending()
|
||||
|| mAnimateNextPositionUpdate;
|
||||
mCommunalViewController.updatePosition(mCommunalPositionResult.communalY, animate);
|
||||
}
|
||||
|
||||
private void updateClockAppearance() {
|
||||
int userSwitcherPreferredY = mStatusBarHeaderHeightKeyguard;
|
||||
boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
|
||||
@@ -1547,9 +1457,8 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
private void updateKeyguardStatusViewAlignment(boolean animate) {
|
||||
boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
|
||||
.getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
|
||||
boolean hasCommunalSurface = mCommunalSource != null && mCommunalSource.get() != null;
|
||||
boolean shouldBeCentered = !mShouldUseSplitNotificationShade
|
||||
|| (!hasVisibleNotifications && !hasCommunalSurface) || mDozing;
|
||||
boolean shouldBeCentered = !mShouldUseSplitNotificationShade || !hasVisibleNotifications
|
||||
|| mDozing;
|
||||
if (mStatusViewCentered != shouldBeCentered) {
|
||||
mStatusViewCentered = shouldBeCentered;
|
||||
ConstraintSet constraintSet = new ConstraintSet();
|
||||
@@ -1579,11 +1488,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
* @return the maximum keyguard notifications that can fit on the screen
|
||||
*/
|
||||
private int computeMaxKeyguardNotifications() {
|
||||
// Do not show any notifications on the keyguard if a communal source is set.
|
||||
if (mCommunalSource != null && mCommunalSource.get() != null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding();
|
||||
int notificationPadding = Math.max(
|
||||
1, mResources.getDimensionPixelSize(R.dimen.notification_divider_height));
|
||||
@@ -1707,12 +1611,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateCommunal() {
|
||||
if (mCommunalViewController != null) {
|
||||
mCommunalViewController.setAlpha(mKeyguardOnlyContentAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateClock() {
|
||||
float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
|
||||
mKeyguardStatusViewController.setAlpha(alpha);
|
||||
@@ -2483,10 +2381,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
mSplitShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
|
||||
mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
|
||||
mSplitShadeHeaderController.setShadeExpanded(mQsVisible);
|
||||
|
||||
if (mCommunalViewController != null) {
|
||||
mCommunalViewController.updateQsExpansion(qsExpansionFraction);
|
||||
}
|
||||
}
|
||||
|
||||
private void onStackYChanged(boolean shouldAnimate) {
|
||||
@@ -2849,10 +2743,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
}
|
||||
mTransitionToFullShadeQSPosition = position;
|
||||
updateQsExpansion();
|
||||
|
||||
if (mCommunalViewController != null) {
|
||||
mCommunalViewController.updateShadeExpansion(mTransitioningToFullShadeProgress);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2876,7 +2766,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
updateKeyguardBottomAreaAlpha();
|
||||
}
|
||||
updateClock();
|
||||
updateCommunal();
|
||||
}
|
||||
|
||||
private void trackMovement(MotionEvent event) {
|
||||
@@ -4770,14 +4659,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
goingToFullShade,
|
||||
mBarState);
|
||||
|
||||
if (mCommunalViewController != null) {
|
||||
mCommunalViewController.setKeyguardStatusViewVisibility(
|
||||
statusBarState,
|
||||
keyguardFadingAway,
|
||||
goingToFullShade,
|
||||
mBarState);
|
||||
}
|
||||
|
||||
setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
|
||||
|
||||
mBarState = statusBarState;
|
||||
@@ -4905,25 +4786,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
setExpandedFraction(1f);
|
||||
}
|
||||
|
||||
private void setCommunalSource(WeakReference<CommunalSource> source) {
|
||||
CommunalSource existingSource = mCommunalSource != null ? mCommunalSource.get() : null;
|
||||
|
||||
if (existingSource != null) {
|
||||
mCommunalViewController.show(null /*source*/);
|
||||
}
|
||||
|
||||
mCommunalSource = source;
|
||||
|
||||
CommunalSource currentSource = mCommunalSource != null ? mCommunalSource.get() : null;
|
||||
// Set source and register callback
|
||||
if (currentSource != null && mCommunalViewController != null) {
|
||||
mCommunalViewController.show(source);
|
||||
}
|
||||
|
||||
updateKeyguardStatusViewAlignment(true /*animate*/);
|
||||
updateMaxDisplayedNotifications(true /*recompute*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the overstretch amount in raw pixels when dragging down.
|
||||
*/
|
||||
@@ -4941,7 +4803,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
.addTagListener(QS.TAG, mFragmentListener);
|
||||
mStatusBarStateController.addCallback(mStatusBarStateListener);
|
||||
mConfigurationController.addCallback(mConfigurationListener);
|
||||
mCommunalSourceMonitor.addCallback(mCommunalSourceMonitorCallback);
|
||||
// Theme might have changed between inflating this view and attaching it to the
|
||||
// window, so
|
||||
// force a call to onThemeChanged
|
||||
@@ -4949,7 +4810,6 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
mFalsingManager.addTapListener(mFalsingTapListener);
|
||||
mKeyguardIndicationController.init();
|
||||
registerSettingsChangeListener();
|
||||
mCommunalStateController.addCallback(mCommunalStateCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4959,9 +4819,7 @@ public class NotificationPanelViewController extends PanelViewController
|
||||
.removeTagListener(QS.TAG, mFragmentListener);
|
||||
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
||||
mConfigurationController.removeCallback(mConfigurationListener);
|
||||
mCommunalSourceMonitor.removeCallback(mCommunalSourceMonitorCallback);
|
||||
mFalsingManager.removeTapListener(mFalsingTapListener);
|
||||
mCommunalStateController.removeCallback(mCommunalStateCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.android.keyguard.KeyguardVisibilityHelper;
|
||||
import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
|
||||
import com.android.settingslib.drawable.CircleFramedDrawable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
@@ -119,7 +118,6 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
|
||||
@Main Resources resources,
|
||||
ScreenLifecycle screenLifecycle,
|
||||
UserSwitcherController userSwitcherController,
|
||||
CommunalStateController communalStateController,
|
||||
KeyguardStateController keyguardStateController,
|
||||
FalsingManager falsingManager,
|
||||
ConfigurationController configurationController,
|
||||
@@ -138,10 +136,9 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
|
||||
mFalsingManager = falsingManager;
|
||||
mConfigurationController = configurationController;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
|
||||
keyguardStateController, dozeParameters,
|
||||
screenOffAnimationController, /* animateYPos= */ false,
|
||||
/* visibleOnCommunal= */ false);
|
||||
screenOffAnimationController, /* animateYPos= */ false);
|
||||
mUserSwitchDialogController = userSwitchDialogController;
|
||||
mUiEventLogger = uiEventLogger;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
|
||||
import com.android.settingslib.drawable.CircleFramedDrawable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
@@ -158,7 +157,6 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
|
||||
LayoutInflater layoutInflater,
|
||||
ScreenLifecycle screenLifecycle,
|
||||
UserSwitcherController userSwitcherController,
|
||||
CommunalStateController communalStateController,
|
||||
KeyguardStateController keyguardStateController,
|
||||
SysuiStatusBarStateController statusBarStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
@@ -174,10 +172,9 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mAdapter = new KeyguardUserAdapter(mContext, resources, layoutInflater,
|
||||
mUserSwitcherController, this);
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
|
||||
keyguardStateController, dozeParameters,
|
||||
screenOffAnimationController, /* animateYPos= */ false,
|
||||
/* visibleOnCommunal= */ false);
|
||||
screenOffAnimationController, /* animateYPos= */ false);
|
||||
mBackground = new KeyguardUserSwitcherScrim(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@ import android.content.IntentFilter;
|
||||
import android.os.PatternMatcher;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.communal.CommunalSource;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -36,8 +34,8 @@ import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* {@link PackageObserver} allows for monitoring the system for changes relating to a particular
|
||||
* package. This can be used by {@link CommunalSource} clients to detect when a related package
|
||||
* has changed and reloading is necessary.
|
||||
* package. This can be used by clients to detect when a related package has changed and reloading
|
||||
* is necessary.
|
||||
*/
|
||||
public class PackageObserver implements Observer {
|
||||
private static final String TAG = "PackageObserver";
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
|
||||
@@ -50,8 +49,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private KeyguardStateController mKeyguardStateController;
|
||||
@Mock
|
||||
private CommunalStateController mCommunalStateController;
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@Mock
|
||||
ConfigurationController mConfigurationController;
|
||||
@@ -76,7 +73,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
|
||||
mKeyguardClockSwitchController,
|
||||
mKeyguardStateController,
|
||||
mKeyguardUpdateMonitor,
|
||||
mCommunalStateController,
|
||||
mConfigurationController,
|
||||
mDozeParameters,
|
||||
mKeyguardUnlockAnimationController,
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
public class KeyguardVisibilityHelperTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private CommunalStateController mCommunalStateController;
|
||||
@Mock
|
||||
private KeyguardStateController mKeyguardStateController;
|
||||
@Mock
|
||||
com.android.systemui.statusbar.phone.DozeParameters mDozeParameters;
|
||||
@Mock
|
||||
ScreenOffAnimationController mScreenOffAnimationController;
|
||||
@Mock
|
||||
ViewPropertyAnimator mViewPropertyAnimator;
|
||||
@Mock
|
||||
View mTargetView;
|
||||
|
||||
private KeyguardVisibilityHelper mKeyguardVisibilityHelper;
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mTargetView.animate()).thenReturn(mViewPropertyAnimator);
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mTargetView,
|
||||
mCommunalStateController, mKeyguardStateController, mDozeParameters,
|
||||
mScreenOffAnimationController, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHideOnCommunal() {
|
||||
// Verify view is hidden when communal is visible.
|
||||
when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
|
||||
mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
|
||||
false, StatusBarState.KEYGUARD);
|
||||
verify(mTargetView).setVisibility(View.GONE);
|
||||
verify(mTargetView).setAlpha(1.0f);
|
||||
|
||||
// Verify view is shown when communal is not visible.
|
||||
when(mCommunalStateController.getCommunalViewShowing()).thenReturn(false);
|
||||
mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
|
||||
false, StatusBarState.KEYGUARD);
|
||||
verify(mTargetView).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVisibleOnCommunal() {
|
||||
when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
|
||||
when(mKeyguardStateController.isOccluded()).thenReturn(false);
|
||||
|
||||
// Verify that helpers constructed with visibility on communal are not hidden when communal
|
||||
// is present.
|
||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mTargetView,
|
||||
mCommunalStateController, mKeyguardStateController, mDozeParameters,
|
||||
mScreenOffAnimationController, false, true);
|
||||
mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
|
||||
false, StatusBarState.KEYGUARD);
|
||||
verify(mTargetView).setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class CommunalHostViewControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private CommunalStateController mCommunalStateController;
|
||||
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
|
||||
@Mock
|
||||
private KeyguardStateController mKeyguardStateController;
|
||||
|
||||
@Mock
|
||||
private StatusBarStateController mStatusBarStateController;
|
||||
|
||||
@Mock
|
||||
private CommunalHostView mCommunalView;
|
||||
|
||||
@Mock
|
||||
private DozeParameters mDozeParameters;
|
||||
|
||||
@Mock
|
||||
private ScreenOffAnimationController mScreenOffAnimationController;
|
||||
|
||||
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
private CommunalHostViewController mController;
|
||||
|
||||
@Mock
|
||||
private CommunalSource mCommunalSource;
|
||||
|
||||
@Mock
|
||||
private View mChildView;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mKeyguardStateController.isShowing()).thenReturn(true);
|
||||
when(mCommunalView.isAttachedToWindow()).thenReturn(true);
|
||||
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
|
||||
|
||||
mController = new CommunalHostViewController(mFakeExecutor, mCommunalStateController,
|
||||
mKeyguardUpdateMonitor, mKeyguardStateController, mDozeParameters,
|
||||
mScreenOffAnimationController, mStatusBarStateController, mCommunalView);
|
||||
mController.init();
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
Mockito.clearInvocations(mCommunalView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShow() {
|
||||
ArgumentCaptor<KeyguardStateController.Callback> callbackCapture =
|
||||
ArgumentCaptor.forClass(KeyguardStateController.Callback.class);
|
||||
|
||||
// Capture callback value for later use.
|
||||
verify(mKeyguardStateController).addCallback(callbackCapture.capture());
|
||||
|
||||
// Verify the communal view is shown when the controller is initialized with keyguard
|
||||
// showing (see setup).
|
||||
mController.show(new WeakReference<>(mCommunalSource));
|
||||
mFakeExecutor.runAllReady();
|
||||
verify(mCommunalView).setVisibility(View.VISIBLE);
|
||||
|
||||
// Trigger keyguard off to ensure visibility of communal view is changed accordingly.
|
||||
when(mKeyguardStateController.isShowing()).thenReturn(false);
|
||||
callbackCapture.getValue().onKeyguardShowingChanged();
|
||||
mFakeExecutor.runAllReady();
|
||||
verify(mCommunalView).setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHideOnOcclude() {
|
||||
ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
|
||||
ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
|
||||
|
||||
// Capture callback value for later use.
|
||||
verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
|
||||
|
||||
// Establish a visible communal view.
|
||||
mController.show(new WeakReference<>(mCommunalSource));
|
||||
mFakeExecutor.runAllReady();
|
||||
verify(mCommunalView).setVisibility(View.VISIBLE);
|
||||
Mockito.clearInvocations(mCommunalView);
|
||||
|
||||
// Occlude.
|
||||
Mockito.clearInvocations(mCommunalView);
|
||||
callbackCapture.getValue().onKeyguardOccludedChanged(true);
|
||||
mFakeExecutor.runAllReady();
|
||||
verify(mCommunalView).setVisibility(View.INVISIBLE);
|
||||
|
||||
// Unocclude.
|
||||
Mockito.clearInvocations(mCommunalView);
|
||||
callbackCapture.getValue().onKeyguardOccludedChanged(false);
|
||||
mFakeExecutor.runAllReady();
|
||||
verify(mCommunalView).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReportOcclusion() {
|
||||
// Ensure CommunalHostViewController reports view occluded when either the QS or Shade is
|
||||
// expanded.
|
||||
clearInvocations(mCommunalStateController);
|
||||
mController.updateShadeExpansion(0);
|
||||
verify(mCommunalStateController).setCommunalViewOccluded(false);
|
||||
clearInvocations(mCommunalStateController);
|
||||
mController.updateQsExpansion(.5f);
|
||||
verify(mCommunalStateController).setCommunalViewOccluded(true);
|
||||
clearInvocations(mCommunalStateController);
|
||||
mController.updateShadeExpansion(.7f);
|
||||
verify(mCommunalStateController).setCommunalViewOccluded(true);
|
||||
clearInvocations(mCommunalStateController);
|
||||
mController.updateShadeExpansion(0);
|
||||
verify(mCommunalStateController).setCommunalViewOccluded(true);
|
||||
clearInvocations(mCommunalStateController);
|
||||
mController.updateQsExpansion(0f);
|
||||
verify(mCommunalStateController).setCommunalViewOccluded(false);
|
||||
clearInvocations(mCommunalStateController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommunalStateControllerHideNotified() {
|
||||
ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
|
||||
ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
|
||||
|
||||
// Capture callback value for later use.
|
||||
verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
|
||||
|
||||
// Establish a visible communal view.
|
||||
mController.show(new WeakReference<>(mCommunalSource));
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
// Occlude
|
||||
clearInvocations(mCommunalStateController);
|
||||
callbackCapture.getValue().onKeyguardOccludedChanged(true);
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
// Verify state controller is notified communal view is hidden.
|
||||
verify(mCommunalStateController).setCommunalViewShowing(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlphaPropagation() {
|
||||
final float alpha = 0.8f;
|
||||
|
||||
// Ensure alpha setting is propagated to children.
|
||||
when(mCommunalView.getChildCount()).thenReturn(1);
|
||||
when(mCommunalView.getChildAt(0)).thenReturn(mChildView);
|
||||
mController.setAlpha(alpha);
|
||||
verify(mChildView).setAlpha(alpha);
|
||||
verify(mCommunalView).setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleShowRequestSuppression() {
|
||||
// Ensure first request invokes source.
|
||||
mController.show(new WeakReference<>(mCommunalSource));
|
||||
mFakeExecutor.runAllReady();
|
||||
verify(mCommunalSource).requestCommunalView(any());
|
||||
clearInvocations(mCommunalSource);
|
||||
|
||||
// Ensure subsequent identical request is suppressed
|
||||
mController.show(new WeakReference<>(mCommunalSource));
|
||||
mFakeExecutor.runAllReady();
|
||||
verify(mCommunalSource, never()).requestCommunalView(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoShowInvocationOnBouncer() {
|
||||
ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
|
||||
ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
|
||||
|
||||
// Capture callback value for later use.
|
||||
verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
|
||||
|
||||
// Set source so it will be cleared if in invalid state.
|
||||
mController.show(new WeakReference<>(mCommunalSource));
|
||||
mFakeExecutor.runAllReady();
|
||||
clearInvocations(mCommunalStateController, mCommunalView);
|
||||
|
||||
// Change bouncer to showing.
|
||||
callbackCapture.getValue().onKeyguardBouncerChanged(true);
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
// Verify that there were no requests to remove all child views or set the communal
|
||||
// state to not showing.
|
||||
verify(mCommunalStateController, never()).setCommunalViewShowing(eq(false));
|
||||
verify(mCommunalView, never()).removeAllViews();
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.communal.CommunalHostViewPositionAlgorithm.Result;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
@SmallTest
|
||||
public class CommunalHostViewPositionAlgorithmTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testOutput() {
|
||||
final float expansion = 0.25f;
|
||||
final int height = 120;
|
||||
|
||||
final CommunalHostViewPositionAlgorithm algorithm = new CommunalHostViewPositionAlgorithm();
|
||||
algorithm.setup(expansion, height);
|
||||
final Result result = new Result();
|
||||
algorithm.run(result);
|
||||
|
||||
// Verify the communal view is shifted offscreen vertically by the correct amount.
|
||||
assertThat((1 - expansion) * -height).isEqualTo(result.communalY);
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.communal.conditions.CommunalSettingCondition;
|
||||
import com.android.systemui.util.condition.Condition;
|
||||
import com.android.systemui.util.settings.FakeSettings;
|
||||
import com.android.systemui.utils.os.FakeHandler;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class CommunalSettingConditionTest extends SysuiTestCase {
|
||||
private FakeSettings mSecureSettings;
|
||||
private CommunalSettingCondition mCondition;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
final FakeHandler handler = new FakeHandler(Looper.getMainLooper());
|
||||
mSecureSettings = new FakeSettings();
|
||||
mCondition = new CommunalSettingCondition(handler, mSecureSettings);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addCallback_communalSettingEnabled_immediatelyReportsTrue() {
|
||||
updateCommunalSetting(true);
|
||||
|
||||
final Condition.Callback callback = mock(Condition.Callback.class);
|
||||
mCondition.addCallback(callback);
|
||||
verify(callback).onConditionChanged(mCondition);
|
||||
assertThat(mCondition.isConditionMet()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addCallback_communalSettingDisabled_noReport() {
|
||||
updateCommunalSetting(false);
|
||||
|
||||
final Condition.Callback callback = mock(Condition.Callback.class);
|
||||
mCondition.addCallback(callback);
|
||||
verify(callback, never()).onConditionChanged(eq(mCondition));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateCallback_communalSettingEnabled_reportsTrue() {
|
||||
updateCommunalSetting(false);
|
||||
|
||||
final Condition.Callback callback = mock(Condition.Callback.class);
|
||||
mCondition.addCallback(callback);
|
||||
clearInvocations(callback);
|
||||
|
||||
updateCommunalSetting(true);
|
||||
verify(callback).onConditionChanged(mCondition);
|
||||
assertThat(mCondition.isConditionMet()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateCallback_communalSettingDisabled_reportsFalse() {
|
||||
updateCommunalSetting(true);
|
||||
|
||||
final Condition.Callback callback = mock(Condition.Callback.class);
|
||||
mCondition.addCallback(callback);
|
||||
clearInvocations(callback);
|
||||
|
||||
updateCommunalSetting(false);
|
||||
verify(callback).onConditionChanged(mCondition);
|
||||
assertThat(mCondition.isConditionMet()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateCallback_communalSettingDidNotChange_neverReportDup() {
|
||||
updateCommunalSetting(true);
|
||||
|
||||
final Condition.Callback callback = mock(Condition.Callback.class);
|
||||
mCondition.addCallback(callback);
|
||||
clearInvocations(callback);
|
||||
|
||||
updateCommunalSetting(true);
|
||||
verify(callback, never()).onConditionChanged(mCondition);
|
||||
assertThat(mCondition.isConditionMet()).isTrue();
|
||||
}
|
||||
|
||||
private void updateCommunalSetting(boolean value) {
|
||||
mSecureSettings.putIntForUser(Settings.Secure.COMMUNAL_MODE_ENABLED, value ? 1 : 0,
|
||||
UserHandle.USER_SYSTEM);
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.condition.Monitor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
public class CommunalSourceMonitorTest extends SysuiTestCase {
|
||||
@Mock private Monitor mCommunalConditionsMonitor;
|
||||
|
||||
@Captor private ArgumentCaptor<Monitor.Callback> mConditionsCallbackCaptor;
|
||||
|
||||
private CommunalSourceMonitor mCommunalSourceMonitor;
|
||||
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mCommunalSourceMonitor = new CommunalSourceMonitor(mExecutor, mCommunalConditionsMonitor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSourceAddedBeforeCallbackAdded() {
|
||||
final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
|
||||
final CommunalSource source = mock(CommunalSource.class);
|
||||
|
||||
setSource(source);
|
||||
mCommunalSourceMonitor.addCallback(callback);
|
||||
setConditionsMet(true);
|
||||
|
||||
verifyOnSourceAvailableCalledWith(callback, source);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveCallback() {
|
||||
final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
|
||||
final CommunalSource source = mock(CommunalSource.class);
|
||||
|
||||
mCommunalSourceMonitor.addCallback(callback);
|
||||
mCommunalSourceMonitor.removeCallback(callback);
|
||||
setSource(source);
|
||||
|
||||
verify(callback, never()).onSourceAvailable(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddCallbackWithConditionsMet() {
|
||||
final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
|
||||
final CommunalSource source = mock(CommunalSource.class);
|
||||
|
||||
mCommunalSourceMonitor.addCallback(callback);
|
||||
setConditionsMet(true);
|
||||
clearInvocations(callback);
|
||||
setSource(source);
|
||||
|
||||
verifyOnSourceAvailableCalledWith(callback, source);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddCallbackWithConditionsNotMet() {
|
||||
final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
|
||||
final CommunalSource source = mock(CommunalSource.class);
|
||||
|
||||
mCommunalSourceMonitor.addCallback(callback);
|
||||
setConditionsMet(false);
|
||||
setSource(source);
|
||||
|
||||
verify(callback, never()).onSourceAvailable(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConditionsAreMetAfterCallbackAdded() {
|
||||
final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
|
||||
final CommunalSource source = mock(CommunalSource.class);
|
||||
|
||||
mCommunalSourceMonitor.addCallback(callback);
|
||||
setSource(source);
|
||||
|
||||
// The callback should not have executed since communal is disabled.
|
||||
verify(callback, never()).onSourceAvailable(any());
|
||||
|
||||
// The callback should execute when all conditions are met.
|
||||
setConditionsMet(true);
|
||||
verifyOnSourceAvailableCalledWith(callback, source);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConditionsNoLongerMetAfterCallbackAdded() {
|
||||
final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
|
||||
final CommunalSource source = mock(CommunalSource.class);
|
||||
|
||||
mCommunalSourceMonitor.addCallback(callback);
|
||||
setSource(source);
|
||||
setConditionsMet(true);
|
||||
verifyOnSourceAvailableCalledWith(callback, source);
|
||||
|
||||
// The callback should execute again when conditions are no longer met, with a value of
|
||||
// null.
|
||||
setConditionsMet(false);
|
||||
verify(callback).onSourceAvailable(null);
|
||||
}
|
||||
|
||||
private void verifyOnSourceAvailableCalledWith(CommunalSourceMonitor.Callback callback,
|
||||
CommunalSource source) {
|
||||
final ArgumentCaptor<WeakReference<CommunalSource>> sourceCapture =
|
||||
ArgumentCaptor.forClass(WeakReference.class);
|
||||
verify(callback).onSourceAvailable(sourceCapture.capture());
|
||||
assertThat(sourceCapture.getValue().get()).isEqualTo(source);
|
||||
}
|
||||
|
||||
// Pushes an update on whether the communal conditions are met, assuming that a callback has
|
||||
// been registered with the communal conditions monitor.
|
||||
private void setConditionsMet(boolean value) {
|
||||
mExecutor.runAllReady();
|
||||
verify(mCommunalConditionsMonitor).addCallback(mConditionsCallbackCaptor.capture());
|
||||
final Monitor.Callback conditionsCallback =
|
||||
mConditionsCallbackCaptor.getValue();
|
||||
conditionsCallback.onConditionsChanged(value);
|
||||
mExecutor.runAllReady();
|
||||
}
|
||||
|
||||
private void setSource(CommunalSource source) {
|
||||
mCommunalSourceMonitor.setSource(source);
|
||||
mExecutor.runAllReady();
|
||||
}
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;;
|
||||
import com.android.systemui.util.ref.GcWeakReference;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class CommunalSourcePrimerTest extends SysuiTestCase {
|
||||
private static final String TEST_COMPONENT_NAME = "com.google.tests/.CommunalService";
|
||||
private static final int MAX_RETRIES = 5;
|
||||
private static final int RETRY_DELAY_MS = 1000;
|
||||
private static final int CONNECTION_MIN_DURATION_MS = 5000;
|
||||
|
||||
// A simple implementation of {@link CommunalSource.Observer} to capture a callback value.
|
||||
// Used to ensure the references to a {@link CommunalSource.Observer.Callback} can be fully
|
||||
// removed.
|
||||
private static class FakeObserver implements CommunalSource.Observer {
|
||||
public GcWeakReference<Callback> mLastCallback;
|
||||
|
||||
@Override
|
||||
public void addCallback(Callback callback) {
|
||||
mLastCallback = new GcWeakReference<>(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallback(Callback callback) {
|
||||
if (mLastCallback.get() == callback) {
|
||||
mLastCallback = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A simple implementation of {@link CommunalSource} to capture callback values. This
|
||||
// implementation better emulates the {@link WeakReference} wrapping behavior of
|
||||
// {@link CommunalSource} implementations than a mock.
|
||||
private static class FakeSource implements CommunalSource {
|
||||
@Override
|
||||
public ListenableFuture<CommunalViewResult> requestCommunalView(Context context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
|
||||
private FakeSystemClock mFakeClock = new FakeSystemClock();
|
||||
private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeClock);
|
||||
|
||||
private FakeSource mSource = new FakeSource();
|
||||
|
||||
@Mock
|
||||
private CommunalSourceMonitor mCommunalSourceMonitor;
|
||||
|
||||
@Mock
|
||||
private CommunalSource.Connector mConnector;
|
||||
|
||||
@Mock
|
||||
private CommunalSource.Connection mConnection;
|
||||
|
||||
private FakeObserver mObserver = new FakeObserver();
|
||||
|
||||
private CommunalSourcePrimer mPrimer;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mResources.getInteger(R.integer.config_communalSourceMaxReconnectAttempts))
|
||||
.thenReturn(MAX_RETRIES);
|
||||
when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
|
||||
.thenReturn(RETRY_DELAY_MS);
|
||||
when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
|
||||
.thenReturn(RETRY_DELAY_MS);
|
||||
when(mResources.getString(R.string.config_communalSourceComponent))
|
||||
.thenReturn(TEST_COMPONENT_NAME);
|
||||
when(mResources.getInteger(R.integer.config_connectionMinDuration))
|
||||
.thenReturn(CONNECTION_MIN_DURATION_MS);
|
||||
|
||||
mPrimer = new CommunalSourcePrimer(mContext, mResources, mFakeClock, mFakeExecutor,
|
||||
mCommunalSourceMonitor, Optional.of(mConnector), Optional.of(mObserver));
|
||||
}
|
||||
|
||||
private CommunalSource.Connection.Callback captureCallbackAndSend(
|
||||
CommunalSource.Connector connector, Optional<CommunalSource> source) {
|
||||
ArgumentCaptor<CommunalSource.Connection.Callback> connectionCallback =
|
||||
ArgumentCaptor.forClass(CommunalSource.Connection.Callback.class);
|
||||
|
||||
verify(connector).connect(connectionCallback.capture());
|
||||
Mockito.clearInvocations(connector);
|
||||
|
||||
final CommunalSource.Connection.Callback callback = connectionCallback.getValue();
|
||||
callback.onSourceEstablished(source);
|
||||
|
||||
return callback;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnect() {
|
||||
mPrimer.onBootCompleted();
|
||||
captureCallbackAndSend(mConnector, Optional.of(mSource));
|
||||
verify(mCommunalSourceMonitor).setSource(mSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetryOnBindFailure() throws Exception {
|
||||
mPrimer.onBootCompleted();
|
||||
|
||||
// Verify attempts happen. Note that we account for the retries plus initial attempt, which
|
||||
// is not scheduled.
|
||||
for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
|
||||
captureCallbackAndSend(mConnector, Optional.empty());
|
||||
mFakeExecutor.advanceClockToNext();
|
||||
mFakeExecutor.runAllReady();
|
||||
}
|
||||
|
||||
verify(mCommunalSourceMonitor, never()).setSource(Mockito.notNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetryOnDisconnectFailure() throws Exception {
|
||||
mPrimer.onBootCompleted();
|
||||
// Verify attempts happen. Note that we account for the retries plus initial attempt, which
|
||||
// is not scheduled.
|
||||
for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
|
||||
final CommunalSource.Connection.Callback callback =
|
||||
captureCallbackAndSend(mConnector, Optional.of(mSource));
|
||||
verify(mCommunalSourceMonitor).setSource(Mockito.notNull());
|
||||
clearInvocations(mCommunalSourceMonitor);
|
||||
callback.onDisconnected();
|
||||
mFakeExecutor.advanceClockToNext();
|
||||
mFakeExecutor.runAllReady();
|
||||
}
|
||||
|
||||
verify(mConnector, never()).connect(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttemptOnPackageChange() {
|
||||
mPrimer.onBootCompleted();
|
||||
captureCallbackAndSend(mConnector, Optional.empty());
|
||||
|
||||
mObserver.mLastCallback.get().onSourceChanged();
|
||||
|
||||
verify(mConnector, times(1)).connect(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisconnect() {
|
||||
mPrimer.onBootCompleted();
|
||||
final CommunalSource.Connection.Callback callback =
|
||||
captureCallbackAndSend(mConnector, Optional.of(mSource));
|
||||
verify(mCommunalSourceMonitor).setSource(mSource);
|
||||
|
||||
mFakeClock.advanceTime(CONNECTION_MIN_DURATION_MS + 1);
|
||||
callback.onDisconnected();
|
||||
|
||||
verify(mConnector).connect(any());
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class CommunalStateControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private CommunalStateController.Callback mCallback;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultCommunalViewShowingState() {
|
||||
// The state controller should report the communal view as not showing by default.
|
||||
final CommunalStateController stateController = new CommunalStateController();
|
||||
assertThat(stateController.getCommunalViewShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyCommunalSurfaceShow() {
|
||||
final CommunalStateController stateController = new CommunalStateController();
|
||||
stateController.addCallback(mCallback);
|
||||
|
||||
// Verify setting communal view to showing propagates to callback.
|
||||
stateController.setCommunalViewShowing(true);
|
||||
verify(mCallback).onCommunalViewShowingChanged();
|
||||
assertThat(stateController.getCommunalViewShowing()).isTrue();
|
||||
|
||||
clearInvocations(mCallback);
|
||||
|
||||
// Verify setting communal view to not showing propagates to callback.
|
||||
stateController.setCommunalViewShowing(false);
|
||||
verify(mCallback).onCommunalViewShowingChanged();
|
||||
assertThat(stateController.getCommunalViewShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallbackRegistration() {
|
||||
final CommunalStateController stateController = new CommunalStateController();
|
||||
stateController.addCallback(mCallback);
|
||||
|
||||
// Verify setting communal view to showing propagates to callback.
|
||||
stateController.setCommunalViewShowing(true);
|
||||
verify(mCallback).onCommunalViewShowingChanged();
|
||||
|
||||
clearInvocations(mCallback);
|
||||
|
||||
stateController.removeCallback(mCallback);
|
||||
clearInvocations(mCallback);
|
||||
|
||||
// Verify callback not invoked after removing from state controller.
|
||||
stateController.setCommunalViewShowing(false);
|
||||
verify(mCallback, never()).onCommunalViewShowingChanged();
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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.communal;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class PackageObserverTest extends SysuiTestCase {
|
||||
private static final String PACKAGE_NAME = "com.foo.bar";
|
||||
|
||||
@Mock
|
||||
Context mContext;
|
||||
|
||||
@Mock
|
||||
CommunalSource.Observer.Callback mCallback;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChange() {
|
||||
final PackageObserver observer = new PackageObserver(mContext, PACKAGE_NAME);
|
||||
final ArgumentCaptor<BroadcastReceiver> receiverCapture =
|
||||
ArgumentCaptor.forClass(BroadcastReceiver.class);
|
||||
|
||||
observer.addCallback(mCallback);
|
||||
|
||||
// Verify broadcast receiver registered.
|
||||
verify(mContext).registerReceiver(receiverCapture.capture(), any(), anyInt());
|
||||
|
||||
// Simulate package change.
|
||||
receiverCapture.getValue().onReceive(mContext, new Intent());
|
||||
|
||||
// Check that callback was informed.
|
||||
verify(mCallback).onSourceChanged();
|
||||
|
||||
observer.removeCallback(mCallback);
|
||||
|
||||
// Make sure receiver is unregistered on last callback removal
|
||||
verify(mContext).unregisterReceiver(receiverCapture.getValue());
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* 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.statusbar.notification.collection.coordinator;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
|
||||
@SmallTest
|
||||
public class CommunalCoordinatorTest extends SysuiTestCase {
|
||||
private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
@Mock
|
||||
CommunalStateController mCommunalStateController;
|
||||
@Mock
|
||||
NotificationEntryManager mNotificationEntryManager;
|
||||
@Mock
|
||||
NotificationLockscreenUserManager mNotificationLockscreenUserManager;
|
||||
@Mock
|
||||
NotifPipeline mNotifPipeline;
|
||||
@Mock
|
||||
NotificationEntry mNotificationEntry;
|
||||
@Mock
|
||||
Pluggable.PluggableListener mFilterListener;
|
||||
|
||||
CommunalCoordinator mCoordinator;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mCoordinator = new CommunalCoordinator(mExecutor, mNotificationEntryManager,
|
||||
mNotificationLockscreenUserManager, mCommunalStateController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationSuppressionInCommunal() {
|
||||
mCoordinator.attach(mNotifPipeline);
|
||||
final ArgumentCaptor<CommunalStateController.Callback> stateCallbackCaptor =
|
||||
ArgumentCaptor.forClass(CommunalStateController.Callback.class);
|
||||
verify(mCommunalStateController).addCallback(stateCallbackCaptor.capture());
|
||||
|
||||
final CommunalStateController.Callback stateCallback = stateCallbackCaptor.getValue();
|
||||
|
||||
final ArgumentCaptor<NotifFilter> filterCaptor =
|
||||
ArgumentCaptor.forClass(NotifFilter.class);
|
||||
verify(mNotifPipeline).addPreGroupFilter(filterCaptor.capture());
|
||||
|
||||
final NotifFilter filter = filterCaptor.getValue();
|
||||
|
||||
// Verify that notifications are not filtered out by default.
|
||||
assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isFalse();
|
||||
|
||||
filter.setInvalidationListener(mFilterListener);
|
||||
|
||||
// Verify that notifications are filtered out when communal is showing and that the filter
|
||||
// pipeline is notified.
|
||||
when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
|
||||
stateCallback.onCommunalViewShowingChanged();
|
||||
// Make sure callback depends on executor to run.
|
||||
verify(mFilterListener, never()).onPluggableInvalidated(any());
|
||||
verify(mNotificationEntryManager, never()).updateNotifications(any());
|
||||
|
||||
mExecutor.runAllReady();
|
||||
|
||||
verify(mFilterListener).onPluggableInvalidated(any());
|
||||
verify(mNotificationEntryManager).updateNotifications(any());
|
||||
assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
@@ -88,12 +87,6 @@ import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.classifier.FalsingCollectorFake;
|
||||
import com.android.systemui.classifier.FalsingManagerFake;
|
||||
import com.android.systemui.communal.CommunalHostView;
|
||||
import com.android.systemui.communal.CommunalHostViewController;
|
||||
import com.android.systemui.communal.CommunalSource;
|
||||
import com.android.systemui.communal.CommunalSourceMonitor;
|
||||
import com.android.systemui.communal.CommunalStateController;
|
||||
import com.android.systemui.communal.dagger.CommunalViewComponent;
|
||||
import com.android.systemui.controls.dagger.ControlsComponent;
|
||||
import com.android.systemui.doze.DozeLog;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
@@ -157,7 +150,6 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -271,21 +263,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
|
||||
@Mock
|
||||
private CommunalViewComponent.Factory mCommunalViewComponentFactory;
|
||||
@Mock
|
||||
private CommunalViewComponent mCommunalViewComponent;
|
||||
@Mock
|
||||
private CommunalHostViewController mCommunalHostViewController;
|
||||
@Mock
|
||||
private CommunalSourceMonitor mCommunalSourceMonitor;
|
||||
@Mock
|
||||
private CommunalSource mCommunalSource;
|
||||
@Mock
|
||||
private CommunalHostView mCommunalHostView;
|
||||
@Mock
|
||||
private CommunalStateController mCommunalStateController;
|
||||
private CommunalStateController.Callback mCommunalStateControllerCallback;
|
||||
@Mock
|
||||
private KeyguardClockSwitchController mKeyguardClockSwitchController;
|
||||
@Mock
|
||||
private KeyguardStatusViewController mKeyguardStatusViewController;
|
||||
@@ -400,7 +377,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
|
||||
when(mView.findViewById(R.id.notification_stack_scroller))
|
||||
.thenReturn(mNotificationStackScrollLayout);
|
||||
when(mView.findViewById(R.id.communal_host)).thenReturn(mCommunalHostView);
|
||||
when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
|
||||
when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
|
||||
.thenReturn(mHeadsUpCallback);
|
||||
@@ -466,10 +442,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
.thenReturn(mKeyguardStatusBarViewComponent);
|
||||
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
|
||||
.thenReturn(mKeyguardStatusBarViewController);
|
||||
when(mCommunalViewComponentFactory.build(any()))
|
||||
.thenReturn(mCommunalViewComponent);
|
||||
when(mCommunalViewComponent.getCommunalHostViewController())
|
||||
.thenReturn(mCommunalHostViewController);
|
||||
when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
|
||||
.thenReturn(mKeyguardStatusView);
|
||||
when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean()))
|
||||
@@ -497,13 +469,13 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
|
||||
mFalsingManager, new FalsingCollectorFake(),
|
||||
mNotificationLockscreenUserManager, mNotificationEntryManager,
|
||||
mCommunalStateController, mKeyguardStateController,
|
||||
mKeyguardStateController,
|
||||
mStatusBarStateController,
|
||||
mStatusBarWindowStateController,
|
||||
mNotificationShadeWindowController,
|
||||
mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
|
||||
mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
|
||||
mCommunalSourceMonitor, mMetricsLogger, mActivityManager, mConfigurationController,
|
||||
mMetricsLogger, mActivityManager, mConfigurationController,
|
||||
() -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
|
||||
mConversationNotificationManager, mMediaHiearchyManager,
|
||||
mStatusBarKeyguardViewManager,
|
||||
@@ -513,7 +485,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
mKeyguardQsUserSwitchComponentFactory,
|
||||
mKeyguardUserSwitcherComponentFactory,
|
||||
mKeyguardStatusBarViewComponentFactory,
|
||||
mCommunalViewComponentFactory,
|
||||
mLockscreenShadeTransitionController,
|
||||
mGroupManager,
|
||||
mNotificationAreaController,
|
||||
@@ -1018,81 +989,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
verify(mKeyguardStatusViewController, never()).displayClock(LARGE, /* animate */ true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommunalhostViewControllerInit() {
|
||||
verify(mCommunalHostViewController, times(1)).init();
|
||||
clearInvocations(mCommunalHostViewController);
|
||||
givenViewAttached();
|
||||
verify(mCommunalHostViewController, never()).init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommunalSourceListening() {
|
||||
final ArgumentCaptor<CommunalSourceMonitor.Callback> monitorCallback =
|
||||
ArgumentCaptor.forClass(CommunalSourceMonitor.Callback.class);
|
||||
|
||||
givenViewAttached();
|
||||
verify(mCommunalSourceMonitor).addCallback(monitorCallback.capture());
|
||||
|
||||
final ArgumentCaptor<WeakReference<CommunalSource>> sourceCapture =
|
||||
ArgumentCaptor.forClass(WeakReference.class);
|
||||
|
||||
monitorCallback.getValue().onSourceAvailable(new WeakReference<>(mCommunalSource));
|
||||
mExecutor.runAllReady();
|
||||
verify(mCommunalHostViewController).show(sourceCapture.capture());
|
||||
assertThat(sourceCapture.getValue().get()).isEqualTo(mCommunalSource);
|
||||
|
||||
clearInvocations(mCommunalHostViewController);
|
||||
givenViewDetached();
|
||||
verify(mCommunalSourceMonitor).removeCallback(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyguardStatusViewUpdatedWithCommunalPresence() {
|
||||
givenViewAttached();
|
||||
|
||||
when(mResources.getBoolean(
|
||||
com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
|
||||
updateMultiUserSetting(true);
|
||||
|
||||
ArgumentCaptor<CommunalStateController.Callback> communalCallbackCapture =
|
||||
ArgumentCaptor.forClass(CommunalStateController.Callback.class);
|
||||
verify(mCommunalStateController).addCallback(communalCallbackCapture.capture());
|
||||
final CommunalStateController.Callback communalStateControllerCallback =
|
||||
communalCallbackCapture.getValue();
|
||||
|
||||
clearInvocations(mKeyguardStatusViewController, mKeyguardUserSwitcherController);
|
||||
// Ensure changes in communal visibility leads to setting the keyguard status view
|
||||
// visibility.
|
||||
communalStateControllerCallback.onCommunalViewShowingChanged();
|
||||
verify(mKeyguardStatusViewController).setKeyguardStatusViewVisibility(anyInt(),
|
||||
anyBoolean(), anyBoolean(), anyInt());
|
||||
verify(mKeyguardUserSwitcherController).setKeyguardUserSwitcherVisibility(anyInt(),
|
||||
anyBoolean(), anyBoolean(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommunalAlphaUpdate() {
|
||||
// Verify keyguard content alpha changes are propagate. Note the actual value set is not
|
||||
// checked since an interpolation is applied to the incoming value.
|
||||
mNotificationPanelViewController.setKeyguardOnlyContentAlpha(0.8f);
|
||||
verify(mCommunalHostViewController).setAlpha(anyFloat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommunalPositionUpdate() {
|
||||
// Verify that the communal position is updated on interaction with the
|
||||
// NotificationPanelViewController. Note that there a number of paths where the position
|
||||
// might be updated and therefore the check isn't strictly on a single invocation.
|
||||
clearInvocations(mCommunalHostViewController);
|
||||
final View.OnLayoutChangeListener layoutChangeListener =
|
||||
mNotificationPanelViewController.createLayoutChangeListener();
|
||||
mNotificationPanelViewController.mStatusBarStateController.setState(KEYGUARD);
|
||||
layoutChangeListener.onLayoutChange(mView, 0, 0, 200, 200, 0, 0, 200, 200);
|
||||
verify(mCommunalHostViewController, atLeast(1))
|
||||
.updatePosition(anyInt(), anyBoolean());
|
||||
}
|
||||
|
||||
private void triggerPositionClockAndNotifications() {
|
||||
mNotificationPanelViewController.closeQs();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import androidx.test.filters.SmallTest
|
||||
import com.android.internal.logging.UiEventLogger
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.communal.CommunalStateController
|
||||
import com.android.systemui.keyguard.ScreenLifecycle
|
||||
import com.android.systemui.plugins.FalsingManager
|
||||
import com.android.systemui.qs.user.UserSwitchDialogController
|
||||
@@ -54,9 +53,6 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
|
||||
@Mock
|
||||
private lateinit var userSwitcherController: UserSwitcherController
|
||||
|
||||
@Mock
|
||||
private lateinit var communalStateController: CommunalStateController
|
||||
|
||||
@Mock
|
||||
private lateinit var keyguardStateController: KeyguardStateController
|
||||
|
||||
@@ -99,7 +95,6 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
|
||||
context.resources,
|
||||
screenLifecycle,
|
||||
userSwitcherController,
|
||||
communalStateController,
|
||||
keyguardStateController,
|
||||
falsingManager,
|
||||
configurationController,
|
||||
|
||||
Reference in New Issue
Block a user