Unifying activity tracker callback

> Using a common class for both Launcher and RecentsActivity
> Removing static refenrece to LauncherModel and using a common pattern for
  tracking activities

Bug: 141376165
Bug: 137568159
Change-Id: Ic1897abe6913ec78e25725118eedf5b468d5ec70
This commit is contained in:
Sunny Goyal 2019-09-26 17:05:31 -07:00
parent f7a2971530
commit e84c5b82be
24 changed files with 239 additions and 349 deletions

View File

@ -26,6 +26,7 @@ import androidx.annotation.Nullable;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.IconRecentsView;
@ -85,13 +86,13 @@ public final class FallbackActivityControllerHelper extends
@Override
public ActivityInitListener createActivityInitListener(
BiPredicate<RecentsActivity, Boolean> onInitListener) {
return new RecentsActivityTracker(onInitListener);
return new ActivityInitListener(onInitListener, RecentsActivity.ACTIVITY_TRACKER);
}
@Nullable
@Override
public RecentsActivity getCreatedActivity() {
return RecentsActivityTracker.getCurrentActivity();
return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
}
@Nullable

View File

@ -55,7 +55,7 @@ public final class LauncherActivityControllerHelper extends GoActivityControlHel
}
@Override
public ActivityInitListener createActivityInitListener(
public LauncherInitListener createActivityInitListener(
BiPredicate<Launcher, Boolean> onInitListener) {
return new LauncherInitListener(onInitListener);
}

View File

@ -27,8 +27,8 @@ import android.view.ViewConfiguration;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.AppToOverviewAnimationProvider.AppToOverviewAnimationListener;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.views.IconRecentsView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.LatencyTrackerCompat;
@ -104,7 +104,7 @@ public class OverviewCommandHelper {
private final long mToggleClickedTime = SystemClock.uptimeMillis();
private boolean mUserEventLogged;
private ActivityInitListener mListener;
private ActivityInitListener<T> mListener;
public RecentsActivityCommand() {
mHelper = mOverviewComponentObserver.getActivityControlHelper();

View File

@ -27,7 +27,7 @@ public class LauncherInitListenerEx extends LauncherInitListener {
}
@Override
protected boolean init(Launcher launcher, boolean alreadyOnHome) {
public boolean init(Launcher launcher, boolean alreadyOnHome) {
PredictionUiStateManager.INSTANCE.get(launcher).switchClient(Client.OVERVIEW);
return super.init(launcher, alreadyOnHome);
}

View File

@ -57,10 +57,10 @@ import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
import com.android.quickstep.util.RectFSpringAnim;

View File

@ -35,6 +35,7 @@ import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.RecentsView;
@ -177,13 +178,13 @@ public final class FallbackActivityControllerHelper implements
@Override
public ActivityInitListener createActivityInitListener(
BiPredicate<RecentsActivity, Boolean> onInitListener) {
return new RecentsActivityTracker(onInitListener);
return new ActivityInitListener(onInitListener, RecentsActivity.ACTIVITY_TRACKER);
}
@Nullable
@Override
public RecentsActivity getCreatedActivity() {
return RecentsActivityTracker.getCurrentActivity();
return BaseRecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
}
@Nullable

View File

@ -50,7 +50,6 @@ import androidx.annotation.UiThread;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherInitListenerEx;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
@ -61,6 +60,7 @@ import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.views.LauncherRecentsView;
@ -404,11 +404,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
@Nullable
@Override
public Launcher getCreatedActivity() {
LauncherAppState app = LauncherAppState.getInstanceNoCreate();
if (app == null) {
return null;
}
return (Launcher) app.getModel().getCallback();
return Launcher.ACTIVITY_TRACKER.getCreatedActivity();
}
@Nullable

View File

@ -25,14 +25,12 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.SystemClock;
import android.util.Log;
import android.view.ViewConfiguration;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityManagerWrapper;

View File

@ -38,11 +38,11 @@ import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAnimationRunner;
import com.android.launcher3.R;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsRootView;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.ObjectWrapper;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityOptionsCompat;

View File

@ -38,6 +38,7 @@ import android.os.Bundle;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.util.ObjectWrapper;
import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseSwipeUpHandler;
@ -47,7 +48,6 @@ import com.android.quickstep.RecentsActivity;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.ObjectWrapper;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.views.TaskView;

View File

@ -19,29 +19,25 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import com.android.launcher3.states.InternalStateHandler;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import java.util.function.BiPredicate;
@TargetApi(Build.VERSION_CODES.P)
public class LauncherInitListener extends InternalStateHandler implements ActivityInitListener {
private final BiPredicate<Launcher, Boolean> mOnInitListener;
public class LauncherInitListener extends ActivityInitListener<Launcher> {
private RemoteAnimationProvider mRemoteAnimationProvider;
public LauncherInitListener(BiPredicate<Launcher, Boolean> onInitListener) {
mOnInitListener = onInitListener;
super(onInitListener, Launcher.ACTIVITY_TRACKER);
}
@Override
protected boolean init(Launcher launcher, boolean alreadyOnHome) {
public boolean init(Launcher launcher, boolean alreadyOnHome) {
if (mRemoteAnimationProvider != null) {
QuickstepAppTransitionManagerImpl appTransitionManager =
(QuickstepAppTransitionManagerImpl) launcher.getAppTransitionManager();
@ -63,28 +59,19 @@ public class LauncherInitListener extends InternalStateHandler implements Activi
}, cancellationSignal);
}
launcher.deferOverlayCallbacksUntilNextResumeOrStop();
return mOnInitListener.test(launcher, alreadyOnHome);
}
@Override
public void register() {
initWhenReady();
return super.init(launcher, alreadyOnHome);
}
@Override
public void unregister() {
mRemoteAnimationProvider = null;
clearReference();
super.unregister();
}
@Override
public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
Context context, Handler handler, long duration) {
mRemoteAnimationProvider = animProvider;
register();
Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle();
context.startActivity(addToIntent(new Intent((intent))), options);
super.registerAndStartActivity(intent, animProvider, context, handler, duration);
}
}

View File

@ -17,12 +17,10 @@ package com.android.quickstep;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@ -34,7 +32,7 @@ import androidx.annotation.UiThread;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@ -99,16 +97,6 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
default void closeOverlay() { }
interface ActivityInitListener {
void register();
void unregister();
void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
Context context, Handler handler, long duration);
}
interface AnimationFactory {
enum ShelfAnimState {

View File

@ -28,6 +28,7 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
@ -43,6 +44,7 @@ import java.io.PrintWriter;
*/
public abstract class BaseRecentsActivity extends BaseDraggingActivity {
public static ActivityTracker<BaseRecentsActivity> ACTIVITY_TRACKER = new ActivityTracker<>();
private Configuration mOldConfig;
@Override
@ -55,7 +57,7 @@ public abstract class BaseRecentsActivity extends BaseDraggingActivity {
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
RecentsActivityTracker.onRecentsActivityCreate(this);
ACTIVITY_TRACKER.handleCreate((RecentsActivity) this);
}
/**
@ -132,13 +134,13 @@ public abstract class BaseRecentsActivity extends BaseDraggingActivity {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
RecentsActivityTracker.onRecentsActivityNewIntent(this);
ACTIVITY_TRACKER.handleNewIntent(this, intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
RecentsActivityTracker.onRecentsActivityDestroy(this);
ACTIVITY_TRACKER.onActivityDestroyed(this);
}
@Override

View File

@ -1,130 +0,0 @@
/*
* Copyright (C) 2018 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.quickstep;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import java.lang.ref.WeakReference;
import java.util.function.BiPredicate;
/**
* Utility class to track create/destroy for some {@link BaseRecentsActivity}.
*/
@TargetApi(Build.VERSION_CODES.P)
public class RecentsActivityTracker<T extends BaseRecentsActivity> implements ActivityInitListener {
private static WeakReference<BaseRecentsActivity> sCurrentActivity =
new WeakReference<>(null);
private static final Scheduler sScheduler = new Scheduler();
private final BiPredicate<T, Boolean> mOnInitListener;
public RecentsActivityTracker(BiPredicate<T, Boolean> onInitListener) {
mOnInitListener = onInitListener;
}
@Override
public void register() {
sScheduler.schedule(this);
}
@Override
public void unregister() {
sScheduler.clearReference(this);
}
private boolean init(T activity, boolean visible) {
return mOnInitListener.test(activity, visible);
}
public static <T extends BaseRecentsActivity> T getCurrentActivity() {
return (T) sCurrentActivity.get();
}
@Override
public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
Context context, Handler handler, long duration) {
register();
Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle();
context.startActivity(intent, options);
}
public static void onRecentsActivityCreate(BaseRecentsActivity activity) {
sCurrentActivity = new WeakReference<>(activity);
sScheduler.initIfPending(activity, false);
}
public static void onRecentsActivityNewIntent(BaseRecentsActivity activity) {
sScheduler.initIfPending(activity, activity.isStarted());
}
public static void onRecentsActivityDestroy(BaseRecentsActivity activity) {
if (sCurrentActivity.get() == activity) {
sCurrentActivity.clear();
}
}
private static class Scheduler implements Runnable {
private WeakReference<RecentsActivityTracker> mPendingTracker = new WeakReference<>(null);
public synchronized void schedule(RecentsActivityTracker tracker) {
mPendingTracker = new WeakReference<>(tracker);
MAIN_EXECUTOR.execute(this);
}
@Override
public void run() {
BaseRecentsActivity activity = sCurrentActivity.get();
if (activity != null) {
initIfPending(activity, activity.isStarted());
}
}
public synchronized boolean initIfPending(BaseRecentsActivity activity,
boolean alreadyOnHome) {
RecentsActivityTracker tracker = mPendingTracker.get();
if (tracker != null) {
if (!tracker.init(activity, alreadyOnHome)) {
mPendingTracker.clear();
}
return true;
}
return false;
}
public synchronized boolean clearReference(RecentsActivityTracker tracker) {
if (mPendingTracker.get() == tracker) {
mPendingTracker.clear();
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2019 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.quickstep.util;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.ActivityTracker.SchedulerCallback;
import java.util.function.BiPredicate;
public class ActivityInitListener<T extends BaseActivity> implements SchedulerCallback<T> {
private final BiPredicate<T, Boolean> mOnInitListener;
private final ActivityTracker<T> mActivityTracker;
public ActivityInitListener(BiPredicate<T, Boolean> onInitListener,
ActivityTracker<T> tracker) {
mOnInitListener = onInitListener;
mActivityTracker = tracker;
}
@Override
public boolean init(T activity, boolean alreadyOnHome) {
return mOnInitListener.test(activity, alreadyOnHome);
}
public void register() {
mActivityTracker.schedule(this);
}
public void unregister() {
mActivityTracker.clearReference(this);
}
public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
Context context, Handler handler, long duration) {
register();
Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle();
context.startActivity(addToIntent(new Intent((intent))), options);
}
}

View File

@ -113,7 +113,6 @@ import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.qsb.QsbContainerView;
import com.android.launcher3.states.InternalStateHandler;
import com.android.launcher3.states.RotationHelper;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.uioverrides.DejankBinderTracker;
@ -124,6 +123,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ActivityResultInfo;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.ItemInfoMatcher;
@ -176,6 +176,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
Callbacks, LauncherProviderChangeListener, UserEventDelegate,
InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {
public static final String TAG = "Launcher";
public static final ActivityTracker<Launcher> ACTIVITY_TRACKER = new ActivityTracker<>();
static final boolean LOGD = false;
static final boolean DEBUG_STRICT_MODE = false;
@ -359,7 +362,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
mAppTransitionManager = LauncherAppTransitionManager.newInstance(this);
boolean internalStateHandled = InternalStateHandler.handleCreate(this, getIntent());
boolean internalStateHandled = ACTIVITY_TRACKER.handleCreate(this);
if (internalStateHandled) {
if (savedInstanceState != null) {
// InternalStateHandler has already set the appropriate state.
@ -1444,8 +1447,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
boolean shouldMoveToDefaultScreen = alreadyOnHome && isInState(NORMAL)
&& AbstractFloatingView.getTopOpenView(this) == null;
boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
boolean internalStateHandled = InternalStateHandler
.handleNewIntent(this, intent, isStarted());
boolean internalStateHandled = ACTIVITY_TRACKER.handleNewIntent(this, intent);
if (isActionMain) {
if (!internalStateHandled) {
@ -1535,6 +1537,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public void onDestroy() {
super.onDestroy();
ACTIVITY_TRACKER.onActivityDestroyed(this);
unregisterReceiver(mScreenOffReceiver);
mWorkspace.removeFolderListeners();

View File

@ -31,12 +31,10 @@ import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.LauncherStateManager.StateListener;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.states.InternalStateHandler;
/**
* Abstract base class of floating view responsible for showing discovery bounce animation
@ -181,7 +179,7 @@ public class DiscoveryBounce extends AbstractFloatingView {
if (withDelay) {
new Handler().postDelayed(() -> showForOverviewIfNeeded(launcher, false), DELAY_MS);
return;
} else if (InternalStateHandler.hasPending()
} else if (Launcher.ACTIVITY_TRACKER.hasPending()
|| AbstractFloatingView.getTopOpenView(launcher) != null) {
// TODO: Move these checks to the top and call this method after invalidate handler.
return;

View File

@ -45,6 +45,7 @@ import android.view.View.OnTouchListener;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetHost;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
@ -176,7 +177,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener
.setPackage(getPackageName())
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
listener.initWhenReady();
Launcher.ACTIVITY_TRACKER.schedule(listener);
startActivity(homeIntent,
ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out).toBundle());
mFinishOnPause = true;

View File

@ -36,8 +36,7 @@ import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.states.InternalStateHandler;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.ActivityTracker.SchedulerCallback;
import com.android.launcher3.widget.PendingItemDragHelper;
import java.util.UUID;
@ -45,8 +44,8 @@ import java.util.UUID;
/**
* {@link DragSource} for handling drop from a different window.
*/
public abstract class BaseItemDragListener extends InternalStateHandler implements
View.OnDragListener, DragSource, DragOptions.PreDragCondition {
public abstract class BaseItemDragListener implements View.OnDragListener, DragSource,
DragOptions.PreDragCondition, SchedulerCallback<Launcher> {
private static final String TAG = "BaseItemDragListener";
@ -165,7 +164,7 @@ public abstract class BaseItemDragListener extends InternalStateHandler implemen
}
protected void postCleanup() {
clearReference();
Launcher.ACTIVITY_TRACKER.clearReference(this);
if (mLauncher != null) {
// Remove any drag params from the launcher intent since the drag operation is complete.
Intent newIntent = new Intent(mLauncher.getIntent());

View File

@ -1,145 +0,0 @@
/*
* Copyright (C) 2017 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.launcher3.states;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.model.BgDataModel.Callbacks;
import java.lang.ref.WeakReference;
/**
* Utility class to sending state handling logic to Launcher from within the same process.
*
* Extending {@link Binder} ensures that the platform maintains a single instance of each object
* which allows this object to safely navigate the system process.
*/
public abstract class InternalStateHandler extends Binder {
public static final String EXTRA_STATE_HANDLER = "launcher.state_handler";
private static final Scheduler sScheduler = new Scheduler();
/**
* Initializes the handler when the launcher is ready.
* @return true if the handler wants to stay alive.
*/
protected abstract boolean init(Launcher launcher, boolean alreadyOnHome);
public final Intent addToIntent(Intent intent) {
Bundle extras = new Bundle();
extras.putBinder(EXTRA_STATE_HANDLER, this);
intent.putExtras(extras);
return intent;
}
public final void initWhenReady() {
sScheduler.schedule(this);
}
public boolean clearReference() {
return sScheduler.clearReference(this);
}
public static boolean hasPending() {
return sScheduler.hasPending();
}
public static boolean handleCreate(Launcher launcher, Intent intent) {
return handleIntent(launcher, intent, false, false);
}
public static boolean handleNewIntent(Launcher launcher, Intent intent, boolean alreadyOnHome) {
return handleIntent(launcher, intent, alreadyOnHome, true);
}
private static boolean handleIntent(
Launcher launcher, Intent intent, boolean alreadyOnHome, boolean explicitIntent) {
boolean result = false;
if (intent != null && intent.getExtras() != null) {
IBinder stateBinder = intent.getExtras().getBinder(EXTRA_STATE_HANDLER);
if (stateBinder instanceof InternalStateHandler) {
InternalStateHandler handler = (InternalStateHandler) stateBinder;
if (!handler.init(launcher, alreadyOnHome)) {
intent.getExtras().remove(EXTRA_STATE_HANDLER);
}
result = true;
}
}
if (!result && !explicitIntent) {
result = sScheduler.initIfPending(launcher, alreadyOnHome);
}
return result;
}
private static class Scheduler implements Runnable {
private WeakReference<InternalStateHandler> mPendingHandler = new WeakReference<>(null);
public void schedule(InternalStateHandler handler) {
synchronized (this) {
mPendingHandler = new WeakReference<>(handler);
}
MAIN_EXECUTOR.execute(this);
}
@Override
public void run() {
LauncherAppState app = LauncherAppState.getInstanceNoCreate();
if (app == null) {
return;
}
Callbacks cb = app.getModel().getCallback();
if (!(cb instanceof Launcher)) {
return;
}
Launcher launcher = (Launcher) cb;
initIfPending(launcher, launcher.isStarted());
}
public boolean initIfPending(Launcher launcher, boolean alreadyOnHome) {
InternalStateHandler pendingHandler = mPendingHandler.get();
if (pendingHandler != null) {
if (!pendingHandler.init(launcher, alreadyOnHome)) {
clearReference(pendingHandler);
}
return true;
}
return false;
}
public boolean clearReference(InternalStateHandler handler) {
synchronized (this) {
if (mPendingHandler.get() == handler) {
mPendingHandler.clear();
return true;
}
return false;
}
}
public boolean hasPending() {
return mPendingHandler.get() != null;
}
}
}

View File

@ -24,7 +24,6 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
@ -59,7 +58,9 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
private boolean mAutoRotateEnabled;
/**
* Rotation request made by {@link InternalStateHandler}. This supersedes any other request.
* Rotation request made by
* {@link com.android.launcher3.util.ActivityTracker.SchedulerCallback}.
* This supersedes any other request.
*/
private int mStateHandlerRequest = REQUEST_NONE;
/**

View File

@ -56,8 +56,7 @@ public class TestInformationHandler implements ResourceBasedOverride {
mDeviceProfile = InvariantDeviceProfile.INSTANCE.
get(context).getDeviceProfile(context);
mLauncherAppState = LauncherAppState.getInstanceNoCreate();
mLauncher = mLauncherAppState != null ?
(Launcher) mLauncherAppState.getModel().getCallback() : null;
mLauncher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
}
public Bundle call(String method) {

View File

@ -0,0 +1,131 @@
/*
* Copyright (C) 2019 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.launcher3.util;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseActivity;
import java.lang.ref.WeakReference;
/**
* Helper class to statically track activity creation
*/
public final class ActivityTracker<T extends BaseActivity> implements Runnable {
private WeakReference<T> mCurrentActivity = new WeakReference<>(null);
private WeakReference<SchedulerCallback<T>> mPendingCallback = new WeakReference<>(null);
private static final String EXTRA_SCHEDULER_CALLBACK = "launcher.scheduler_callback";
@Nullable
public <R extends T> R getCreatedActivity() {
return (R) mCurrentActivity.get();
}
public void onActivityDestroyed(T activity) {
if (mCurrentActivity.get() == activity) {
mCurrentActivity.clear();
}
}
public void schedule(SchedulerCallback<? extends T> callback) {
synchronized (this) {
mPendingCallback = new WeakReference<>((SchedulerCallback<T>) callback);
}
MAIN_EXECUTOR.execute(this);
}
@Override
public void run() {
T activity = mCurrentActivity.get();
if (activity != null) {
initIfPending(activity, activity.isStarted());
}
}
public boolean initIfPending(T activity, boolean alreadyOnHome) {
SchedulerCallback<T> pendingCallback = mPendingCallback.get();
if (pendingCallback != null) {
if (!pendingCallback.init(activity, alreadyOnHome)) {
clearReference(pendingCallback);
}
return true;
}
return false;
}
public boolean clearReference(SchedulerCallback<? extends T> handler) {
synchronized (this) {
if (mPendingCallback.get() == handler) {
mPendingCallback.clear();
return true;
}
return false;
}
}
public boolean hasPending() {
return mPendingCallback.get() != null;
}
public boolean handleCreate(T activity) {
mCurrentActivity = new WeakReference<>(activity);
return handleIntent(activity, activity.getIntent(), false, false);
}
public boolean handleNewIntent(T activity, Intent intent) {
return handleIntent(activity, intent, activity.isStarted(), true);
}
private boolean handleIntent(
T activity, Intent intent, boolean alreadyOnHome, boolean explicitIntent) {
boolean result = false;
if (intent != null && intent.getExtras() != null) {
IBinder stateBinder = intent.getExtras().getBinder(EXTRA_SCHEDULER_CALLBACK);
if (stateBinder instanceof ObjectWrapper) {
SchedulerCallback<T> handler =
((ObjectWrapper<SchedulerCallback>) stateBinder).get();
if (!handler.init(activity, alreadyOnHome)) {
intent.getExtras().remove(EXTRA_SCHEDULER_CALLBACK);
}
result = true;
}
}
if (!result && !explicitIntent) {
result = initIfPending(activity, alreadyOnHome);
}
return result;
}
public interface SchedulerCallback<T extends BaseActivity> {
boolean init(T activity, boolean alreadyOnHome);
default Intent addToIntent(Intent intent) {
Bundle extras = new Bundle();
extras.putBinder(EXTRA_SCHEDULER_CALLBACK, ObjectWrapper.wrap(this));
intent.putExtras(extras);
return intent;
}
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.quickstep.util;
package com.android.launcher3.util;
import android.os.Binder;
import android.os.IBinder;