blob: 9e59acb6b5b9558899aef2761e393d9e0758aa6d [file] [log] [blame]
/*
* 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.unfold.util;
import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
import java.util.ArrayList;
import java.util.List;
/**
* Manages progress listeners that can have smaller lifespan than the unfold animation.
* Allows to limit getting transition updates to only when
* {@link ScopedUnfoldTransitionProgressProvider#setReadyToHandleTransition} is called
* with readyToHandleTransition = true
*
* If the transition has already started by the moment when the clients are ready to play
* the transition then it will report transition started callback and current animation progress.
*/
public final class ScopedUnfoldTransitionProgressProvider implements
UnfoldTransitionProgressProvider, TransitionProgressListener {
private static final float PROGRESS_UNSET = -1f;
@Nullable
private UnfoldTransitionProgressProvider mSource;
private final List<TransitionProgressListener> mListeners = new ArrayList<>();
private boolean mIsReadyToHandleTransition;
private boolean mIsTransitionRunning;
private float mLastTransitionProgress = PROGRESS_UNSET;
public ScopedUnfoldTransitionProgressProvider() {
this(null);
}
public ScopedUnfoldTransitionProgressProvider(
@Nullable UnfoldTransitionProgressProvider source) {
setSourceProvider(source);
}
/**
* Sets the source for the unfold transition progress updates,
* it replaces current provider if it is already set
* @param provider transition provider that emits transition progress updates
*/
public void setSourceProvider(@Nullable UnfoldTransitionProgressProvider provider) {
if (mSource != null) {
mSource.removeCallback(this);
}
if (provider != null) {
mSource = provider;
mSource.addCallback(this);
} else {
mSource = null;
}
}
/**
* Allows to notify this provide whether the listeners can play the transition or not.
* Call this method with readyToHandleTransition = true when all listeners
* are ready to consume the transition progress events.
* Call it with readyToHandleTransition = false when listeners can't process the events.
*/
public void setReadyToHandleTransition(boolean isReadyToHandleTransition) {
if (mIsTransitionRunning) {
if (isReadyToHandleTransition) {
mListeners.forEach(TransitionProgressListener::onTransitionStarted);
if (mLastTransitionProgress != PROGRESS_UNSET) {
mListeners.forEach(listener ->
listener.onTransitionProgress(mLastTransitionProgress));
}
} else {
mIsTransitionRunning = false;
mListeners.forEach(TransitionProgressListener::onTransitionFinished);
}
}
mIsReadyToHandleTransition = isReadyToHandleTransition;
}
@Override
public void addCallback(@NonNull TransitionProgressListener listener) {
mListeners.add(listener);
}
@Override
public void removeCallback(@NonNull TransitionProgressListener listener) {
mListeners.remove(listener);
}
@Override
public void destroy() {
mSource.removeCallback(this);
mSource.destroy();
}
@Override
public void onTransitionStarted() {
this.mIsTransitionRunning = true;
if (mIsReadyToHandleTransition) {
mListeners.forEach(TransitionProgressListener::onTransitionStarted);
}
}
@Override
public void onTransitionProgress(float progress) {
if (mIsReadyToHandleTransition) {
mListeners.forEach(listener -> listener.onTransitionProgress(progress));
}
mLastTransitionProgress = progress;
}
@Override
public void onTransitionFinished() {
if (mIsReadyToHandleTransition) {
mListeners.forEach(TransitionProgressListener::onTransitionFinished);
}
mIsTransitionRunning = false;
mLastTransitionProgress = PROGRESS_UNSET;
}
}