Merge "Register remote animation in JetpackTaskFragmentOrganizer" into sc-v2-dev am: 7861b3bdce

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15560522

Change-Id: I0fd8dc497072f0368121ddaa31392bbfcb511026
This commit is contained in:
Chris Li
2021-08-31 23:54:27 +00:00
committed by Automerger Merge Worker
3 changed files with 174 additions and 0 deletions

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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;
}
}