Merge "Register remote animation in JetpackTaskFragmentOrganizer" into sc-v2-dev
This commit is contained in:
@@ -62,6 +62,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
||||
final Map<IBinder, Configuration> mFragmentParentConfigs = new ArrayMap<>();
|
||||
|
||||
private final TaskFragmentCallback mCallback;
|
||||
private TaskFragmentAnimationController mAnimationController;
|
||||
|
||||
/**
|
||||
* Callback that notifies the controller about changes to task fragments.
|
||||
@@ -83,6 +84,25 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOrganizer() {
|
||||
if (mAnimationController != null) {
|
||||
throw new IllegalStateException("Must unregister the organizer before re-register.");
|
||||
}
|
||||
super.registerOrganizer();
|
||||
mAnimationController = new TaskFragmentAnimationController(this);
|
||||
mAnimationController.registerRemoteAnimations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterOrganizer() {
|
||||
if (mAnimationController != null) {
|
||||
mAnimationController.unregisterRemoteAnimations();
|
||||
mAnimationController = null;
|
||||
}
|
||||
super.unregisterOrganizer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new Activity and puts it into split with an existing Activity side-by-side.
|
||||
* @param launchingFragmentToken token for the launching TaskFragment. If it exists, it will
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 androidx.window.extensions.organizer;
|
||||
|
||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
|
||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
|
||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.RemoteAnimationAdapter;
|
||||
import android.view.RemoteAnimationDefinition;
|
||||
import android.window.TaskFragmentOrganizer;
|
||||
|
||||
/** Controls the TaskFragment remote animations. */
|
||||
class TaskFragmentAnimationController {
|
||||
|
||||
private static final String TAG = "TaskFragAnimationCtrl";
|
||||
// TODO(b/196173550) turn off when finalize
|
||||
static final boolean DEBUG = false;
|
||||
|
||||
private final TaskFragmentOrganizer mOrganizer;
|
||||
private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();
|
||||
|
||||
TaskFragmentAnimationController(TaskFragmentOrganizer organizer) {
|
||||
mOrganizer = organizer;
|
||||
}
|
||||
|
||||
void registerRemoteAnimations() {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "registerRemoteAnimations");
|
||||
}
|
||||
final RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
|
||||
final RemoteAnimationAdapter animationAdapter =
|
||||
new RemoteAnimationAdapter(mRemoteRunner, 0, 0);
|
||||
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, animationAdapter);
|
||||
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, animationAdapter);
|
||||
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
|
||||
mOrganizer.registerRemoteAnimations(definition);
|
||||
}
|
||||
|
||||
void unregisterRemoteAnimations() {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "unregisterRemoteAnimations");
|
||||
}
|
||||
mOrganizer.unregisterRemoteAnimations();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 androidx.window.extensions.organizer;
|
||||
|
||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.IRemoteAnimationFinishedCallback;
|
||||
import android.view.IRemoteAnimationRunner;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/** To run the TaskFragment animations. */
|
||||
class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
||||
|
||||
private static final String TAG = "TaskFragAnimationRunner";
|
||||
private final Handler mHandler = new Handler(Looper.myLooper());
|
||||
|
||||
@Nullable
|
||||
private IRemoteAnimationFinishedCallback mFinishedCallback;
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(@WindowManager.TransitionOldType int transit,
|
||||
RemoteAnimationTarget[] apps,
|
||||
RemoteAnimationTarget[] wallpapers,
|
||||
RemoteAnimationTarget[] nonApps,
|
||||
IRemoteAnimationFinishedCallback finishedCallback) {
|
||||
if (wallpapers.length != 0 || nonApps.length != 0) {
|
||||
throw new IllegalArgumentException("TaskFragment shouldn't handle animation with"
|
||||
+ "wallpaper or non-app windows.");
|
||||
}
|
||||
if (TaskFragmentAnimationController.DEBUG) {
|
||||
Log.v(TAG, "onAnimationStart transit=" + transit);
|
||||
}
|
||||
mHandler.post(() -> startAnimation(apps, finishedCallback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancelled() {
|
||||
if (TaskFragmentAnimationController.DEBUG) {
|
||||
Log.v(TAG, "onAnimationCancelled");
|
||||
}
|
||||
mHandler.post(this::onAnimationFinished);
|
||||
}
|
||||
|
||||
private void startAnimation(RemoteAnimationTarget[] targets,
|
||||
IRemoteAnimationFinishedCallback finishedCallback) {
|
||||
// TODO(b/196173550) replace with actual animations
|
||||
mFinishedCallback = finishedCallback;
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
for (RemoteAnimationTarget target : targets) {
|
||||
if (target.mode == MODE_OPENING) {
|
||||
t.show(target.leash);
|
||||
t.setAlpha(target.leash, 1);
|
||||
}
|
||||
t.setPosition(target.leash, target.localBounds.left, target.localBounds.top);
|
||||
}
|
||||
t.apply();
|
||||
onAnimationFinished();
|
||||
}
|
||||
|
||||
private void onAnimationFinished() {
|
||||
if (mFinishedCallback == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mFinishedCallback.onAnimationFinished();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
mFinishedCallback = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user