Merge "Don't rely on intent to call back from activity tracker" into sc-dev
This commit is contained in:
commit
1b369c4763
|
@ -21,6 +21,7 @@ import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.android.launcher3.BaseActivity;
|
import com.android.launcher3.BaseActivity;
|
||||||
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||||
import com.android.launcher3.util.ActivityTracker;
|
import com.android.launcher3.util.ActivityTracker;
|
||||||
|
|
||||||
|
@ -37,7 +38,8 @@ public class HotseatEduActivity extends Activity {
|
||||||
.addCategory(Intent.CATEGORY_HOME)
|
.addCategory(Intent.CATEGORY_HOME)
|
||||||
.setPackage(getPackageName())
|
.setPackage(getPackageName())
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
new HotseatActivityTracker<>().addToIntent(homeIntent);
|
|
||||||
|
Launcher.ACTIVITY_TRACKER.registerCallback(new HotseatActivityTracker());
|
||||||
startActivity(homeIntent);
|
startActivity(homeIntent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,6 +349,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mActivity != null) {
|
if (mActivity != null) {
|
||||||
|
if (mStateCallback.hasStates(STATE_GESTURE_COMPLETED)) {
|
||||||
|
// If the activity has restarted between setting the page scroll settling callback
|
||||||
|
// and actually receiving the callback, just mark the gesture completed
|
||||||
|
mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// The launcher may have been recreated as a result of device rotation.
|
// The launcher may have been recreated as a result of device rotation.
|
||||||
int oldState = mStateCallback.getState() & ~LAUNCHER_UI_STATES;
|
int oldState = mStateCallback.getState() & ~LAUNCHER_UI_STATES;
|
||||||
initStateCallbacks();
|
initStateCallbacks();
|
||||||
|
@ -1717,13 +1724,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a callback to run when the activity is ready.
|
* Registers a callback to run when the activity is ready.
|
||||||
* @param intent The intent that will be used to start the activity if it doesn't exist already.
|
|
||||||
*/
|
*/
|
||||||
public void initWhenReady(Intent intent) {
|
public void initWhenReady() {
|
||||||
// Preload the plan
|
// Preload the plan
|
||||||
RecentsModel.INSTANCE.get(mContext).getTasks(null);
|
RecentsModel.INSTANCE.get(mContext).getTasks(null);
|
||||||
|
|
||||||
mActivityInitListener.register(intent);
|
mActivityInitListener.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -184,9 +184,7 @@ public class OverviewCommandHelper {
|
||||||
.newHandler(gestureState, cmd.createTime);
|
.newHandler(gestureState, cmd.createTime);
|
||||||
interactionHandler.setGestureEndCallback(
|
interactionHandler.setGestureEndCallback(
|
||||||
() -> onTransitionComplete(cmd, interactionHandler));
|
() -> onTransitionComplete(cmd, interactionHandler));
|
||||||
|
interactionHandler.initWhenReady();
|
||||||
Intent intent = new Intent(interactionHandler.getLaunchIntent());
|
|
||||||
interactionHandler.initWhenReady(intent);
|
|
||||||
|
|
||||||
RecentsAnimationListener recentAnimListener = new RecentsAnimationListener() {
|
RecentsAnimationListener recentAnimListener = new RecentsAnimationListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -212,6 +210,7 @@ public class OverviewCommandHelper {
|
||||||
cmd.mActiveCallbacks.addListener(recentAnimListener);
|
cmd.mActiveCallbacks.addListener(recentAnimListener);
|
||||||
mTaskAnimationManager.notifyRecentsAnimationState(recentAnimListener);
|
mTaskAnimationManager.notifyRecentsAnimationState(recentAnimListener);
|
||||||
} else {
|
} else {
|
||||||
|
Intent intent = new Intent(interactionHandler.getLaunchIntent());
|
||||||
intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, gestureState.getGestureId());
|
intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, gestureState.getGestureId());
|
||||||
cmd.mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(
|
cmd.mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(
|
||||||
gestureState, intent, interactionHandler);
|
gestureState, intent, interactionHandler);
|
||||||
|
|
|
@ -141,7 +141,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
|
||||||
@Override
|
@Override
|
||||||
protected void onNewIntent(Intent intent) {
|
protected void onNewIntent(Intent intent) {
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
ACTIVITY_TRACKER.handleNewIntent(this, intent);
|
ACTIVITY_TRACKER.handleNewIntent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -389,8 +389,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||||
mInteractionHandler = mHandlerFactory.newHandler(mGestureState, touchTimeMs);
|
mInteractionHandler = mHandlerFactory.newHandler(mGestureState, touchTimeMs);
|
||||||
mInteractionHandler.setGestureEndCallback(this::onInteractionGestureFinished);
|
mInteractionHandler.setGestureEndCallback(this::onInteractionGestureFinished);
|
||||||
mMotionPauseDetector.setOnMotionPauseListener(mInteractionHandler.getMotionPauseListener());
|
mMotionPauseDetector.setOnMotionPauseListener(mInteractionHandler.getMotionPauseListener());
|
||||||
Intent intent = new Intent(mInteractionHandler.getLaunchIntent());
|
mInteractionHandler.initWhenReady();
|
||||||
mInteractionHandler.initWhenReady(intent);
|
|
||||||
|
|
||||||
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
|
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
|
||||||
mActiveCallbacks = mTaskAnimationManager.continueRecentsAnimation(mGestureState);
|
mActiveCallbacks = mTaskAnimationManager.continueRecentsAnimation(mGestureState);
|
||||||
|
@ -398,6 +397,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||||
mTaskAnimationManager.notifyRecentsAnimationState(mInteractionHandler);
|
mTaskAnimationManager.notifyRecentsAnimationState(mInteractionHandler);
|
||||||
notifyGestureStarted(true /*isLikelyToStartNewTask*/);
|
notifyGestureStarted(true /*isLikelyToStartNewTask*/);
|
||||||
} else {
|
} else {
|
||||||
|
Intent intent = new Intent(mInteractionHandler.getLaunchIntent());
|
||||||
intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId());
|
intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId());
|
||||||
mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(mGestureState, intent,
|
mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(mGestureState, intent,
|
||||||
mInteractionHandler);
|
mInteractionHandler);
|
||||||
|
|
|
@ -26,7 +26,8 @@ import com.android.launcher3.util.ActivityTracker.SchedulerCallback;
|
||||||
|
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
|
|
||||||
public class ActivityInitListener<T extends BaseActivity> implements SchedulerCallback<T> {
|
public class ActivityInitListener<T extends BaseActivity> implements
|
||||||
|
SchedulerCallback<T> {
|
||||||
|
|
||||||
private BiPredicate<T, Boolean> mOnInitListener;
|
private BiPredicate<T, Boolean> mOnInitListener;
|
||||||
private final ActivityTracker<T> mActivityTracker;
|
private final ActivityTracker<T> mActivityTracker;
|
||||||
|
@ -47,6 +48,7 @@ public class ActivityInitListener<T extends BaseActivity> implements SchedulerCa
|
||||||
@Override
|
@Override
|
||||||
public final boolean init(T activity, boolean alreadyOnHome) {
|
public final boolean init(T activity, boolean alreadyOnHome) {
|
||||||
if (!mIsRegistered) {
|
if (!mIsRegistered) {
|
||||||
|
// Don't receive any more updates
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return handleInit(activity, alreadyOnHome);
|
return handleInit(activity, alreadyOnHome);
|
||||||
|
@ -59,18 +61,17 @@ public class ActivityInitListener<T extends BaseActivity> implements SchedulerCa
|
||||||
/**
|
/**
|
||||||
* Registers the activity-created listener. If the activity is already created, then the
|
* Registers the activity-created listener. If the activity is already created, then the
|
||||||
* callback provided in the constructor will be called synchronously.
|
* callback provided in the constructor will be called synchronously.
|
||||||
* @param intent The intent that will be used to initialize the activity, if the activity
|
|
||||||
* doesn't already exist. We add the callback as an extra on this intent.
|
|
||||||
*/
|
*/
|
||||||
public void register(Intent intent) {
|
public void register() {
|
||||||
mIsRegistered = true;
|
mIsRegistered = true;
|
||||||
mActivityTracker.runCallbackWhenActivityExists(this, intent);
|
mActivityTracker.registerCallback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After calling this, we won't {@link #init} even when the activity is ready.
|
* After calling this, we won't {@link #init} even when the activity is ready.
|
||||||
*/
|
*/
|
||||||
public void unregister() {
|
public void unregister() {
|
||||||
|
mActivityTracker.unregisterCallback(this);
|
||||||
mIsRegistered = false;
|
mIsRegistered = false;
|
||||||
mOnInitListener = null;
|
mOnInitListener = null;
|
||||||
}
|
}
|
||||||
|
@ -82,9 +83,9 @@ public class ActivityInitListener<T extends BaseActivity> implements SchedulerCa
|
||||||
*/
|
*/
|
||||||
public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
|
public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
|
||||||
Context context, Handler handler, long duration) {
|
Context context, Handler handler, long duration) {
|
||||||
mIsRegistered = true;
|
register();
|
||||||
|
|
||||||
Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle();
|
Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle();
|
||||||
context.startActivity(addToIntent(new Intent(intent)), options);
|
context.startActivity(new Intent(intent), options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1478,7 +1478,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||||
boolean shouldMoveToDefaultScreen = alreadyOnHome && isInState(NORMAL)
|
boolean shouldMoveToDefaultScreen = alreadyOnHome && isInState(NORMAL)
|
||||||
&& AbstractFloatingView.getTopOpenView(this) == null;
|
&& AbstractFloatingView.getTopOpenView(this) == null;
|
||||||
boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
|
boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
|
||||||
boolean internalStateHandled = ACTIVITY_TRACKER.handleNewIntent(this, intent);
|
boolean internalStateHandled = ACTIVITY_TRACKER.handleNewIntent(this);
|
||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
if (isActionMain) {
|
if (isActionMain) {
|
||||||
if (!internalStateHandled) {
|
if (!internalStateHandled) {
|
||||||
|
|
|
@ -212,7 +212,7 @@ public class AddItemActivity extends BaseActivity
|
||||||
.addCategory(Intent.CATEGORY_HOME)
|
.addCategory(Intent.CATEGORY_HOME)
|
||||||
.setPackage(getPackageName())
|
.setPackage(getPackageName())
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
Launcher.ACTIVITY_TRACKER.runCallbackWhenActivityExists(listener, homeIntent);
|
Launcher.ACTIVITY_TRACKER.registerCallback(listener);
|
||||||
startActivity(homeIntent,
|
startActivity(homeIntent,
|
||||||
ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out)
|
ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out)
|
||||||
.toBundle());
|
.toBundle());
|
||||||
|
|
|
@ -25,6 +25,7 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import com.android.launcher3.BaseActivity;
|
import com.android.launcher3.BaseActivity;
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
|
import com.android.launcher3.util.ActivityTracker;
|
||||||
import com.android.launcher3.util.UiThreadHelper;
|
import com.android.launcher3.util.UiThreadHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +51,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotation request made by
|
* Rotation request made by
|
||||||
* {@link com.android.launcher3.util.ActivityTracker.SchedulerCallback}.
|
* {@link ActivityTracker.SchedulerCallback}.
|
||||||
* This supersedes any other request.
|
* This supersedes any other request.
|
||||||
*/
|
*/
|
||||||
private int mStateHandlerRequest = REQUEST_NONE;
|
private int mStateHandlerRequest = REQUEST_NONE;
|
||||||
|
|
|
@ -15,15 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package com.android.launcher3.util;
|
package com.android.launcher3.util;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.IBinder;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.launcher3.BaseActivity;
|
import com.android.launcher3.BaseActivity;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to statically track activity creation
|
* Helper class to statically track activity creation
|
||||||
|
@ -32,8 +31,7 @@ import java.lang.ref.WeakReference;
|
||||||
public final class ActivityTracker<T extends BaseActivity> {
|
public final class ActivityTracker<T extends BaseActivity> {
|
||||||
|
|
||||||
private WeakReference<T> mCurrentActivity = new WeakReference<>(null);
|
private WeakReference<T> mCurrentActivity = new WeakReference<>(null);
|
||||||
|
private CopyOnWriteArrayList<SchedulerCallback<T>> mCallbacks = new CopyOnWriteArrayList<>();
|
||||||
private static final String EXTRA_SCHEDULER_CALLBACK = "launcher.scheduler_callback";
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public <R extends T> R getCreatedActivity() {
|
public <R extends T> R getCreatedActivity() {
|
||||||
|
@ -47,43 +45,50 @@ public final class ActivityTracker<T extends BaseActivity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call {@link SchedulerCallback#init(BaseActivity, boolean)} when the activity is ready.
|
* Call {@link SchedulerCallback#init(BaseActivity, boolean)} when the
|
||||||
* If the activity is already created, this is called immediately, otherwise we add the
|
* activity is ready. If the activity is already created, this is called immediately.
|
||||||
* callback as an extra on the intent, and will call init() when we get handleIntent().
|
*
|
||||||
|
* The tracker maintains a strong ref to the callback, so it is up to the caller to return
|
||||||
|
* {@code false} in the callback OR to unregister the callback explicitly.
|
||||||
|
*
|
||||||
* @param callback The callback to call init() on when the activity is ready.
|
* @param callback The callback to call init() on when the activity is ready.
|
||||||
* @param intent The intent that will be used to initialize the activity, if the activity
|
|
||||||
* doesn't already exist. We add the callback as an extra on this intent.
|
|
||||||
*/
|
*/
|
||||||
public void runCallbackWhenActivityExists(SchedulerCallback<T> callback, Intent intent) {
|
public void registerCallback(SchedulerCallback<T> callback) {
|
||||||
T activity = mCurrentActivity.get();
|
T activity = mCurrentActivity.get();
|
||||||
|
mCallbacks.add(callback);
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
callback.init(activity, activity.isStarted());
|
if (!callback.init(activity, activity.isStarted())) {
|
||||||
} else {
|
unregisterCallback(callback);
|
||||||
callback.addToIntent(intent);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters a registered callback.
|
||||||
|
*/
|
||||||
|
public void unregisterCallback(SchedulerCallback<T> callback) {
|
||||||
|
mCallbacks.remove(callback);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean handleCreate(T activity) {
|
public boolean handleCreate(T activity) {
|
||||||
mCurrentActivity = new WeakReference<>(activity);
|
mCurrentActivity = new WeakReference<>(activity);
|
||||||
return handleIntent(activity, activity.getIntent(), false);
|
return handleIntent(activity, false /* alreadyOnHome */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean handleNewIntent(T activity, Intent intent) {
|
public boolean handleNewIntent(T activity) {
|
||||||
return handleIntent(activity, intent, activity.isStarted());
|
return handleIntent(activity, activity.isStarted());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleIntent(T activity, Intent intent, boolean alreadyOnHome) {
|
private boolean handleIntent(T activity, boolean alreadyOnHome) {
|
||||||
if (intent != null && intent.getExtras() != null) {
|
boolean handled = false;
|
||||||
IBinder stateBinder = intent.getExtras().getBinder(EXTRA_SCHEDULER_CALLBACK);
|
for (SchedulerCallback<T> cb : mCallbacks) {
|
||||||
SchedulerCallback<T> handler = ObjectWrapper.unwrap(stateBinder);
|
if (!cb.init(activity, alreadyOnHome)) {
|
||||||
if (handler != null) {
|
// Callback doesn't want any more updates
|
||||||
if (!handler.init(activity, alreadyOnHome)) {
|
unregisterCallback(cb);
|
||||||
intent.getExtras().remove(EXTRA_SCHEDULER_CALLBACK);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
handled = true;
|
||||||
}
|
}
|
||||||
return false;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface SchedulerCallback<T extends BaseActivity> {
|
public interface SchedulerCallback<T extends BaseActivity> {
|
||||||
|
@ -94,17 +99,5 @@ public final class ActivityTracker<T extends BaseActivity> {
|
||||||
* @return Whether to continue receiving callbacks (i.e. if the activity is recreated).
|
* @return Whether to continue receiving callbacks (i.e. if the activity is recreated).
|
||||||
*/
|
*/
|
||||||
boolean init(T activity, boolean alreadyOnHome);
|
boolean init(T activity, boolean alreadyOnHome);
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds this callback as an extra on the intent, so we can retrieve it in handleIntent() and
|
|
||||||
* call {@link #init}. The intent should be used to start the activity after calling this
|
|
||||||
* method in order for us to get handleIntent().
|
|
||||||
*/
|
|
||||||
default Intent addToIntent(Intent intent) {
|
|
||||||
Bundle extras = new Bundle();
|
|
||||||
extras.putBinder(EXTRA_SCHEDULER_CALLBACK, ObjectWrapper.wrap(this));
|
|
||||||
intent.putExtras(extras);
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue