Snap for 5892445 from 1cfbdcec9b to rvc-release
Change-Id: Ia3983064252d6a99da280ca214233aee1f5433a2
This commit is contained in:
+5
-15
@@ -23,12 +23,7 @@ include $(CLEAR_VARS)
|
||||
LOCAL_USE_AAPT2 := true
|
||||
LOCAL_AAPT2_ONLY := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
ifneq (,$(wildcard frameworks/base))
|
||||
LOCAL_STATIC_JAVA_LIBRARIES:= PluginCoreLib
|
||||
else
|
||||
LOCAL_STATIC_JAVA_LIBRARIES:= libPluginCore
|
||||
endif
|
||||
LOCAL_STATIC_JAVA_LIBRARIES:= PluginCoreLib
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src_plugins)
|
||||
@@ -89,8 +84,7 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src) \
|
||||
$(call all-java-files-under, src_shortcuts_overrides) \
|
||||
$(call all-java-files-under, src_ui_overrides) \
|
||||
$(call all-java-files-under, src_flags)
|
||||
$(call all-java-files-under, src_ui_overrides)
|
||||
|
||||
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
# Proguard is disable for testing. Derivarive prjects to keep proguard enabled
|
||||
@@ -151,11 +145,10 @@ LOCAL_USE_AAPT2 := true
|
||||
LOCAL_AAPT2_ONLY := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
ifneq (,$(wildcard frameworks/base))
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
else
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
|
||||
LOCAL_SDK_VERSION := system_current
|
||||
LOCAL_MIN_SDK_VERSION := 26
|
||||
endif
|
||||
@@ -169,7 +162,6 @@ LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src) \
|
||||
$(call all-java-files-under, quickstep/src) \
|
||||
$(call all-java-files-under, quickstep/recents_ui_overrides/src) \
|
||||
$(call all-java-files-under, src_flags) \
|
||||
$(call all-java-files-under, src_shortcuts_overrides)
|
||||
|
||||
LOCAL_RESOURCE_DIR := \
|
||||
@@ -224,11 +216,10 @@ include $(CLEAR_VARS)
|
||||
LOCAL_USE_AAPT2 := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
ifneq (,$(wildcard frameworks/base))
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
else
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
|
||||
LOCAL_SDK_VERSION := system_current
|
||||
LOCAL_MIN_SDK_VERSION := 26
|
||||
endif
|
||||
@@ -271,11 +262,10 @@ include $(CLEAR_VARS)
|
||||
LOCAL_USE_AAPT2 := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
ifneq (,$(wildcard frameworks/base))
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
else
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
|
||||
LOCAL_SDK_VERSION := system_current
|
||||
LOCAL_MIN_SDK_VERSION := 26
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
[Hook Scripts]
|
||||
checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
|
||||
@@ -20,7 +20,6 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeStatesTouchController;
|
||||
@@ -51,7 +50,7 @@ public abstract class RecentsUiFactory {
|
||||
.getMode().hasGestures;
|
||||
list.add(new PortraitStatesTouchController(launcher, allowDragToOverview));
|
||||
}
|
||||
if (FeatureFlags.PULL_DOWN_STATUS_BAR && Utilities.IS_DEBUG_DEVICE
|
||||
if (Utilities.IS_DEBUG_DEVICE
|
||||
&& !launcher.getDeviceProfile().isMultiWindowMode
|
||||
&& !launcher.getDeviceProfile().isVerticalBarLayout()) {
|
||||
list.add(new StatusBarTouchController(launcher));
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper
|
||||
.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
@@ -25,7 +25,6 @@ import android.os.SystemClock;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
||||
@@ -43,7 +42,6 @@ public class OverviewCommandHelper {
|
||||
private final Context mContext;
|
||||
private final ActivityManagerWrapper mAM;
|
||||
private final RecentsModel mRecentsModel;
|
||||
private final MainThreadExecutor mMainThreadExecutor;
|
||||
private final OverviewComponentObserver mOverviewComponentObserver;
|
||||
|
||||
private long mLastToggleTime;
|
||||
@@ -51,7 +49,6 @@ public class OverviewCommandHelper {
|
||||
public OverviewCommandHelper(Context context, OverviewComponentObserver observer) {
|
||||
mContext = context;
|
||||
mAM = ActivityManagerWrapper.getInstance();
|
||||
mMainThreadExecutor = new MainThreadExecutor();
|
||||
mRecentsModel = RecentsModel.INSTANCE.get(mContext);
|
||||
mOverviewComponentObserver = observer;
|
||||
}
|
||||
@@ -63,19 +60,19 @@ public class OverviewCommandHelper {
|
||||
}
|
||||
|
||||
mAM.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
mMainThreadExecutor.execute(new RecentsActivityCommand<>());
|
||||
MAIN_EXECUTOR.execute(new RecentsActivityCommand<>());
|
||||
}
|
||||
|
||||
public void onOverviewShown(boolean triggeredFromAltTab) {
|
||||
mMainThreadExecutor.execute(new ShowRecentsCommand());
|
||||
MAIN_EXECUTOR.execute(new ShowRecentsCommand());
|
||||
}
|
||||
|
||||
public void onOverviewHidden() {
|
||||
mMainThreadExecutor.execute(new HideRecentsCommand());
|
||||
MAIN_EXECUTOR.execute(new HideRecentsCommand());
|
||||
}
|
||||
|
||||
public void onTip(int actionType, int viewType) {
|
||||
mMainThreadExecutor.execute(() ->
|
||||
MAIN_EXECUTOR.execute(() ->
|
||||
UserEventDispatcher.newInstance(mContext).logActionTip(actionType, viewType));
|
||||
}
|
||||
|
||||
@@ -161,7 +158,7 @@ public class OverviewCommandHelper {
|
||||
// Otherwise, start overview.
|
||||
mListener = mHelper.createActivityInitListener(provider::onActivityReady);
|
||||
mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(),
|
||||
provider, mContext, mMainThreadExecutor.getHandler(),
|
||||
provider, mContext, MAIN_EXECUTOR.getHandler(),
|
||||
provider.getRecentsLaunchDuration());
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.compat.UserManagerCompat;
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
|
||||
@@ -139,9 +137,6 @@ public class TouchInteractionService extends Service {
|
||||
return sConnected;
|
||||
}
|
||||
|
||||
public static final LooperExecutor BACKGROUND_EXECUTOR =
|
||||
new LooperExecutor(UiThreadHelper.getBackgroundLooper());
|
||||
|
||||
private RecentsModel mRecentsModel;
|
||||
private OverviewComponentObserver mOverviewComponentObserver;
|
||||
private OverviewCommandHelper mOverviewCommandHelper;
|
||||
|
||||
@@ -1,32 +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.config;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Defines a set of flags used to control various launcher behaviors
|
||||
*/
|
||||
public final class FeatureFlags extends BaseFlags {
|
||||
private FeatureFlags() {
|
||||
// Prevent instantiation
|
||||
}
|
||||
|
||||
// Features to control Launcher3Go behavior
|
||||
public static final boolean GO_DISABLE_WIDGETS = true;
|
||||
public static final boolean LAUNCHER3_SPRING_ICONS = false;
|
||||
}
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package com.android.launcher3.model;
|
||||
|
||||
import com.android.launcher3.AllAppsList;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherModel.Callbacks;
|
||||
import com.android.launcher3.model.BgDataModel.Callbacks;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ import androidx.annotation.Nullable;
|
||||
* <p> The widgets and shortcuts are organized using package name as its index.
|
||||
*/
|
||||
public class WidgetsModel {
|
||||
|
||||
// True is the widget support is disabled.
|
||||
public static final boolean GO_DISABLE_WIDGETS = false;
|
||||
|
||||
private static final ArrayList<WidgetListRowEntry> EMPTY_WIDGET_LIST = new ArrayList<>();
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,34 +27,23 @@ import android.os.UserHandle;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.notification.NotificationKeyData;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Performs operations related to deep shortcuts, such as querying for them, pinning them, etc.
|
||||
*/
|
||||
public class DeepShortcutManager {
|
||||
private static DeepShortcutManager sInstance;
|
||||
private static final Object sInstanceLock = new Object();
|
||||
|
||||
private static final DeepShortcutManager sInstance = new DeepShortcutManager();
|
||||
|
||||
public static DeepShortcutManager getInstance(Context context) {
|
||||
synchronized (sInstanceLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new DeepShortcutManager(context.getApplicationContext());
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private DeepShortcutManager(Context context) {
|
||||
}
|
||||
private final QueryResult mFailure = new QueryResult();
|
||||
|
||||
public boolean wasLastCallSuccess() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onShortcutsChanged(List<ShortcutInfo> shortcuts) {
|
||||
}
|
||||
private DeepShortcutManager() { }
|
||||
|
||||
/**
|
||||
* Queries for the shortcuts with the package name and provided ids.
|
||||
@@ -62,18 +51,18 @@ public class DeepShortcutManager {
|
||||
* This method is intended to get the full details for shortcuts when they are added or updated,
|
||||
* because we only get "key" fields in onShortcutsChanged().
|
||||
*/
|
||||
public List<ShortcutInfo> queryForFullDetails(String packageName,
|
||||
public QueryResult queryForFullDetails(String packageName,
|
||||
List<String> shortcutIds, UserHandle user) {
|
||||
return Collections.emptyList();
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the manifest and dynamic shortcuts associated with the given package and user,
|
||||
* to be displayed in the shortcuts container on long press.
|
||||
*/
|
||||
public List<ShortcutInfo> queryForShortcutsContainer(ComponentName activity,
|
||||
public QueryResult queryForShortcutsContainer(ComponentName activity,
|
||||
UserHandle user) {
|
||||
return Collections.emptyList();
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,20 +92,28 @@ public class DeepShortcutManager {
|
||||
*
|
||||
* If packageName is null, returns all pinned shortcuts regardless of package.
|
||||
*/
|
||||
public List<ShortcutInfo> queryForPinnedShortcuts(String packageName, UserHandle user) {
|
||||
return Collections.emptyList();
|
||||
public QueryResult queryForPinnedShortcuts(String packageName, UserHandle user) {
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
public List<ShortcutInfo> queryForPinnedShortcuts(String packageName,
|
||||
public QueryResult queryForPinnedShortcuts(String packageName,
|
||||
List<String> shortcutIds, UserHandle user) {
|
||||
return Collections.emptyList();
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
public List<ShortcutInfo> queryForAllShortcuts(UserHandle user) {
|
||||
return Collections.emptyList();
|
||||
public QueryResult queryForAllShortcuts(UserHandle user) {
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
public boolean hasHostPermission() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static class QueryResult extends ArrayList<ShortcutInfo> {
|
||||
|
||||
public boolean wasSuccess() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,4 +10,4 @@ PROTOBUF_CLASS_PATH=com.google.protobuf:protobuf-gradle-plugin:0.8.6
|
||||
PROTOBUF_DEPENDENCY=com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7
|
||||
|
||||
BUILD_TOOLS_VERSION=28.0.3
|
||||
COMPILE_SDK=android-Q
|
||||
COMPILE_SDK=android-R
|
||||
|
||||
@@ -267,6 +267,10 @@ public abstract class BaseIconCache {
|
||||
entry = new CacheEntry();
|
||||
cachingLogic.loadIcon(mContext, object, entry);
|
||||
}
|
||||
// Icon can't be loaded from cachingLogic, which implies alternative icon was loaded
|
||||
// (e.g. fallback icon, default icon). So we drop here since there's no point in caching
|
||||
// an empty entry.
|
||||
if (entry.icon == null) return;
|
||||
entry.title = cachingLogic.getLabel(object);
|
||||
entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
|
||||
mCache.put(key, entry);
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.launcher3.icons.cache;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.os.LocaleList;
|
||||
import android.os.UserHandle;
|
||||
|
||||
@@ -41,4 +42,11 @@ public interface CachingLogic<T> {
|
||||
default String getKeywords(T object, LocaleList localeList) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp the entry was last updated in cache.
|
||||
*/
|
||||
default long getLastUpdatedTime(T object, PackageInfo info) {
|
||||
return info.lastUpdateTime;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -171,8 +171,9 @@ public class IconCacheUpdateHandler {
|
||||
long updateTime = c.getLong(indexLastUpdate);
|
||||
int version = c.getInt(indexVersion);
|
||||
T app = componentMap.remove(component);
|
||||
if (version == info.versionCode && updateTime == info.lastUpdateTime &&
|
||||
TextUtils.equals(c.getString(systemStateIndex),
|
||||
if (version == info.versionCode
|
||||
&& updateTime == cachingLogic.getLastUpdatedTime(app, info)
|
||||
&& TextUtils.equals(c.getString(systemStateIndex),
|
||||
mIconCache.getIconSystemState(info.packageName))) {
|
||||
|
||||
if (mFilterMode == MODE_CLEAR_VALID_ITEMS) {
|
||||
@@ -231,7 +232,6 @@ public class IconCacheUpdateHandler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A runnable that updates invalid icons and adds missing icons in the DB for the provided
|
||||
* LauncherActivityInfo list. Items are updated/added one at a time, so that the
|
||||
|
||||
@@ -118,6 +118,7 @@ enum ControlType {
|
||||
APP_USAGE_SETTINGS = 18;
|
||||
BACK_GESTURE = 19;
|
||||
UNDO = 20;
|
||||
DISMISS_PREDICTION = 21;
|
||||
}
|
||||
|
||||
enum TipType {
|
||||
|
||||
+8
-7
@@ -17,6 +17,8 @@ package com.android.launcher3.appprediction;
|
||||
|
||||
import static android.content.pm.PackageManager.MATCH_INSTANT;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -30,8 +32,12 @@ import android.os.Message;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherModel;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
@@ -45,11 +51,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
/**
|
||||
* Utility class which loads and caches predicted items like instant apps and shortcuts, before
|
||||
* they can be displayed on the UI
|
||||
@@ -77,7 +78,7 @@ public class DynamicItemCache {
|
||||
|
||||
public DynamicItemCache(Context context, Runnable onUpdateCallback) {
|
||||
mContext = context;
|
||||
mWorker = new Handler(LauncherModel.getWorkerLooper(), this::handleWorkerMessage);
|
||||
mWorker = new Handler(MODEL_EXECUTOR.getLooper(), this::handleWorkerMessage);
|
||||
mUiHandler = new Handler(Looper.getMainLooper(), this::handleUiMessage);
|
||||
mInstantAppResolver = InstantAppResolver.newInstance(context);
|
||||
mOnUpdateCallback = onUpdateCallback;
|
||||
|
||||
+93
-20
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.launcher3.appprediction;
|
||||
|
||||
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.prediction.AppPredictionContext;
|
||||
@@ -34,19 +35,25 @@ import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
|
||||
import com.android.launcher3.model.AppLaunchTracker;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||
import com.android.systemui.plugins.AppLaunchEventsPlugin;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Subclass of app tracker which publishes the data to the prediction engine and gets back results.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.Q)
|
||||
public class PredictionAppTracker extends AppLaunchTracker {
|
||||
public class PredictionAppTracker extends AppLaunchTracker
|
||||
implements PluginListener<AppLaunchEventsPlugin> {
|
||||
|
||||
private static final String TAG = "PredictionAppTracker";
|
||||
private static final boolean DBG = false;
|
||||
@@ -58,6 +65,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
|
||||
|
||||
protected final Context mContext;
|
||||
private final Handler mMessageHandler;
|
||||
private final List<AppLaunchEventsPlugin> mAppLaunchEventsPluginsList;
|
||||
|
||||
// Accessed only on worker thread
|
||||
private AppPredictor mHomeAppPredictor;
|
||||
@@ -65,10 +73,14 @@ public class PredictionAppTracker extends AppLaunchTracker {
|
||||
|
||||
public PredictionAppTracker(Context context) {
|
||||
mContext = context;
|
||||
mMessageHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleMessage);
|
||||
mMessageHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleMessage);
|
||||
InvariantDeviceProfile.INSTANCE.get(mContext).addOnChangeListener(this::onIdpChanged);
|
||||
|
||||
mMessageHandler.sendEmptyMessage(MSG_INIT);
|
||||
|
||||
mAppLaunchEventsPluginsList = new ArrayList<>();
|
||||
PluginManagerWrapper.INSTANCE.get(context)
|
||||
.addPluginListener(this, AppLaunchEventsPlugin.class, true);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -96,7 +108,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
|
||||
AppPredictionManager apm = mContext.getSystemService(AppPredictionManager.class);
|
||||
|
||||
if (apm == null) {
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
AppPredictor predictor = apm.createAppPredictionSession(
|
||||
@@ -116,7 +128,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
|
||||
*/
|
||||
@WorkerThread
|
||||
@Nullable
|
||||
public Bundle getAppPredictionContextExtras(Client client){
|
||||
public Bundle getAppPredictionContextExtras(Client client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -128,7 +140,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
|
||||
destroy();
|
||||
|
||||
// Initialize the clients
|
||||
int count = InvariantDeviceProfile.INSTANCE.get(mContext).numColumns;
|
||||
int count = InvariantDeviceProfile.INSTANCE.get(mContext).numAllAppsColumns;
|
||||
mHomeAppPredictor = createPredictor(Client.HOME, count);
|
||||
mRecentsOverviewPredictor = createPredictor(Client.OVERVIEW, count);
|
||||
return true;
|
||||
@@ -167,37 +179,98 @@ public class PredictionAppTracker extends AppLaunchTracker {
|
||||
if (DBG) {
|
||||
Log.d(TAG, String.format("Sent immediate message to update %s", client));
|
||||
}
|
||||
|
||||
// Relay onReturnedToHome to every plugin.
|
||||
mAppLaunchEventsPluginsList.forEach(AppLaunchEventsPlugin::onReturnedToHome);
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
|
||||
String container) {
|
||||
String container) {
|
||||
// TODO: Use the full shortcut info
|
||||
AppTarget target = new AppTarget
|
||||
.Builder(new AppTargetId("shortcut:" + shortcutId), packageName, user)
|
||||
.setClassName(shortcutId)
|
||||
.build();
|
||||
AppTarget target = new AppTarget.Builder(
|
||||
new AppTargetId("shortcut:" + shortcutId), packageName, user)
|
||||
.setClassName(shortcutId)
|
||||
.build();
|
||||
|
||||
sendLaunch(target, container);
|
||||
|
||||
// Relay onStartShortcut info to every connected plugin.
|
||||
mAppLaunchEventsPluginsList
|
||||
.forEach(plugin -> plugin.onStartShortcut(
|
||||
packageName,
|
||||
shortcutId,
|
||||
user,
|
||||
container != null ? container : CONTAINER_DEFAULT)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public void onStartApp(ComponentName cn, UserHandle user, String container) {
|
||||
if (cn != null) {
|
||||
AppTarget target = new AppTarget
|
||||
.Builder(new AppTargetId("app:" + cn), cn.getPackageName(), user)
|
||||
.setClassName(cn.getClassName())
|
||||
.build();
|
||||
AppTarget target = new AppTarget.Builder(
|
||||
new AppTargetId("app:" + cn), cn.getPackageName(), user)
|
||||
.setClassName(cn.getClassName())
|
||||
.build();
|
||||
sendLaunch(target, container);
|
||||
|
||||
// Relay onStartApp to every connected plugin.
|
||||
mAppLaunchEventsPluginsList
|
||||
.forEach(plugin -> plugin.onStartApp(
|
||||
cn,
|
||||
user,
|
||||
container != null ? container : CONTAINER_DEFAULT)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
private void sendLaunch(AppTarget target, String container) {
|
||||
AppTargetEvent event = new AppTargetEvent.Builder(target, AppTargetEvent.ACTION_LAUNCH)
|
||||
public void onDismissApp(ComponentName cn, UserHandle user, String container) {
|
||||
if (cn == null) return;
|
||||
AppTarget target = new AppTarget.Builder(
|
||||
new AppTargetId("app: " + cn), cn.getPackageName(), user)
|
||||
.setClassName(cn.getClassName())
|
||||
.build();
|
||||
sendDismiss(target, container);
|
||||
|
||||
// Relay onDismissApp to every connected plugin.
|
||||
mAppLaunchEventsPluginsList
|
||||
.forEach(plugin -> plugin.onDismissApp(
|
||||
cn,
|
||||
user,
|
||||
container != null ? container : CONTAINER_DEFAULT)
|
||||
);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void sendEvent(AppTarget target, String container, int eventId) {
|
||||
AppTargetEvent event = new AppTargetEvent.Builder(target, eventId)
|
||||
.setLaunchLocation(container == null ? CONTAINER_DEFAULT : container)
|
||||
.build();
|
||||
Message.obtain(mMessageHandler, MSG_LAUNCH, event).sendToTarget();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void sendLaunch(AppTarget target, String container) {
|
||||
sendEvent(target, container, AppTargetEvent.ACTION_LAUNCH);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void sendDismiss(AppTarget target, String container) {
|
||||
sendEvent(target, container, AppTargetEvent.ACTION_DISMISS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginConnected(AppLaunchEventsPlugin appLaunchEventsPlugin, Context context) {
|
||||
mAppLaunchEventsPluginsList.add(appLaunchEventsPlugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginDisconnected(AppLaunchEventsPlugin appLaunchEventsPlugin) {
|
||||
mAppLaunchEventsPluginsList.remove(appLaunchEventsPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-4
@@ -43,6 +43,7 @@ import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.ItemInfoWithIcon;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.allapps.AllAppsStore;
|
||||
@@ -92,7 +93,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final PredictionUiStateManager mPredictionUiStateManager;
|
||||
private final int mNumPredictedAppsPerRow;
|
||||
private int mNumPredictedAppsPerRow;
|
||||
|
||||
// The set of predicted app component names
|
||||
private final List<ComponentKeyMapper> mPredictedAppComponents = new ArrayList<>();
|
||||
@@ -128,7 +129,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||
|
||||
mFocusHelper = new SimpleFocusIndicatorHelper(this);
|
||||
|
||||
mNumPredictedAppsPerRow = LauncherAppState.getIDP(context).numColumns;
|
||||
mNumPredictedAppsPerRow = LauncherAppState.getIDP(context).numAllAppsColumns;
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
mLauncher.addOnDeviceProfileChangeListener(this);
|
||||
|
||||
@@ -226,6 +227,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||
|
||||
@Override
|
||||
public void onDeviceProfileChanged(DeviceProfile dp) {
|
||||
mNumPredictedAppsPerRow = dp.inv.numAllAppsColumns;
|
||||
removeAllViews();
|
||||
applyPredictionApps();
|
||||
}
|
||||
@@ -281,7 +283,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||
}
|
||||
|
||||
private List<ItemInfoWithIcon> processPredictedAppComponents(List<ComponentKeyMapper> components) {
|
||||
if (getAppsStore().getApps().isEmpty()) {
|
||||
if (getAppsStore().getApps().length == 0) {
|
||||
// Apps have not been bound yet.
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -290,7 +292,9 @@ public class PredictionRowView extends LinearLayout implements
|
||||
for (ComponentKeyMapper mapper : components) {
|
||||
ItemInfoWithIcon info = mapper.getApp(getAppsStore());
|
||||
if (info != null) {
|
||||
predictedApps.add(info);
|
||||
ItemInfoWithIcon predictedApp = info.clone();
|
||||
predictedApp.container = LauncherSettings.Favorites.CONTAINER_PREDICTION;
|
||||
predictedApps.add(predictedApp);
|
||||
} else {
|
||||
if (FeatureFlags.IS_DOGFOOD_BUILD) {
|
||||
Log.e(TAG, "Predicted app not found: " + mapper);
|
||||
|
||||
+2
-5
@@ -28,17 +28,15 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.OverviewToAllAppsTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.QuickSwitchTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
@@ -164,8 +162,7 @@ public abstract class RecentsUiFactory {
|
||||
}
|
||||
}
|
||||
|
||||
if (FeatureFlags.PULL_DOWN_STATUS_BAR
|
||||
&& !launcher.getDeviceProfile().isMultiWindowMode) {
|
||||
if (!launcher.getDeviceProfile().isMultiWindowMode) {
|
||||
list.add(new StatusBarTouchController(launcher));
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -19,7 +19,6 @@ import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
@@ -69,8 +68,16 @@ public class BackgroundAppState extends OverviewState {
|
||||
if (taskCount == 0) {
|
||||
return super.getOverviewScaleAndTranslation(launcher);
|
||||
}
|
||||
TaskView dummyTask = recentsView.getTaskViewAt(Utilities.boundToRange(
|
||||
recentsView.getCurrentPage(), 0, taskCount - 1));
|
||||
TaskView dummyTask;
|
||||
if (recentsView.getCurrentPage() >= 0) {
|
||||
if (recentsView.getCurrentPage() <= taskCount - 1) {
|
||||
dummyTask = recentsView.getCurrentPageTaskView();
|
||||
} else {
|
||||
dummyTask = recentsView.getTaskViewAt(taskCount - 1);
|
||||
}
|
||||
} else {
|
||||
dummyTask = recentsView.getTaskViewAt(0);
|
||||
}
|
||||
return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask)
|
||||
.getScaleAndTranslation();
|
||||
}
|
||||
|
||||
+18
@@ -42,6 +42,7 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
@@ -179,6 +180,11 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
||||
} else {
|
||||
super.onDragEnd(velocity, fling);
|
||||
}
|
||||
|
||||
View searchView = mLauncher.getAppsView().getSearchView();
|
||||
if (searchView instanceof FeedbackHandler) {
|
||||
((FeedbackHandler) searchView).resetFeedback();
|
||||
}
|
||||
mMotionPauseDetector.clear();
|
||||
}
|
||||
|
||||
@@ -205,4 +211,16 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
||||
builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for views with feedback animation requiring reset
|
||||
*/
|
||||
public interface FeedbackHandler {
|
||||
|
||||
/**
|
||||
* reset searchWidget feedback
|
||||
*/
|
||||
void resetFeedback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -47,9 +47,9 @@ public final class PortraitOverviewStateTouchHelper {
|
||||
* @return true if we should intercept the motion event
|
||||
*/
|
||||
boolean canInterceptTouch(MotionEvent ev) {
|
||||
if (mRecentsView.getChildCount() > 0) {
|
||||
if (mRecentsView.getTaskViewCount() > 0) {
|
||||
// Allow swiping up in the gap between the hotseat and overview.
|
||||
return ev.getY() >= mRecentsView.getChildAt(0).getBottom();
|
||||
return ev.getY() >= mRecentsView.getTaskViewAt(0).getBottom();
|
||||
} else {
|
||||
// If there are no tasks, we only intercept if we're below the hotseat height.
|
||||
return isTouchOverHotseat(mLauncher, ev);
|
||||
@@ -63,7 +63,7 @@ public final class PortraitOverviewStateTouchHelper {
|
||||
* @return true if going back should take the user to the currently running task
|
||||
*/
|
||||
boolean shouldSwipeDownReturnToApp() {
|
||||
TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getNextPage());
|
||||
TaskView taskView = mRecentsView.getNextPageTaskView();
|
||||
return taskView != null && mRecentsView.shouldSwipeDownLaunchApp();
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public final class PortraitOverviewStateTouchHelper {
|
||||
*/
|
||||
PendingAnimation createSwipeDownToTaskAppAnimation(long duration) {
|
||||
mRecentsView.setCurrentPage(mRecentsView.getPageNearestToCenterOfScreen());
|
||||
TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getCurrentPage());
|
||||
TaskView taskView = mRecentsView.getCurrentPageTaskView();
|
||||
if (taskView == null) {
|
||||
throw new IllegalStateException("There is no task view to animate to.");
|
||||
}
|
||||
|
||||
-1
@@ -50,7 +50,6 @@ import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
/**
|
||||
* Handles quick switching to a recent task from the home screen.
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
|
||||
anim.addListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
mHelper.onSwipeUpToRecentsComplete(mActivity);
|
||||
if (mRecentsView != null) {
|
||||
mRecentsView.animateUpRunningTaskIconScale();
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ import static com.android.launcher3.Utilities.postAsyncCallback;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
|
||||
import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
|
||||
import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -44,9 +44,10 @@ import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
@@ -54,7 +55,6 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.views.FloatingIconView;
|
||||
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
||||
@@ -75,8 +75,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
/**
|
||||
* Base class for swipe up handler with some utility methods
|
||||
*/
|
||||
@@ -126,7 +124,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
|
||||
protected Runnable mGestureEndCallback;
|
||||
|
||||
protected final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler();
|
||||
protected final Handler mMainThreadHandler = MAIN_EXECUTOR.getHandler();
|
||||
protected MultiStateCallback mStateCallback;
|
||||
|
||||
protected boolean mCanceled;
|
||||
@@ -174,7 +172,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
if (effect == null) {
|
||||
return;
|
||||
}
|
||||
BACKGROUND_EXECUTOR.execute(() -> mVibrator.vibrate(effect));
|
||||
UI_HELPER_EXECUTOR.execute(() -> mVibrator.vibrate(effect));
|
||||
}
|
||||
|
||||
public Consumer<MotionEvent> getRecentsViewDispatcher(RotationMode rotationMode) {
|
||||
@@ -229,10 +227,10 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
// Launch the task user scrolled to (mRecentsView.getNextPage()).
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
// We finish recents animation inside launchTask() when live tile is enabled.
|
||||
mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */,
|
||||
mRecentsView.getNextPageTaskView().launchTask(false /* animate */,
|
||||
true /* freezeTaskList */);
|
||||
} else {
|
||||
int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id;
|
||||
int taskId = mRecentsView.getNextPageTaskView().getTask().key.id;
|
||||
mFinishingRecentsAnimationForNewTaskId = taskId;
|
||||
mRecentsAnimationWrapper.finish(true /* toRecents */, () -> {
|
||||
if (!mCanceled) {
|
||||
@@ -275,7 +273,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
overviewStackBounds = getStackBounds(dp);
|
||||
}
|
||||
dp.updateInsets(targetSet.homeContentInsets);
|
||||
dp.updateIsSeascape(mContext.getSystemService(WindowManager.class));
|
||||
dp.updateIsSeascape(mContext);
|
||||
if (runningTaskTarget != null) {
|
||||
mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
|
||||
}
|
||||
|
||||
+18
-4
@@ -66,6 +66,7 @@ import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||
import com.android.quickstep.views.LauncherRecentsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.plugins.shared.LauncherOverlayManager;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
import java.util.function.BiPredicate;
|
||||
@@ -268,7 +269,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
||||
INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0);
|
||||
|
||||
int runningTaskIndex = recentsView.getRunningTaskIndex();
|
||||
if (runningTaskIndex == 0) {
|
||||
if (runningTaskIndex == recentsView.getTaskViewStartIndex()) {
|
||||
// If we are on the first task (we haven't quick switched), translate recents in
|
||||
// from the side. Calculate the start translation based on current scale/scroll.
|
||||
float currScale = recentsView.getScaleX();
|
||||
@@ -351,8 +352,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
||||
private void playScaleDownAnim(AnimatorSet anim, Launcher launcher, LauncherState fromState,
|
||||
LauncherState endState) {
|
||||
RecentsView recentsView = launcher.getOverviewPanel();
|
||||
TaskView v = recentsView.getTaskViewAt(recentsView.getCurrentPage());
|
||||
if (v == null) {
|
||||
if (recentsView.getCurrentPageTaskView() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
||||
// recents as a whole needs to translate further to keep up with the app window.
|
||||
TaskView runningTaskView = recentsView.getRunningTaskView();
|
||||
if (runningTaskView == null) {
|
||||
runningTaskView = recentsView.getTaskViewAt(recentsView.getCurrentPage());
|
||||
runningTaskView = recentsView.getCurrentPageTaskView();
|
||||
}
|
||||
TimeInterpolator oldInterpolator = translateY.getInterpolator();
|
||||
Rect fallbackInsets = launcher.getDeviceProfile().getInsets();
|
||||
@@ -479,4 +479,18 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
||||
public void onLaunchTaskSuccess(Launcher launcher) {
|
||||
launcher.getStateManager().moveToRestState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeOverlay() {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
if (launcher == null) {
|
||||
return;
|
||||
}
|
||||
LauncherOverlayManager om = launcher.getOverlayManager();
|
||||
if (!launcher.isStarted() || launcher.isForceInvisible()) {
|
||||
om.hideOverlay(false /* animate */);
|
||||
} else {
|
||||
om.hideOverlay(150);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-11
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper
|
||||
.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -29,7 +29,6 @@ import android.util.Log;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
@@ -49,7 +48,6 @@ public class OverviewCommandHelper {
|
||||
private final Context mContext;
|
||||
private final ActivityManagerWrapper mAM;
|
||||
private final RecentsModel mRecentsModel;
|
||||
private final MainThreadExecutor mMainThreadExecutor;
|
||||
private final OverviewComponentObserver mOverviewComponentObserver;
|
||||
|
||||
private long mLastToggleTime;
|
||||
@@ -57,7 +55,6 @@ public class OverviewCommandHelper {
|
||||
public OverviewCommandHelper(Context context, OverviewComponentObserver observer) {
|
||||
mContext = context;
|
||||
mAM = ActivityManagerWrapper.getInstance();
|
||||
mMainThreadExecutor = new MainThreadExecutor();
|
||||
mRecentsModel = RecentsModel.INSTANCE.get(mContext);
|
||||
mOverviewComponentObserver = observer;
|
||||
}
|
||||
@@ -69,19 +66,19 @@ public class OverviewCommandHelper {
|
||||
}
|
||||
|
||||
mAM.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
mMainThreadExecutor.execute(new RecentsActivityCommand<>());
|
||||
MAIN_EXECUTOR.execute(new RecentsActivityCommand<>());
|
||||
}
|
||||
|
||||
public void onOverviewShown(boolean triggeredFromAltTab) {
|
||||
mMainThreadExecutor.execute(new ShowRecentsCommand(triggeredFromAltTab));
|
||||
MAIN_EXECUTOR.execute(new ShowRecentsCommand(triggeredFromAltTab));
|
||||
}
|
||||
|
||||
public void onOverviewHidden() {
|
||||
mMainThreadExecutor.execute(new HideRecentsCommand());
|
||||
MAIN_EXECUTOR.execute(new HideRecentsCommand());
|
||||
}
|
||||
|
||||
public void onTip(int actionType, int viewType) {
|
||||
mMainThreadExecutor.execute(() ->
|
||||
MAIN_EXECUTOR.execute(() ->
|
||||
UserEventDispatcher.newInstance(mContext).logActionTip(actionType, viewType));
|
||||
}
|
||||
|
||||
@@ -112,7 +109,7 @@ public class OverviewCommandHelper {
|
||||
TaskView taskView = rv.getNextTaskView();
|
||||
if (taskView == null) {
|
||||
if (rv.getTaskViewCount() > 0) {
|
||||
taskView = (TaskView) rv.getPageAt(0);
|
||||
taskView = rv.getTaskViewAt(0);
|
||||
taskView.requestFocus();
|
||||
} else {
|
||||
rv.requestFocus();
|
||||
@@ -183,7 +180,7 @@ public class OverviewCommandHelper {
|
||||
// Otherwise, start overview.
|
||||
mListener = mHelper.createActivityInitListener(this::onActivityReady);
|
||||
mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(),
|
||||
this::createWindowAnimation, mContext, mMainThreadExecutor.getHandler(),
|
||||
this::createWindowAnimation, mContext, MAIN_EXECUTOR.getHandler(),
|
||||
mAnimationProvider.getRecentsLaunchDuration());
|
||||
}
|
||||
|
||||
|
||||
+17
-6
@@ -1,9 +1,10 @@
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.testing.TestInformationHandler;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.uioverrides.states.OverviewState;
|
||||
@@ -15,7 +16,9 @@ import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class QuickstepTestInformationHandler extends TestInformationHandler {
|
||||
|
||||
private final Context mContext;
|
||||
public QuickstepTestInformationHandler(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,8 +55,8 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
|
||||
|
||||
case TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN: {
|
||||
try {
|
||||
final int leftMargin = new MainThreadExecutor().submit(() ->
|
||||
mLauncher.<RecentsView>getOverviewPanel().getLeftGestureMargin()).get();
|
||||
final int leftMargin = MAIN_EXECUTOR.submit(() ->
|
||||
getRecentsView().getLeftGestureMargin()).get();
|
||||
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, leftMargin);
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
@@ -65,9 +68,8 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
|
||||
|
||||
case TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN: {
|
||||
try {
|
||||
final int rightMargin = new MainThreadExecutor().submit(() ->
|
||||
mLauncher.<RecentsView>getOverviewPanel().getRightGestureMargin()).
|
||||
get();
|
||||
final int rightMargin = MAIN_EXECUTOR.submit(() ->
|
||||
getRecentsView().getRightGestureMargin()).get();
|
||||
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, rightMargin);
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
@@ -80,4 +82,13 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
|
||||
|
||||
return super.call(method);
|
||||
}
|
||||
|
||||
private RecentsView getRecentsView() {
|
||||
OverviewComponentObserver observer = new OverviewComponentObserver(mContext);
|
||||
try {
|
||||
return observer.getActivityControlHelper().getCreatedActivity().getOverviewPanel();
|
||||
} finally {
|
||||
observer.onDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,12 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
||||
return (T) mFallbackRecentsView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnToHomescreen() {
|
||||
super.returnToHomescreen();
|
||||
// TODO(b/137318995) This should go home, but doing so removes freeform windows
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActivityOptions getActivityLaunchOptions(final View v) {
|
||||
if (!(v instanceof TaskView)) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.android.launcher3.util.Preconditions;
|
||||
import com.android.quickstep.util.RecentsAnimationListenerSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,7 @@ public class SwipeSharedState implements SwipeAnimationListener {
|
||||
public boolean goingToLauncher;
|
||||
public boolean recentsAnimationFinishInterrupted;
|
||||
public int nextRunningTaskId = -1;
|
||||
private int mLogId;
|
||||
|
||||
public void setOverviewComponentObserver(OverviewComponentObserver observer) {
|
||||
mOverviewComponentObserver = observer;
|
||||
@@ -77,7 +79,7 @@ public class SwipeSharedState implements SwipeAnimationListener {
|
||||
mRecentsAnimationListener.removeListener(this);
|
||||
mRecentsAnimationListener.cancelListener();
|
||||
if (mLastAnimationRunning && mLastAnimationTarget != null) {
|
||||
Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(),
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
|
||||
finishAnimation
|
||||
? mLastAnimationTarget::finishAnimation
|
||||
: mLastAnimationTarget::cancelAnimation);
|
||||
@@ -155,5 +157,10 @@ public class SwipeSharedState implements SwipeAnimationListener {
|
||||
pw.println(prefix + "nextRunningTaskId=" + nextRunningTaskId);
|
||||
pw.println(prefix + "lastAnimationCancelled=" + mLastAnimationCancelled);
|
||||
pw.println(prefix + "lastAnimationRunning=" + mLastAnimationRunning);
|
||||
pw.println(prefix + "logTraceId=" + mLogId);
|
||||
}
|
||||
|
||||
public void setLogTraceId(int logId) {
|
||||
this.mLogId = logId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ import android.view.View;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.popup.SystemShortcut;
|
||||
@@ -267,12 +265,16 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
|
||||
|
||||
@Override
|
||||
protected ActivityOptions makeLaunchOptions(Activity activity) {
|
||||
return ActivityOptionsCompat.makeFreeformOptions();
|
||||
ActivityOptions activityOptions = ActivityOptionsCompat.makeFreeformOptions();
|
||||
// Arbitrary bounds only because freeform is in dev mode right now
|
||||
Rect r = new Rect(50, 50, 200, 200);
|
||||
activityOptions.setLaunchBounds(r);
|
||||
return activityOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onActivityStarted(BaseDraggingActivity activity) {
|
||||
Launcher.getLauncher(activity).getStateManager().goToState(LauncherState.NORMAL);
|
||||
activity.returnToHomescreen();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+53
-53
@@ -23,6 +23,8 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_HINTS_IN_OVERVIEW
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.config.FeatureFlags.FAKE_LANDSCAPE_UI;
|
||||
import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
|
||||
@@ -50,8 +52,6 @@ import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Region;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.DisplayManager.DisplayListener;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -61,18 +61,15 @@ import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Choreographer;
|
||||
import android.view.Display;
|
||||
import android.view.InputEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.ResourceUtils;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -82,8 +79,8 @@ import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.model.AppLaunchTracker;
|
||||
import com.android.launcher3.provider.RestoreDbTask;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
import com.android.launcher3.uioverrides.DejankBinderTracker;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
|
||||
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
|
||||
@@ -106,8 +103,8 @@ import com.android.systemui.shared.system.QuickStepContract;
|
||||
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
|
||||
import com.android.systemui.shared.system.RecentsAnimationListener;
|
||||
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
|
||||
|
||||
import com.android.systemui.shared.system.TaskInfoCompat;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
@@ -136,11 +133,14 @@ class ArgList extends LinkedList<String> {
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.Q)
|
||||
public class TouchInteractionService extends Service implements
|
||||
NavigationModeChangeListener, DisplayListener {
|
||||
NavigationModeChangeListener, DefaultDisplay.DisplayInfoChangeListener {
|
||||
|
||||
/**
|
||||
* NOTE: This value should be kept same as
|
||||
* ActivityTaskManagerService#INTENT_EXTRA_LOG_TRACE_ID in platform
|
||||
*/
|
||||
public static final String INTENT_EXTRA_LOG_TRACE_ID = "INTENT_EXTRA_LOG_TRACE_ID";
|
||||
|
||||
public static final MainThreadExecutor MAIN_THREAD_EXECUTOR = new MainThreadExecutor();
|
||||
public static final LooperExecutor BACKGROUND_EXECUTOR =
|
||||
new LooperExecutor(UiThreadHelper.getBackgroundLooper());
|
||||
|
||||
public static final EventLogArray TOUCH_INTERACTION_LOG =
|
||||
new EventLogArray("touch_interaction_log", 40);
|
||||
@@ -161,9 +161,9 @@ public class TouchInteractionService extends Service implements
|
||||
public void onInitialize(Bundle bundle) {
|
||||
mISystemUiProxy = ISystemUiProxy.Stub
|
||||
.asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
|
||||
MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor);
|
||||
MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet);
|
||||
MAIN_THREAD_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */));
|
||||
MAIN_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor);
|
||||
MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet);
|
||||
MAIN_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */));
|
||||
sIsInitialized = true;
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ public class TouchInteractionService extends Service implements
|
||||
@Override
|
||||
public void onAssistantVisibilityChanged(float visibility) {
|
||||
mLastAssistantVisibility = visibility;
|
||||
MAIN_THREAD_EXECUTOR.execute(
|
||||
MAIN_EXECUTOR.execute(
|
||||
TouchInteractionService.this::onAssistantVisibilityChanged);
|
||||
}
|
||||
|
||||
@@ -214,13 +214,13 @@ public class TouchInteractionService extends Service implements
|
||||
isButton, gestureSwipeLeft, activityControl.getContainerType());
|
||||
|
||||
if (completed && !isButton && shouldNotifyBackGesture()) {
|
||||
BACKGROUND_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture);
|
||||
UI_HELPER_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture);
|
||||
}
|
||||
}
|
||||
|
||||
public void onSystemUiStateChanged(int stateFlags) {
|
||||
mSystemUiStateFlags = stateFlags;
|
||||
MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged);
|
||||
MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged);
|
||||
}
|
||||
|
||||
/** Deprecated methods **/
|
||||
@@ -244,6 +244,7 @@ public class TouchInteractionService extends Service implements
|
||||
private static boolean sConnected = false;
|
||||
private static boolean sIsInitialized = false;
|
||||
private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState();
|
||||
private int mLogId;
|
||||
|
||||
public static boolean isConnected() {
|
||||
return sConnected;
|
||||
@@ -271,7 +272,6 @@ public class TouchInteractionService extends Service implements
|
||||
private OverviewCommandHelper mOverviewCommandHelper;
|
||||
private OverviewComponentObserver mOverviewComponentObserver;
|
||||
private OverviewInteractionState mOverviewInteractionState;
|
||||
private OverviewCallbacks mOverviewCallbacks;
|
||||
private TaskOverlayFactory mTaskOverlayFactory;
|
||||
private InputConsumerController mInputConsumer;
|
||||
private boolean mAssistantAvailable;
|
||||
@@ -323,8 +323,7 @@ public class TouchInteractionService extends Service implements
|
||||
registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
|
||||
}
|
||||
|
||||
mDefaultDisplayId = getSystemService(WindowManager.class).getDefaultDisplay()
|
||||
.getDisplayId();
|
||||
mDefaultDisplayId = DefaultDisplay.INSTANCE.get(this).getInfo().id;
|
||||
String blockingActivity = getString(R.string.gesture_blocking_activity);
|
||||
mGestureBlockingActivity = TextUtils.isEmpty(blockingActivity) ? null :
|
||||
ComponentName.unflattenFromString(blockingActivity);
|
||||
@@ -391,9 +390,8 @@ public class TouchInteractionService extends Service implements
|
||||
return;
|
||||
}
|
||||
|
||||
Display defaultDisplay = getSystemService(WindowManager.class).getDefaultDisplay();
|
||||
Point realSize = new Point();
|
||||
defaultDisplay.getRealSize(realSize);
|
||||
DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(this).getInfo();
|
||||
Point realSize = new Point(displayInfo.realSize);
|
||||
mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y);
|
||||
if (mMode == Mode.NO_BUTTON) {
|
||||
int touchHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
|
||||
@@ -415,7 +413,7 @@ public class TouchInteractionService extends Service implements
|
||||
} else {
|
||||
mAssistantLeftRegion.setEmpty();
|
||||
mAssistantRightRegion.setEmpty();
|
||||
switch (defaultDisplay.getRotation()) {
|
||||
switch (displayInfo.rotation) {
|
||||
case Surface.ROTATION_90:
|
||||
mSwipeTouchRegion.left = mSwipeTouchRegion.right
|
||||
- getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
|
||||
@@ -438,10 +436,9 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
if (mMode.hasGestures != newMode.hasGestures) {
|
||||
if (newMode.hasGestures) {
|
||||
getSystemService(DisplayManager.class).registerDisplayListener(
|
||||
this, MAIN_THREAD_EXECUTOR.getHandler());
|
||||
DefaultDisplay.INSTANCE.get(this).addChangeListener(this);
|
||||
} else {
|
||||
getSystemService(DisplayManager.class).unregisterDisplayListener(this);
|
||||
DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
|
||||
}
|
||||
}
|
||||
mMode = newMode;
|
||||
@@ -457,14 +454,8 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayAdded(int i) { }
|
||||
|
||||
@Override
|
||||
public void onDisplayRemoved(int i) { }
|
||||
|
||||
@Override
|
||||
public void onDisplayChanged(int displayId) {
|
||||
if (displayId != mDefaultDisplayId) {
|
||||
public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
|
||||
if (info.id != mDefaultDisplayId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -477,7 +468,6 @@ public class TouchInteractionService extends Service implements
|
||||
|
||||
mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
|
||||
mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
|
||||
mOverviewCallbacks = OverviewCallbacks.get(this);
|
||||
mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
|
||||
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
|
||||
mIsUserUnlocked = true;
|
||||
@@ -529,7 +519,7 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
disposeEventHandlers();
|
||||
if (mMode.hasGestures) {
|
||||
getSystemService(DisplayManager.class).unregisterDisplayListener(this);
|
||||
DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
|
||||
}
|
||||
|
||||
sConnected = false;
|
||||
@@ -547,6 +537,7 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
|
||||
private void onInputEvent(InputEvent ev) {
|
||||
DejankBinderTracker.allowBinderTrackingInTests();
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onInputEvent " + ev);
|
||||
}
|
||||
@@ -554,9 +545,12 @@ public class TouchInteractionService extends Service implements
|
||||
Log.e(TAG, "Unknown event " + ev);
|
||||
return;
|
||||
}
|
||||
|
||||
MotionEvent event = (MotionEvent) ev;
|
||||
TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked());
|
||||
if (event.getAction() == ACTION_DOWN) {
|
||||
mLogId = TOUCH_INTERACTION_LOG.generateAndSetLogId();
|
||||
sSwipeSharedState.setLogTraceId(mLogId);
|
||||
|
||||
if (mSwipeTouchRegion.contains(event.getX(), event.getY())) {
|
||||
boolean useSharedState = mConsumer.useSharedSwipeState();
|
||||
mConsumer.onConsumerAboutToBeSwitched();
|
||||
@@ -576,7 +570,10 @@ public class TouchInteractionService extends Service implements
|
||||
mUncheckedConsumer = InputConsumer.NO_OP;
|
||||
}
|
||||
}
|
||||
|
||||
TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked());
|
||||
mUncheckedConsumer.onMotionEvent(event);
|
||||
DejankBinderTracker.disallowBinderTrackingInTests();
|
||||
}
|
||||
|
||||
private boolean validSystemUiFlags() {
|
||||
@@ -640,7 +637,8 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
|
||||
private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) {
|
||||
RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
|
||||
RunningTaskInfo runningTaskInfo = DejankBinderTracker.whitelistIpcs(
|
||||
() -> mAM.getRunningTask(0));
|
||||
if (!useSharedState) {
|
||||
sSwipeSharedState.clearAllState(false /* finishAnimation */);
|
||||
}
|
||||
@@ -656,12 +654,13 @@ public class TouchInteractionService extends Service implements
|
||||
if (isExcludedAssistant(runningTaskInfo)) {
|
||||
// In the case where we are in the excluded assistant state, ignore it and treat the
|
||||
// running activity as the task behind the assistant
|
||||
runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT);
|
||||
runningTaskInfo = DejankBinderTracker.whitelistIpcs(
|
||||
() -> mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
|
||||
if (!ActivityManagerWrapper.isHomeTask(runningTaskInfo)) {
|
||||
final ComponentName homeComponent =
|
||||
mOverviewComponentObserver.getHomeIntent().getComponent();
|
||||
forceOverviewInputConsumer =
|
||||
runningTaskInfo.baseIntent.getComponent().equals(homeComponent);
|
||||
runningTaskInfo.baseIntent.getComponent(). equals(homeComponent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,26 +704,26 @@ public class TouchInteractionService extends Service implements
|
||||
|
||||
final boolean shouldDefer;
|
||||
final BaseSwipeUpHandler.Factory factory;
|
||||
ActivityControlHelper activityControlHelper =
|
||||
mOverviewComponentObserver.getActivityControlHelper();
|
||||
|
||||
if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
|
||||
shouldDefer = !sSwipeSharedState.recentsAnimationFinishInterrupted;
|
||||
factory = mFallbackNoButtonFactory;
|
||||
} else {
|
||||
shouldDefer = mOverviewComponentObserver.getActivityControlHelper()
|
||||
.deferStartingActivity(mActiveNavBarRegion, event);
|
||||
shouldDefer = activityControlHelper.deferStartingActivity(mActiveNavBarRegion, event);
|
||||
factory = mWindowTreansformFactory;
|
||||
}
|
||||
|
||||
return new OtherActivityInputConsumer(this, runningTaskInfo,
|
||||
shouldDefer, mOverviewCallbacks, this::onConsumerInactive,
|
||||
sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
|
||||
disableHorizontalSwipe(event), factory);
|
||||
return new OtherActivityInputConsumer(this, runningTaskInfo, shouldDefer,
|
||||
this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
|
||||
disableHorizontalSwipe(event), activityControlHelper, factory, mLogId);
|
||||
}
|
||||
|
||||
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
|
||||
if (mMode == Mode.NO_BUTTON && taskInfo != null) {
|
||||
return new DeviceLockedInputConsumer(this, sSwipeSharedState, mInputMonitorCompat,
|
||||
mSwipeTouchRegion, taskInfo.taskId);
|
||||
mSwipeTouchRegion, taskInfo.taskId, mLogId);
|
||||
} else {
|
||||
return mResetGestureInputConsumer;
|
||||
}
|
||||
@@ -740,10 +739,10 @@ public class TouchInteractionService extends Service implements
|
||||
|
||||
if (activity.getRootView().hasWindowFocus() || sSwipeSharedState.goingToLauncher) {
|
||||
return new OverviewInputConsumer(activity, mInputMonitorCompat,
|
||||
false /* startingInActivityBounds */);
|
||||
false /* startingInActivityBounds */, activityControl);
|
||||
} else {
|
||||
return new OverviewWithoutFocusInputConsumer(activity, mInputMonitorCompat,
|
||||
disableHorizontalSwipe(event));
|
||||
activityControl, disableHorizontalSwipe(event));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -788,7 +787,8 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
|
||||
// Pass null animation handler to indicate this start is preload.
|
||||
startRecentsActivityAsync(mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), null);
|
||||
startRecentsActivityAsync(mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(),
|
||||
null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -897,7 +897,7 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
|
||||
public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) {
|
||||
BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
|
||||
UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
|
||||
.startRecentsActivity(intent, null, listener, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
+13
-9
@@ -68,6 +68,7 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.uioverrides.DejankBinderTracker;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
@@ -423,9 +424,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
private void initializeLauncherAnimationController() {
|
||||
buildAnimationController();
|
||||
|
||||
if (LatencyTrackerCompat.isEnabled(mContext)) {
|
||||
LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs));
|
||||
}
|
||||
DejankBinderTracker.whitelistIpcs(() -> {
|
||||
// Only used in debug builds
|
||||
if (LatencyTrackerCompat.isEnabled(mContext)) {
|
||||
LatencyTrackerCompat.logToggleRecents(
|
||||
(int) (mLauncherFrameDrawnTime - mTouchTimeMs));
|
||||
}
|
||||
});
|
||||
|
||||
// This method is only called when STATE_GESTURE_STARTED is set, so we can enable the
|
||||
// high-res thumbnail loader here once we are sure that we will end up in an overview state
|
||||
@@ -479,8 +484,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask;
|
||||
if (animate) {
|
||||
// Only animate if an adjacent task view is visible on screen.
|
||||
TaskView adjacentTask1 = mRecentsView.getTaskViewAt(runningTaskIndex + 1);
|
||||
TaskView adjacentTask2 = mRecentsView.getTaskViewAt(runningTaskIndex - 1);
|
||||
TaskView adjacentTask1 = mRecentsView.getNextTaskView();
|
||||
TaskView adjacentTask2 = mRecentsView.getPreviousTaskView();
|
||||
float prevTranslationX = mRecentsView.getTranslationX();
|
||||
mRecentsView.setTranslationX(0);
|
||||
animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT))
|
||||
@@ -590,8 +595,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
*/
|
||||
private void updateSysUiFlags(float windowProgress) {
|
||||
if (mRecentsView != null) {
|
||||
TaskView centermostTask = mRecentsView.getTaskViewAt(mRecentsView
|
||||
.getPageNearestToCenterOfScreen());
|
||||
TaskView centermostTask = mRecentsView.getTaskViewNearestToCenterOfScreen();
|
||||
int centermostTaskFlags = centermostTask == null ? 0
|
||||
: centermostTask.getThumbnail().getSysUiStatusNavFlags();
|
||||
boolean useHomeScreenFlags = windowProgress > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD;
|
||||
@@ -685,8 +689,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
|
||||
BaseDraggingActivity activity = mActivityControlHelper.getCreatedActivity();
|
||||
return activity == null
|
||||
? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true);
|
||||
return activity == null ? InputConsumer.NO_OP
|
||||
: new OverviewInputConsumer(activity, null, true, mActivityControlHelper);
|
||||
}
|
||||
|
||||
private void endRunningWindowAnim(boolean cancel) {
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
||||
protected void applyLoadPlan(ArrayList<Task> tasks) {
|
||||
// When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher
|
||||
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
|
||||
// track the index of the next task appropriately, as it we are switching on any other app.
|
||||
// track the index of the next task appropriately, as if we are switching on any other app.
|
||||
if (mRunningTaskInfo != null && mRunningTaskInfo.taskId == mRunningTaskId) {
|
||||
// Check if the task list has running task
|
||||
boolean found = false;
|
||||
|
||||
+10
-6
@@ -22,8 +22,9 @@ import static android.view.MotionEvent.ACTION_UP;
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
import static com.android.launcher3.Utilities.squaredTouchSlop;
|
||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
|
||||
import static com.android.quickstep.TouchInteractionService.INTENT_EXTRA_LOG_TRACE_ID;
|
||||
import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync;
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -35,10 +36,10 @@ import android.graphics.RectF;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.quickstep.LockScreenRecentsActivity;
|
||||
import com.android.quickstep.MultiStateCallback;
|
||||
import com.android.quickstep.SwipeSharedState;
|
||||
@@ -76,6 +77,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
|
||||
private final PointF mTouchDown = new PointF();
|
||||
private final ClipAnimationHelper mClipAnimationHelper;
|
||||
private int mLogId;
|
||||
private final ClipAnimationHelper.TransformParams mTransformParams;
|
||||
private final Point mDisplaySize;
|
||||
private final MultiStateCallback mStateCallback;
|
||||
@@ -90,19 +92,20 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
private SwipeAnimationTargetSet mTargetSet;
|
||||
|
||||
public DeviceLockedInputConsumer(Context context, SwipeSharedState swipeSharedState,
|
||||
InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, int runningTaskId) {
|
||||
InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, int runningTaskId,
|
||||
int logId) {
|
||||
mContext = context;
|
||||
mTouchSlopSquared = squaredTouchSlop(context);
|
||||
mSwipeSharedState = swipeSharedState;
|
||||
mClipAnimationHelper = new ClipAnimationHelper(context);
|
||||
mLogId = logId;
|
||||
mTransformParams = new ClipAnimationHelper.TransformParams();
|
||||
mInputMonitorCompat = inputMonitorCompat;
|
||||
mSwipeTouchRegion = swipeTouchRegion;
|
||||
mRunningTaskId = runningTaskId;
|
||||
|
||||
// Do not use DeviceProfile as the user data might be locked
|
||||
mDisplaySize = new Point();
|
||||
context.getSystemService(WindowManager.class).getDefaultDisplay().getRealSize(mDisplaySize);
|
||||
mDisplaySize = DefaultDisplay.INSTANCE.get(context).getInfo().realSize;
|
||||
|
||||
// Init states
|
||||
mStateCallback = new MultiStateCallback(STATE_NAMES);
|
||||
@@ -205,7 +208,8 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
Intent intent = new Intent(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_DEFAULT)
|
||||
.setComponent(new ComponentName(mContext, LockScreenRecentsActivity.class))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mLogId);
|
||||
|
||||
mInputMonitorCompat.pilferPointers();
|
||||
startRecentsActivityAsync(intent, newListenerSet);
|
||||
|
||||
-1
@@ -50,7 +50,6 @@ 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.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
+17
-10
@@ -27,6 +27,7 @@ import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
import static com.android.quickstep.TouchInteractionService.INTENT_EXTRA_LOG_TRACE_ID;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
@@ -35,6 +36,7 @@ import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
@@ -44,12 +46,15 @@ import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.RaceConditionTracker;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.quickstep.ActivityControlHelper;
|
||||
import com.android.quickstep.BaseSwipeUpHandler;
|
||||
import com.android.quickstep.OverviewCallbacks;
|
||||
import com.android.quickstep.BaseSwipeUpHandler.Factory;
|
||||
import com.android.quickstep.SwipeSharedState;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
@@ -62,8 +67,6 @@ import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
/**
|
||||
* Input consumer for handling events originating from an activity other than Launcher
|
||||
*/
|
||||
@@ -78,11 +81,11 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
|
||||
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
|
||||
private final RunningTaskInfo mRunningTask;
|
||||
private final OverviewCallbacks mOverviewCallbacks;
|
||||
private final SwipeSharedState mSwipeSharedState;
|
||||
private final InputMonitorCompat mInputMonitorCompat;
|
||||
private final SysUINavigationMode.Mode mMode;
|
||||
private final RectF mSwipeTouchRegion;
|
||||
private final ActivityControlHelper mActivityControlHelper;
|
||||
|
||||
private final BaseSwipeUpHandler.Factory mHandlerFactory;
|
||||
|
||||
@@ -119,20 +122,23 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
|
||||
true /* restoreHomeStackPosition */);
|
||||
};
|
||||
private int mLogId;
|
||||
|
||||
public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo,
|
||||
boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
|
||||
Consumer<OtherActivityInputConsumer> onCompleteCallback,
|
||||
boolean isDeferredDownTarget, Consumer<OtherActivityInputConsumer> onCompleteCallback,
|
||||
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
|
||||
RectF swipeTouchRegion, boolean disableHorizontalSwipe,
|
||||
BaseSwipeUpHandler.Factory handlerFactory) {
|
||||
ActivityControlHelper activityControlHelper,
|
||||
Factory handlerFactory, int logId) {
|
||||
super(base);
|
||||
mLogId = logId;
|
||||
|
||||
mMainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
mRunningTask = runningTaskInfo;
|
||||
mMode = SysUINavigationMode.getMode(base);
|
||||
mSwipeTouchRegion = swipeTouchRegion;
|
||||
mHandlerFactory = handlerFactory;
|
||||
mActivityControlHelper = activityControlHelper;
|
||||
|
||||
mMotionPauseDetector = new MotionPauseDetector(base);
|
||||
mMotionPauseMinDisplacement = base.getResources().getDimension(
|
||||
@@ -143,7 +149,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
|
||||
boolean continuingPreviousGesture = swipeSharedState.getActiveListener() != null;
|
||||
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
|
||||
mOverviewCallbacks = overviewCallbacks;
|
||||
mSwipeSharedState = swipeSharedState;
|
||||
|
||||
mNavBarPosition = new NavBarPosition(base);
|
||||
@@ -312,7 +317,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
}
|
||||
mInputMonitorCompat.pilferPointers();
|
||||
|
||||
mOverviewCallbacks.closeAllWindows();
|
||||
mActivityControlHelper.closeOverlay();
|
||||
ActivityManagerWrapper.getInstance().closeSystemWindows(
|
||||
CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
|
||||
@@ -341,7 +346,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
RecentsAnimationListenerSet newListenerSet =
|
||||
mSwipeSharedState.newRecentsAnimationListenerSet();
|
||||
newListenerSet.addListener(handler);
|
||||
startRecentsActivityAsync(handler.getLaunchIntent(), newListenerSet);
|
||||
Intent intent = handler.getLaunchIntent();
|
||||
intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mLogId);
|
||||
startRecentsActivityAsync(intent, newListenerSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -19,7 +19,6 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TI
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@@ -27,9 +26,8 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.OverviewCallbacks;
|
||||
import com.android.quickstep.ActivityControlHelper;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
@@ -42,6 +40,7 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
|
||||
implements InputConsumer {
|
||||
|
||||
private final T mActivity;
|
||||
private final ActivityControlHelper<T> mActivityControlHelper;
|
||||
private final BaseDragLayer mTarget;
|
||||
private final InputMonitorCompat mInputMonitor;
|
||||
|
||||
@@ -53,10 +52,12 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
|
||||
private boolean mTargetHandledTouch;
|
||||
|
||||
public OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
|
||||
boolean startingInActivityBounds) {
|
||||
boolean startingInActivityBounds,
|
||||
ActivityControlHelper<T> activityControlHelper) {
|
||||
mActivity = activity;
|
||||
mInputMonitor = inputMonitor;
|
||||
mStartingInActivityBounds = startingInActivityBounds;
|
||||
mActivityControlHelper = activityControlHelper;
|
||||
|
||||
mTarget = activity.getDragLayer();
|
||||
if (startingInActivityBounds) {
|
||||
@@ -98,7 +99,7 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
|
||||
if (!mTargetHandledTouch && handled) {
|
||||
mTargetHandledTouch = true;
|
||||
if (!mStartingInActivityBounds) {
|
||||
OverviewCallbacks.get(mActivity).closeAllWindows();
|
||||
mActivityControlHelper.closeOverlay();
|
||||
ActivityManagerWrapper.getInstance()
|
||||
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
TOUCH_INTERACTION_LOG.addLog("startQuickstep");
|
||||
|
||||
+5
-5
@@ -34,10 +34,9 @@ import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.logging.StatsLogUtils;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.quickstep.OverviewCallbacks;
|
||||
import com.android.quickstep.ActivityControlHelper;
|
||||
import com.android.quickstep.util.NavBarPosition;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
@@ -50,16 +49,17 @@ public class OverviewWithoutFocusInputConsumer implements InputConsumer {
|
||||
private final float mSquaredTouchSlop;
|
||||
private final Context mContext;
|
||||
private final NavBarPosition mNavBarPosition;
|
||||
private final ActivityControlHelper mActivityControlHelper;
|
||||
|
||||
private boolean mInterceptedTouch;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
|
||||
|
||||
public OverviewWithoutFocusInputConsumer(Context context, InputMonitorCompat inputMonitor,
|
||||
boolean disableHorizontalSwipe) {
|
||||
ActivityControlHelper activityControlHelper, boolean disableHorizontalSwipe) {
|
||||
mInputMonitor = inputMonitor;
|
||||
mDisableHorizontalSwipe = disableHorizontalSwipe;
|
||||
mContext = context;
|
||||
mActivityControlHelper = activityControlHelper;
|
||||
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
|
||||
mNavBarPosition = new NavBarPosition(context);
|
||||
|
||||
@@ -148,7 +148,7 @@ public class OverviewWithoutFocusInputConsumer implements InputConsumer {
|
||||
}
|
||||
|
||||
if (triggerQuickstep) {
|
||||
OverviewCallbacks.get(mContext).closeAllWindows();
|
||||
mActivityControlHelper.closeOverlay();
|
||||
ActivityManagerWrapper.getInstance()
|
||||
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
TOUCH_INTERACTION_LOG.addLog("startQuickstep");
|
||||
|
||||
@@ -21,9 +21,9 @@ import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
|
||||
/**
|
||||
@@ -36,8 +36,7 @@ public class NavBarPosition {
|
||||
|
||||
public NavBarPosition(Context context) {
|
||||
mMode = SysUINavigationMode.getMode(context);
|
||||
mDisplayRotation = context.getSystemService(WindowManager.class)
|
||||
.getDefaultDisplay().getRotation();
|
||||
mDisplayRotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation;
|
||||
}
|
||||
|
||||
public boolean isRightEdge() {
|
||||
|
||||
+24
-10
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
|
||||
@@ -31,8 +34,6 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
/**
|
||||
* Wrapper around {@link RecentsAnimationListener} which delegates callbacks to multiple listeners
|
||||
* on the main thread
|
||||
@@ -70,19 +71,21 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
// Called only in R+ platform
|
||||
@BinderThread
|
||||
public final void onAnimationStart(RecentsAnimationControllerCompat controller,
|
||||
RemoteAnimationTargetCompat[] targets, Rect homeContentInsets,
|
||||
Rect minimizedHomeBounds) {
|
||||
RemoteAnimationTargetCompat[] appTargets,
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
Rect homeContentInsets, Rect minimizedHomeBounds) {
|
||||
mController = controller;
|
||||
SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, targets,
|
||||
SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, appTargets,
|
||||
homeContentInsets, minimizedHomeBounds, mShouldMinimizeSplitScreen,
|
||||
mOnFinishListener);
|
||||
|
||||
if (mCancelled) {
|
||||
targetSet.cancelAnimation();
|
||||
} else {
|
||||
Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
|
||||
for (SwipeAnimationListener listener : getListeners()) {
|
||||
listener.onRecentsAnimationStart(targetSet);
|
||||
}
|
||||
@@ -90,16 +93,27 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Called only in Q platform
|
||||
@BinderThread
|
||||
@Deprecated
|
||||
public final void onAnimationStart(RecentsAnimationControllerCompat controller,
|
||||
RemoteAnimationTargetCompat[] appTargets, Rect homeContentInsets,
|
||||
Rect minimizedHomeBounds) {
|
||||
onAnimationStart(controller, appTargets, new RemoteAnimationTargetCompat[0],
|
||||
homeContentInsets, minimizedHomeBounds);
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public final void onAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
|
||||
for (SwipeAnimationListener listener : getListeners()) {
|
||||
listener.onRecentsAnimationCanceled();
|
||||
}
|
||||
});
|
||||
// TODO: handle the transition better instead of simply using a transition delay.
|
||||
if (thumbnailData != null) {
|
||||
MAIN_THREAD_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(),
|
||||
MAIN_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(),
|
||||
TRANSITION_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
|
||||
import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
|
||||
import android.graphics.Rect;
|
||||
@@ -68,25 +68,25 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet {
|
||||
|
||||
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
|
||||
mOnFinishListener.accept(this);
|
||||
BACKGROUND_EXECUTOR.execute(() -> {
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
controller.setInputConsumerEnabled(false);
|
||||
controller.finish(toRecents, sendUserLeaveHint);
|
||||
|
||||
if (callback != null) {
|
||||
MAIN_THREAD_EXECUTOR.execute(callback);
|
||||
MAIN_EXECUTOR.execute(callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void enableInputConsumer() {
|
||||
BACKGROUND_EXECUTOR.submit(() -> {
|
||||
UI_HELPER_EXECUTOR.submit(() -> {
|
||||
controller.hideCurrentInputMethod();
|
||||
controller.setInputConsumerEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void setWindowThresholdCrossed(boolean thresholdCrossed) {
|
||||
BACKGROUND_EXECUTOR.execute(() -> {
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
controller.setAnimationTargetsBehindSystemBars(!thresholdCrossed);
|
||||
if (mShouldMinimizeSplitScreen && thresholdCrossed) {
|
||||
// NOTE: As a workaround for conflicting animations (Launcher animating the task
|
||||
|
||||
+2
-2
@@ -19,6 +19,7 @@ package com.android.quickstep.views;
|
||||
import static android.provider.Settings.ACTION_APP_USAGE_SETTINGS;
|
||||
|
||||
import static com.android.launcher3.Utilities.prefixTextWithIcon;
|
||||
import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityOptions;
|
||||
@@ -41,7 +42,6 @@ import androidx.annotation.StringRes;
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
|
||||
@@ -117,7 +117,7 @@ public final class DigitalWellBeingToast {
|
||||
return;
|
||||
}
|
||||
|
||||
Utilities.THREAD_POOL_EXECUTOR.execute(() -> {
|
||||
THREAD_POOL_EXECUTOR.execute(() -> {
|
||||
final AppUsageLimit usageLimit = mLauncherApps.getAppUsageLimit(
|
||||
task.getTopComponent().getPackageName(),
|
||||
UserHandle.of(task.key.userId));
|
||||
|
||||
+2
-1
@@ -45,6 +45,7 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
||||
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
|
||||
import com.android.launcher3.uioverrides.DejankBinderTracker;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
@@ -172,7 +173,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements StateL
|
||||
|
||||
@Override
|
||||
public boolean shouldUseMultiWindowTaskSizeStrategy() {
|
||||
return mActivity.isInMultiWindowMode();
|
||||
return DejankBinderTracker.whitelistIpcs(() -> mActivity.isInMultiWindowMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,9 +35,9 @@ import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
|
||||
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
|
||||
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
|
||||
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
|
||||
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
|
||||
import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -228,7 +228,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
return;
|
||||
}
|
||||
|
||||
BACKGROUND_EXECUTOR.execute(() -> {
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
TaskView taskView = getTaskView(taskId);
|
||||
if (taskView == null) {
|
||||
return;
|
||||
@@ -306,6 +306,9 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
private Layout mEmptyTextLayout;
|
||||
private LiveTileOverlay mLiveTileOverlay;
|
||||
|
||||
// Keeps track of the index where the first TaskView should be
|
||||
private int mTaskViewStartIndex = 0;
|
||||
|
||||
private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener =
|
||||
(inMultiWindowMode) -> {
|
||||
if (!inMultiWindowMode && mOverviewStateEnabled) {
|
||||
@@ -329,7 +332,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
|
||||
.inflate(R.layout.overview_clear_all_button, this, false);
|
||||
mClearAllButton.setOnClickListener(this::dismissAllTasks);
|
||||
|
||||
mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
|
||||
10 /* initial size */);
|
||||
|
||||
@@ -430,7 +432,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
super.onViewRemoved(child);
|
||||
|
||||
// Clear the task data for the removed child if it was visible
|
||||
if (child != mClearAllButton) {
|
||||
if (child instanceof TaskView) {
|
||||
TaskView taskView = (TaskView) child;
|
||||
mHasVisibleTaskData.delete(taskView.getTask().key.id);
|
||||
mTaskViewPool.recycle(taskView);
|
||||
@@ -444,7 +446,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
public TaskView getTaskView(int taskId) {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView tv = (TaskView) getChildAt(i);
|
||||
TaskView tv = getTaskViewAt(i);
|
||||
if (tv.getTask() != null && tv.getTask().key != null && tv.getTask().key.id == taskId) {
|
||||
return tv;
|
||||
}
|
||||
@@ -536,28 +538,26 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
}
|
||||
|
||||
if (tasks == null || tasks.isEmpty()) {
|
||||
removeAllViews();
|
||||
removeTasksViewsAndClearAllButton();
|
||||
onTaskStackUpdated();
|
||||
return;
|
||||
}
|
||||
|
||||
int oldChildCount = getChildCount();
|
||||
|
||||
// Unload existing visible task data
|
||||
unloadVisibleTaskData();
|
||||
|
||||
TaskView ignoreRestTaskView =
|
||||
TaskView ignoreResetTaskView =
|
||||
mIgnoreResetTaskId == -1 ? null : getTaskView(mIgnoreResetTaskId);
|
||||
|
||||
final int requiredTaskCount = tasks.size();
|
||||
if (getTaskViewCount() != requiredTaskCount) {
|
||||
if (oldChildCount > 0) {
|
||||
if (indexOfChild(mClearAllButton) != -1) {
|
||||
removeView(mClearAllButton);
|
||||
}
|
||||
for (int i = getChildCount(); i < requiredTaskCount; i++) {
|
||||
for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
|
||||
addView(mTaskViewPool.getView());
|
||||
}
|
||||
while (getChildCount() > requiredTaskCount) {
|
||||
while (getTaskViewCount() > requiredTaskCount) {
|
||||
removeView(getChildAt(getChildCount() - 1));
|
||||
}
|
||||
if (requiredTaskCount > 0) {
|
||||
@@ -567,17 +567,20 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
// Rebind and reset all task views
|
||||
for (int i = requiredTaskCount - 1; i >= 0; i--) {
|
||||
final int pageIndex = requiredTaskCount - i - 1;
|
||||
final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
|
||||
final Task task = tasks.get(i);
|
||||
final TaskView taskView = (TaskView) getChildAt(pageIndex);
|
||||
taskView.bind(task);
|
||||
}
|
||||
|
||||
TaskView runningTaskView = getRunningTaskView();
|
||||
if (runningTaskView != null) {
|
||||
setCurrentPage(indexOfChild(runningTaskView));
|
||||
} else if (getTaskViewCount() > 0) {
|
||||
setCurrentPage(indexOfChild(getTaskViewAt(0)));
|
||||
}
|
||||
|
||||
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreRestTaskView) {
|
||||
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) {
|
||||
// If the taskView mapping is changing, do not preserve the visuals. Since we are
|
||||
// mostly preserving the first task, and new taskViews are added to the end, it should
|
||||
// generally map to the same task.
|
||||
@@ -588,17 +591,28 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
updateEnabledOverlays();
|
||||
}
|
||||
|
||||
private void removeTasksViewsAndClearAllButton() {
|
||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||
removeView(getTaskViewAt(i));
|
||||
}
|
||||
if (indexOfChild(mClearAllButton) != -1) {
|
||||
removeView(mClearAllButton);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTaskViewCount() {
|
||||
// Account for the clear all button.
|
||||
int childCount = getChildCount();
|
||||
return childCount == 0 ? 0 : childCount - 1;
|
||||
int taskViewCount = getChildCount() - mTaskViewStartIndex;
|
||||
if (indexOfChild(mClearAllButton) != -1) {
|
||||
taskViewCount--;
|
||||
}
|
||||
return taskViewCount;
|
||||
}
|
||||
|
||||
protected void onTaskStackUpdated() { }
|
||||
|
||||
public void resetTaskVisuals() {
|
||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||
TaskView taskView = (TaskView) getChildAt(i);
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
if (mIgnoreResetTaskId != taskView.getTask().key.id) {
|
||||
taskView.resetVisualProperties();
|
||||
taskView.setStableAlpha(mContentAlpha);
|
||||
@@ -704,7 +718,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through all thet asks, and loads the associated task data for newly visible tasks,
|
||||
* Iterates through all the tasks, and loads the associated task data for newly visible tasks,
|
||||
* and unloads the associated task data for tasks that are no longer visible.
|
||||
*/
|
||||
public void loadVisibleTaskData() {
|
||||
@@ -715,15 +729,16 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
}
|
||||
|
||||
int centerPageIndex = getPageNearestToCenterOfScreen();
|
||||
int numChildren = getTaskViewCount();
|
||||
int numChildren = getChildCount();
|
||||
int lower = Math.max(0, centerPageIndex - 2);
|
||||
int upper = Math.min(centerPageIndex + 2, numChildren - 1);
|
||||
|
||||
// Update the task data for the in/visible children
|
||||
for (int i = 0; i < numChildren; i++) {
|
||||
TaskView taskView = (TaskView) getChildAt(i);
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
Task task = taskView.getTask();
|
||||
boolean visible = lower <= i && i <= upper;
|
||||
int index = indexOfChild(taskView);
|
||||
boolean visible = lower <= index && index <= upper;
|
||||
if (visible) {
|
||||
if (task == mTmpRunningTask) {
|
||||
// Skip loading if this is the task that we are animating into
|
||||
@@ -798,6 +813,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
return tv == null ? -1 : indexOfChild(tv);
|
||||
}
|
||||
|
||||
public int getTaskViewStartIndex() {
|
||||
return mTaskViewStartIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the view if anything in recents changed.
|
||||
*/
|
||||
@@ -853,10 +872,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
*/
|
||||
public void showCurrentTask(int runningTaskId) {
|
||||
if (getTaskView(runningTaskId) == null) {
|
||||
boolean wasEmpty = getChildCount() == 0;
|
||||
boolean wasEmpty = getTaskViewCount() == 0;
|
||||
// Add an empty view for now until the task plan is loaded and applied
|
||||
final TaskView taskView = mTaskViewPool.getView();
|
||||
addView(taskView, 0);
|
||||
addView(taskView, mTaskViewStartIndex);
|
||||
if (wasEmpty) {
|
||||
addView(mClearAllButton);
|
||||
}
|
||||
@@ -922,14 +941,13 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
if (runningTaskView == null) {
|
||||
// Launch the first task
|
||||
if (getTaskViewCount() > 0) {
|
||||
getTaskViewAt(0).launchTask(true /* animate */);
|
||||
getTaskViewAt(0).launchTask(true);
|
||||
}
|
||||
} else {
|
||||
TaskView nextTaskView = getNextTaskView();
|
||||
if (nextTaskView != null) {
|
||||
nextTaskView.launchTask(true /* animate */);
|
||||
if (getNextTaskView() != null) {
|
||||
getNextTaskView().launchTask(true);
|
||||
} else {
|
||||
runningTaskView.launchTask(true /* animate */);
|
||||
runningTaskView.launchTask(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -941,6 +959,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTaskIconScaledDown(TaskView taskView) {
|
||||
return mRunningTaskIconScaledDown && getRunningTaskView() == taskView;
|
||||
}
|
||||
|
||||
private void applyRunningTaskIconScale() {
|
||||
TaskView firstTask = getRunningTaskView();
|
||||
if (firstTask != null) {
|
||||
@@ -1189,7 +1211,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
int count = getTaskViewCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
addDismissedTaskAnimations(getChildAt(i), anim, duration);
|
||||
addDismissedTaskAnimations(getTaskViewAt(i), anim, duration);
|
||||
}
|
||||
|
||||
mPendingAnimation = pendingAnimation;
|
||||
@@ -1197,7 +1219,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
if (onEndListener.isSuccess) {
|
||||
// Remove all the task views now
|
||||
ActivityManagerWrapper.getInstance().removeAllRecentTasks();
|
||||
removeAllViews();
|
||||
removeTasksViewsAndClearAllButton();
|
||||
startHome();
|
||||
}
|
||||
mPendingAnimation = null;
|
||||
@@ -1344,26 +1366,50 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
child.setAlpha(mContentAlpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The most recent task that is older than the currently running task. If there is
|
||||
* currently no running task or there is no task older than it, then return null.
|
||||
*/
|
||||
@Nullable
|
||||
public TaskView getNextTaskView() {
|
||||
TaskView runningTaskView = getRunningTaskView();
|
||||
if (runningTaskView == null) {
|
||||
return null;
|
||||
}
|
||||
return getTaskViewAt(indexOfChild(runningTaskView) + 1);
|
||||
return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() + 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TaskView getPreviousTaskView() {
|
||||
return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() - 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TaskView getCurrentPageTaskView() {
|
||||
return getTaskViewAtByAbsoluteIndex(getCurrentPage());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TaskView getNextPageTaskView() {
|
||||
return getTaskViewAtByAbsoluteIndex(getNextPage());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TaskView getTaskViewNearestToCenterOfScreen() {
|
||||
return getTaskViewAtByAbsoluteIndex(getPageNearestToCenterOfScreen());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null instead of indexOutOfBoundsError when index is not in range
|
||||
*/
|
||||
@Nullable
|
||||
public TaskView getTaskViewAt(int index) {
|
||||
View child = getChildAt(index);
|
||||
return child == mClearAllButton ? null : (TaskView) child;
|
||||
return getTaskViewAtByAbsoluteIndex(index + mTaskViewStartIndex);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TaskView getTaskViewAtByAbsoluteIndex(int index) {
|
||||
if (index < getChildCount() && index >= 0) {
|
||||
View child = getChildAt(index);
|
||||
return child instanceof TaskView ? (TaskView) child : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateEmptyMessage() {
|
||||
boolean isEmpty = getChildCount() == 0;
|
||||
boolean isEmpty = getTaskViewCount() == 0;
|
||||
boolean hasSizeChanged = mLastMeasureSize.x != getWidth()
|
||||
|| mLastMeasureSize.y != getHeight();
|
||||
if (isEmpty == mShowEmptyMessage && !hasSizeChanged) {
|
||||
@@ -1497,7 +1543,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
throw new IllegalStateException("Another pending animation is still running");
|
||||
}
|
||||
|
||||
int count = getChildCount();
|
||||
int count = getTaskViewCount();
|
||||
if (count == 0) {
|
||||
return new PendingAnimation(new AnimatorSet());
|
||||
}
|
||||
@@ -1670,18 +1716,38 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
@Override
|
||||
protected int computeMinScrollX() {
|
||||
if (mIsRtl && mDisallowScrollToClearAll) {
|
||||
// We aren't showing the clear all button, so use the leftmost task as the min scroll.
|
||||
return getScrollForPage(getTaskViewCount() - 1);
|
||||
if (getTaskViewCount() > 0) {
|
||||
if (mDisallowScrollToClearAll) {
|
||||
// We aren't showing the clear all button,
|
||||
// so use the leftmost task as the min scroll.
|
||||
if (mIsRtl) {
|
||||
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
|
||||
}
|
||||
return getScrollForPage(mTaskViewStartIndex);
|
||||
}
|
||||
if (mIsRtl) {
|
||||
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
|
||||
}
|
||||
return getScrollForPage(mTaskViewStartIndex);
|
||||
}
|
||||
return super.computeMinScrollX();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int computeMaxScrollX() {
|
||||
if (!mIsRtl && mDisallowScrollToClearAll) {
|
||||
// We aren't showing the clear all button, so use the rightmost task as the max scroll.
|
||||
return getScrollForPage(getTaskViewCount() - 1);
|
||||
if (getTaskViewCount() > 0) {
|
||||
if (mDisallowScrollToClearAll) {
|
||||
// We aren't showing the clear all button,
|
||||
// so use the rightmost task as the min scroll.
|
||||
if (mIsRtl) {
|
||||
return getScrollForPage(mTaskViewStartIndex);
|
||||
}
|
||||
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
|
||||
}
|
||||
if (mIsRtl) {
|
||||
return getScrollForPage(mTaskViewStartIndex);
|
||||
}
|
||||
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
|
||||
}
|
||||
return super.computeMaxScrollX();
|
||||
}
|
||||
@@ -1733,7 +1799,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1;
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
((TaskView) getChildAt(i)).setOverlayEnabled(i == overlayEnabledPage);
|
||||
getTaskViewAt(i).setOverlayEnabled(i == overlayEnabledPage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -44,7 +44,6 @@ import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.util.SystemUiController;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.quickstep.TaskOverlayFactory;
|
||||
@@ -308,8 +307,7 @@ public class TaskThumbnailView extends View {
|
||||
final Configuration configuration =
|
||||
getContext().getResources().getConfiguration();
|
||||
// Rotate the screenshot if not in multi-window mode
|
||||
isRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
|
||||
configuration.orientation != mThumbnailData.orientation &&
|
||||
isRotated = configuration.orientation != mThumbnailData.orientation &&
|
||||
!mActivity.isInMultiWindowMode() &&
|
||||
mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
|
||||
// Scale the screenshot to always fit the width of the card.
|
||||
|
||||
@@ -28,7 +28,6 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@@ -54,7 +53,6 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
@@ -818,8 +816,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
/ (getWidth() + currentInsetsLeft + currentInsetsRight));
|
||||
}
|
||||
|
||||
// Some of the items in here are dependent on the current fullscreen params
|
||||
setIconScaleAndDim(progress, true /* invert */);
|
||||
if (!getRecentsView().isTaskIconScaledDown(this)) {
|
||||
// Some of the items in here are dependent on the current fullscreen params, but don't
|
||||
// update them if the icon is supposed to be scaled down.
|
||||
setIconScaleAndDim(progress, true /* invert */);
|
||||
}
|
||||
|
||||
thumbnail.setFullscreenParams(mCurrentFullscreenParams);
|
||||
mOutlineProvider.setFullscreenParams(mCurrentFullscreenParams);
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
<resources>
|
||||
<string name="task_overlay_factory_class" translatable="false"></string>
|
||||
|
||||
<string name="overview_callbacks_class" translatable="false"></string>
|
||||
|
||||
<!-- Activity which blocks home gesture -->
|
||||
<string name="gesture_blocking_activity" translatable="false"></string>
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.P)
|
||||
public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
|
||||
|
||||
@@ -50,13 +50,14 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
|
||||
mStartAtFrontOfQueue = startAtFrontOfQueue;
|
||||
}
|
||||
|
||||
// Called only in R+ platform
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onAnimationStart(RemoteAnimationTargetCompat[] targetCompats, Runnable runnable) {
|
||||
public void onAnimationStart(RemoteAnimationTargetCompat[] appTargets,
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets, Runnable runnable) {
|
||||
Runnable r = () -> {
|
||||
finishExistingAnimation();
|
||||
mAnimationResult = new AnimationResult(runnable);
|
||||
onCreateAnimation(targetCompats, mAnimationResult);
|
||||
onCreateAnimation(appTargets, mAnimationResult);
|
||||
};
|
||||
if (mStartAtFrontOfQueue) {
|
||||
postAtFrontOfQueueAsynchronously(mHandler, r);
|
||||
@@ -65,6 +66,13 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
|
||||
}
|
||||
}
|
||||
|
||||
// Called only in Q platform
|
||||
@BinderThread
|
||||
@Deprecated
|
||||
public void onAnimationStart(RemoteAnimationTargetCompat[] appTargets, Runnable runnable) {
|
||||
onAnimationStart(appTargets, new RemoteAnimationTargetCompat[0], runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on the UI thread when the animation targets are received. The implementation must
|
||||
* call {@link AnimationResult#setAnimation} with the target animation to be run.
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.os.Handler;
|
||||
|
||||
import com.android.launcher3.states.InternalStateHandler;
|
||||
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
||||
import com.android.quickstep.OverviewCallbacks;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
|
||||
import java.util.function.BiPredicate;
|
||||
@@ -63,7 +62,7 @@ public class LauncherInitListener extends InternalStateHandler implements Activi
|
||||
return null;
|
||||
}, cancellationSignal);
|
||||
}
|
||||
OverviewCallbacks.get(launcher).onInitOverviewTransition();
|
||||
launcher.deferOverlayCallbacksUntilNextResumeOrStop();
|
||||
return mOnInitListener.test(launcher, alreadyOnHome);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* 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.uioverrides;
|
||||
|
||||
import static android.os.IBinder.FLAG_ONEWAY;
|
||||
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A binder proxy transaction listener for tracking non-whitelisted binder calls.
|
||||
*/
|
||||
public class DejankBinderTracker implements Binder.ProxyTransactListener {
|
||||
private static final String TAG = "DejankBinderTracker";
|
||||
|
||||
private static final Object sLock = new Object();
|
||||
private static final HashSet<String> sWhitelistedFrameworkClasses = new HashSet<>();
|
||||
static {
|
||||
// Common IPCs that are ok to block the main thread.
|
||||
sWhitelistedFrameworkClasses.add("android.view.IWindowSession");
|
||||
sWhitelistedFrameworkClasses.add("android.os.IPowerManager");
|
||||
}
|
||||
private static boolean sTemporarilyIgnoreTracking = false;
|
||||
|
||||
// Used by the client to limit binder tracking to specific regions
|
||||
private static boolean sTrackingAllowed = false;
|
||||
|
||||
private BiConsumer<String, Integer> mUnexpectedTransactionCallback;
|
||||
private boolean mIsTracking = false;
|
||||
|
||||
/**
|
||||
* Temporarily ignore blocking binder calls for the duration of this {@link Runnable}.
|
||||
*/
|
||||
@MainThread
|
||||
public static void whitelistIpcs(Runnable runnable) {
|
||||
sTemporarilyIgnoreTracking = true;
|
||||
runnable.run();
|
||||
sTemporarilyIgnoreTracking = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily ignore blocking binder calls for the duration of this {@link Supplier}.
|
||||
*/
|
||||
@MainThread
|
||||
public static <T> T whitelistIpcs(Supplier<T> supplier) {
|
||||
sTemporarilyIgnoreTracking = true;
|
||||
T value = supplier.get();
|
||||
sTemporarilyIgnoreTracking = false;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables binder tracking during a test.
|
||||
*/
|
||||
@MainThread
|
||||
public static void allowBinderTrackingInTests() {
|
||||
sTrackingAllowed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables binder tracking during a test.
|
||||
*/
|
||||
@MainThread
|
||||
public static void disallowBinderTrackingInTests() {
|
||||
sTrackingAllowed = false;
|
||||
}
|
||||
|
||||
public DejankBinderTracker(BiConsumer<String, Integer> unexpectedTransactionCallback) {
|
||||
mUnexpectedTransactionCallback = unexpectedTransactionCallback;
|
||||
}
|
||||
|
||||
@MainThread
|
||||
public void startTracking() {
|
||||
if (Build.TYPE.toLowerCase(Locale.ROOT).contains("debug")
|
||||
|| Build.TYPE.toLowerCase(Locale.ROOT).equals("eng")) {
|
||||
Log.wtf(TAG, "Unexpected use of binder tracker in non-debug build", new Exception());
|
||||
return;
|
||||
}
|
||||
if (mIsTracking) {
|
||||
return;
|
||||
}
|
||||
mIsTracking = true;
|
||||
Binder.setProxyTransactListener(this);
|
||||
}
|
||||
|
||||
@MainThread
|
||||
public void stopTracking() {
|
||||
if (!mIsTracking) {
|
||||
return;
|
||||
}
|
||||
mIsTracking = false;
|
||||
Binder.setProxyTransactListener(null);
|
||||
}
|
||||
|
||||
// Override the hidden Binder#onTransactStarted method
|
||||
public synchronized Object onTransactStarted(IBinder binder, int transactionCode, int flags) {
|
||||
if (!mIsTracking
|
||||
|| !sTrackingAllowed
|
||||
|| sTemporarilyIgnoreTracking
|
||||
|| (flags & FLAG_ONEWAY) == FLAG_ONEWAY
|
||||
|| !isMainThread()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String descriptor;
|
||||
try {
|
||||
descriptor = binder.getInterfaceDescriptor();
|
||||
if (sWhitelistedFrameworkClasses.contains(descriptor)) {
|
||||
return null;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
descriptor = binder.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
mUnexpectedTransactionCallback.accept(descriptor, transactionCode);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onTransactStarted(IBinder binder, int transactionCode) {
|
||||
// Do nothing
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactEnded(Object session) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public static boolean isMainThread() {
|
||||
return Thread.currentThread() == Looper.getMainLooper().getThread();
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,8 @@ package com.android.launcher3.uioverrides;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.DeviceConfig;
|
||||
import com.android.launcher3.config.BaseFlags.BaseTogglableFlag;
|
||||
|
||||
import com.android.launcher3.config.FeatureFlags.BaseTogglableFlag;
|
||||
|
||||
public class TogglableFlag extends BaseTogglableFlag {
|
||||
public static final String NAMESPACE_LAUNCHER = "launcher";
|
||||
@@ -36,14 +37,14 @@ public class TogglableFlag extends BaseTogglableFlag {
|
||||
@Override
|
||||
public void addChangeListener(Context context, Runnable r) {
|
||||
DeviceConfig.addOnPropertiesChangedListener(
|
||||
NAMESPACE_LAUNCHER,
|
||||
context.getMainExecutor(),
|
||||
(properties) -> {
|
||||
if (!NAMESPACE_LAUNCHER.equals(properties.getNamespace())) {
|
||||
return;
|
||||
}
|
||||
initialize(context);
|
||||
r.run();
|
||||
});
|
||||
NAMESPACE_LAUNCHER,
|
||||
context.getMainExecutor(),
|
||||
(properties) -> {
|
||||
if (!NAMESPACE_LAUNCHER.equals(properties.getNamespace())) {
|
||||
return;
|
||||
}
|
||||
initialize(context);
|
||||
r.run();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,16 +14,17 @@
|
||||
|
||||
package com.android.launcher3.uioverrides.plugins;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.android.launcher3.LauncherModel;
|
||||
import com.android.systemui.shared.plugins.PluginInitializer;
|
||||
|
||||
public class PluginInitializerImpl implements PluginInitializer {
|
||||
@Override
|
||||
public Looper getBgLooper() {
|
||||
return LauncherModel.getWorkerLooper();
|
||||
return MODEL_EXECUTOR.getLooper();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -97,6 +97,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
||||
|
||||
void onLaunchTaskSuccess(T activity);
|
||||
|
||||
default void closeOverlay() { }
|
||||
|
||||
interface ActivityInitListener {
|
||||
|
||||
void register();
|
||||
|
||||
@@ -157,6 +157,6 @@ public abstract class BaseRecentsActivity extends BaseDraggingActivity {
|
||||
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
super.dump(prefix, fd, writer, args);
|
||||
writer.println(prefix + "Misc:");
|
||||
dumpMisc(writer);
|
||||
dumpMisc(prefix + "\t", writer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +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 android.content.Context;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.ResourceBasedOverride;
|
||||
|
||||
/**
|
||||
* Callbacks related to overview/quicksteps.
|
||||
*/
|
||||
public class OverviewCallbacks implements ResourceBasedOverride {
|
||||
|
||||
private static OverviewCallbacks sInstance;
|
||||
|
||||
public static OverviewCallbacks get(Context context) {
|
||||
Preconditions.assertUIThread();
|
||||
if (sInstance == null) {
|
||||
sInstance = Overrides.getObject(OverviewCallbacks.class,
|
||||
context.getApplicationContext(), R.string.overview_callbacks_class);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public void onInitOverviewTransition() { }
|
||||
|
||||
public void closeAllWindows() { }
|
||||
}
|
||||
@@ -15,20 +15,21 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
/**
|
||||
* Sets alpha for the back button
|
||||
*/
|
||||
@@ -62,7 +63,7 @@ public class OverviewInteractionState {
|
||||
// because of its high send frequency and data may be very different than the previous value
|
||||
// For example, send back alpha on uihandler to avoid flickering when setting its visibility
|
||||
mUiHandler = new Handler(this::handleUiMessage);
|
||||
mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
|
||||
mBgHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleBgMessage);
|
||||
|
||||
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context)
|
||||
.addModeChangeListener(this::onNavigationModeChanged));
|
||||
|
||||
@@ -16,19 +16,22 @@
|
||||
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.util.SparseBooleanArray;
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.KeyguardManagerCompat;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -41,7 +44,8 @@ import java.util.function.Consumer;
|
||||
public class RecentTasksList extends TaskStackChangeListener {
|
||||
|
||||
private final KeyguardManagerCompat mKeyguardManager;
|
||||
private final MainThreadExecutor mMainThreadExecutor;
|
||||
private final LooperExecutor mMainThreadExecutor;
|
||||
private final ActivityManagerWrapper mActivityManagerWrapper;
|
||||
|
||||
// The list change id, increments as the task list changes in the system
|
||||
private int mChangeId;
|
||||
@@ -52,11 +56,13 @@ public class RecentTasksList extends TaskStackChangeListener {
|
||||
|
||||
ArrayList<Task> mTasks = new ArrayList<>();
|
||||
|
||||
public RecentTasksList(Context context) {
|
||||
mMainThreadExecutor = new MainThreadExecutor();
|
||||
mKeyguardManager = new KeyguardManagerCompat(context);
|
||||
public RecentTasksList(LooperExecutor mainThreadExecutor,
|
||||
KeyguardManagerCompat keyguardManager, ActivityManagerWrapper activityManagerWrapper) {
|
||||
mMainThreadExecutor = mainThreadExecutor;
|
||||
mKeyguardManager = keyguardManager;
|
||||
mChangeId = 1;
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
|
||||
mActivityManagerWrapper = activityManagerWrapper;
|
||||
mActivityManagerWrapper.registerTaskStackListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +70,7 @@ public class RecentTasksList extends TaskStackChangeListener {
|
||||
*/
|
||||
public void getTaskKeys(int numTasks, Consumer<ArrayList<Task>> callback) {
|
||||
// Kick off task loading in the background
|
||||
BACKGROUND_EXECUTOR.execute(() -> {
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
ArrayList<Task> tasks = loadTasksInBackground(numTasks, true /* loadKeysOnly */);
|
||||
mMainThreadExecutor.execute(() -> callback.accept(tasks));
|
||||
});
|
||||
@@ -86,12 +92,12 @@ public class RecentTasksList extends TaskStackChangeListener {
|
||||
if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) {
|
||||
// The list is up to date, send the callback on the next frame,
|
||||
// so that requestID can be returned first.
|
||||
mMainThreadExecutor.getHandler().post(resultCallback);
|
||||
mMainThreadExecutor.post(resultCallback);
|
||||
return requestLoadId;
|
||||
}
|
||||
|
||||
// Kick off task loading in the background
|
||||
BACKGROUND_EXECUTOR.execute(() -> {
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
ArrayList<Task> tasks = loadTasksInBackground(Integer.MAX_VALUE, loadKeysOnly);
|
||||
|
||||
mMainThreadExecutor.execute(() -> {
|
||||
@@ -136,12 +142,13 @@ public class RecentTasksList extends TaskStackChangeListener {
|
||||
/**
|
||||
* Loads and creates a list of all the recent tasks.
|
||||
*/
|
||||
private ArrayList<Task> loadTasksInBackground(int numTasks,
|
||||
@VisibleForTesting
|
||||
ArrayList<Task> loadTasksInBackground(int numTasks,
|
||||
boolean loadKeysOnly) {
|
||||
int currentUserId = Process.myUserHandle().getIdentifier();
|
||||
ArrayList<Task> allTasks = new ArrayList<>();
|
||||
List<ActivityManager.RecentTaskInfo> rawTasks =
|
||||
ActivityManagerWrapper.getInstance().getRecentTasks(numTasks, currentUserId);
|
||||
mActivityManagerWrapper.getRecentTasks(numTasks, currentUserId);
|
||||
// The raw tasks are given in most-recent to least-recent order, we need to reverse it
|
||||
Collections.reverse(rawTasks);
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
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;
|
||||
@@ -22,7 +24,6 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
|
||||
@@ -92,14 +93,10 @@ public class RecentsActivityTracker<T extends BaseRecentsActivity> implements Ac
|
||||
private static class Scheduler implements Runnable {
|
||||
|
||||
private WeakReference<RecentsActivityTracker> mPendingTracker = new WeakReference<>(null);
|
||||
private MainThreadExecutor mMainThreadExecutor;
|
||||
|
||||
public synchronized void schedule(RecentsActivityTracker tracker) {
|
||||
mPendingTracker = new WeakReference<>(tracker);
|
||||
if (mMainThreadExecutor == null) {
|
||||
mMainThreadExecutor = new MainThreadExecutor();
|
||||
}
|
||||
mMainThreadExecutor.execute(this);
|
||||
MAIN_EXECUTOR.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.createAndStartNewLooper;
|
||||
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
@@ -22,16 +26,20 @@ import android.app.ActivityManager;
|
||||
import android.content.ComponentCallbacks2;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
import com.android.launcher3.compat.LauncherAppsCompat.OnAppsChangedCallbackCompat;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.KeyguardManagerCompat;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -61,13 +69,14 @@ public class RecentsModel extends TaskStackChangeListener {
|
||||
|
||||
private RecentsModel(Context context) {
|
||||
mContext = context;
|
||||
HandlerThread loaderThread = new HandlerThread("TaskThumbnailIconCache",
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
loaderThread.start();
|
||||
mTaskList = new RecentTasksList(context);
|
||||
mIconCache = new TaskIconCache(context, loaderThread.getLooper());
|
||||
mThumbnailCache = new TaskThumbnailCache(context, loaderThread.getLooper());
|
||||
Looper looper =
|
||||
createAndStartNewLooper("TaskThumbnailIconCache", THREAD_PRIORITY_BACKGROUND);
|
||||
mTaskList = new RecentTasksList(MAIN_EXECUTOR,
|
||||
new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance());
|
||||
mIconCache = new TaskIconCache(context, looper);
|
||||
mThumbnailCache = new TaskThumbnailCache(context, looper);
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
|
||||
setupPackageListener();
|
||||
}
|
||||
|
||||
public TaskIconCache getIconCache() {
|
||||
@@ -166,6 +175,7 @@ public class RecentsModel extends TaskStackChangeListener {
|
||||
public void onTaskRemoved(int taskId) {
|
||||
Task.TaskKey dummyKey = new Task.TaskKey(taskId, 0, null, null, 0, 0);
|
||||
mThumbnailCache.remove(dummyKey);
|
||||
mIconCache.onTaskRemoved(dummyKey);
|
||||
}
|
||||
|
||||
public void setSystemUiProxy(ISystemUiProxy systemUiProxy) {
|
||||
@@ -200,6 +210,21 @@ public class RecentsModel extends TaskStackChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void setupPackageListener() {
|
||||
LauncherAppsCompat.getInstance(mContext)
|
||||
.addOnAppsChangedCallback(new OnAppsChangedCallbackCompat() {
|
||||
@Override
|
||||
public void onPackageRemoved(String packageName, UserHandle user) {
|
||||
mIconCache.invalidatePackage(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageChanged(String packageName, UserHandle user) {
|
||||
mIconCache.invalidatePackage(packageName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addThumbnailChangeListener(TaskThumbnailChangeListener listener) {
|
||||
mThumbnailChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.uioverrides.RecentsUiFactory.GO_LOW_RAM_RECENTS_ENABLED;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -27,26 +28,25 @@ import android.os.Looper;
|
||||
import android.util.LruCache;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.icons.cache.HandlerRunnable;
|
||||
import com.android.launcher3.uioverrides.RecentsUiFactory;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.recents.model.Task.TaskKey;
|
||||
import com.android.systemui.shared.recents.model.TaskKeyLruCache;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Manages the caching of task icons and related data.
|
||||
* TODO: This class should later be merged into IconCache.
|
||||
* TODO(b/138944598): This class should later be merged into IconCache.
|
||||
*/
|
||||
public class TaskIconCache {
|
||||
|
||||
private final Handler mBackgroundHandler;
|
||||
private final MainThreadExecutor mMainThreadExecutor;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
|
||||
private final NormalizedIconLoader mIconLoader;
|
||||
@@ -67,7 +67,6 @@ public class TaskIconCache {
|
||||
|
||||
public TaskIconCache(Context context, Looper backgroundLooper) {
|
||||
mBackgroundHandler = new Handler(backgroundLooper);
|
||||
mMainThreadExecutor = new MainThreadExecutor();
|
||||
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
|
||||
|
||||
Resources res = context.getResources();
|
||||
@@ -103,7 +102,7 @@ public class TaskIconCache {
|
||||
// We don't call back to the provided callback in this case
|
||||
return;
|
||||
}
|
||||
mMainThreadExecutor.execute(() -> {
|
||||
MAIN_EXECUTOR.execute(() -> {
|
||||
task.icon = icon;
|
||||
task.titleDescription = contentDescription;
|
||||
callback.accept(task);
|
||||
@@ -149,6 +148,21 @@ public class TaskIconCache {
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
void onTaskRemoved(TaskKey taskKey) {
|
||||
mIconCache.remove(taskKey);
|
||||
}
|
||||
|
||||
void invalidatePackage(String packageName) {
|
||||
// TODO(b/138944598): Merge this class into IconCache so we can do this at the base level
|
||||
Map<ComponentName, ActivityInfo> activityInfoCache = mActivityInfoCache.snapshot();
|
||||
for (ComponentName cn : activityInfoCache.keySet()) {
|
||||
if (cn.getPackageName().equals(packageName)) {
|
||||
mActivityInfoCache.remove(cn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class IconLoadRequest extends HandlerRunnable {
|
||||
IconLoadRequest(Handler handler) {
|
||||
super(handler, null);
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.icons.cache.HandlerRunnable;
|
||||
@@ -30,13 +32,13 @@ import com.android.systemui.shared.recents.model.Task.TaskKey;
|
||||
import com.android.systemui.shared.recents.model.TaskKeyLruCache;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TaskThumbnailCache {
|
||||
|
||||
private final Handler mBackgroundHandler;
|
||||
private final MainThreadExecutor mMainThreadExecutor;
|
||||
|
||||
private final int mCacheSize;
|
||||
private final ThumbnailCache mCache;
|
||||
@@ -94,7 +96,6 @@ public class TaskThumbnailCache {
|
||||
|
||||
public TaskThumbnailCache(Context context, Looper backgroundLooper) {
|
||||
mBackgroundHandler = new Handler(backgroundLooper);
|
||||
mMainThreadExecutor = new MainThreadExecutor();
|
||||
mHighResLoadingState = new HighResLoadingState(context);
|
||||
|
||||
Resources res = context.getResources();
|
||||
@@ -168,7 +169,7 @@ public class TaskThumbnailCache {
|
||||
// We don't call back to the provided callback in this case
|
||||
return;
|
||||
}
|
||||
mMainThreadExecutor.execute(() -> {
|
||||
MAIN_EXECUTOR.execute(() -> {
|
||||
mCache.put(key, thumbnail);
|
||||
callback.accept(thumbnail);
|
||||
onEnd();
|
||||
|
||||
@@ -150,10 +150,10 @@ public class AppPredictionsUITests extends AbstractQuickStepTest {
|
||||
List<AppTarget> targets = new ArrayList<>(activities.length);
|
||||
for (LauncherActivityInfo info : activities) {
|
||||
ComponentName cn = info.getComponentName();
|
||||
AppTarget target =
|
||||
new AppTarget.Builder(new AppTargetId("app:" + cn), cn.getPackageName(), info.getUser())
|
||||
.setClassName(cn.getClassName())
|
||||
.build();
|
||||
AppTarget target = new AppTarget.Builder(
|
||||
new AppTargetId("app:" + cn), cn.getPackageName(), info.getUser())
|
||||
.setClassName(cn.getClassName())
|
||||
.build();
|
||||
targets.add(target);
|
||||
}
|
||||
mCallback.onTargetsAvailable(targets);
|
||||
|
||||
@@ -22,11 +22,18 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation;
|
||||
import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
|
||||
import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage;
|
||||
import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
|
||||
import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT;
|
||||
import static com.android.launcher3.ui.AbstractLauncherUiTest.resolveSystemApp;
|
||||
import static com.android.launcher3.ui.AbstractLauncherUiTest.startAppFast;
|
||||
import static com.android.launcher3.ui.AbstractLauncherUiTest.startTestActivity;
|
||||
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.rule.ShellCommandRule.disableHeadsUpNotification;
|
||||
import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand;
|
||||
import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON;
|
||||
import static com.android.quickstep.NavigationModeSwitchRule.Mode.ZERO_BUTTON;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
@@ -41,10 +48,16 @@ import androidx.test.uiautomator.By;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.Until;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.tapl.BaseOverview;
|
||||
import com.android.launcher3.tapl.LauncherInstrumentation;
|
||||
import com.android.launcher3.tapl.OverviewTask;
|
||||
import com.android.launcher3.tapl.TestHelpers;
|
||||
import com.android.launcher3.testcomponent.TestCommandReceiver;
|
||||
import com.android.launcher3.util.rule.FailureWatcher;
|
||||
import com.android.launcher3.util.rule.SimpleActivityRule;
|
||||
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -53,11 +66,11 @@ import org.junit.rules.TestRule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
/**
|
||||
* TODO: Fix fallback when quickstep is enabled
|
||||
*/
|
||||
public class FallbackRecentsTest {
|
||||
|
||||
private final UiDevice mDevice;
|
||||
@@ -73,6 +86,11 @@ public class FallbackRecentsTest {
|
||||
@Rule
|
||||
public final TestRule mOrderSensitiveRules;
|
||||
|
||||
@Rule
|
||||
public final SimpleActivityRule<RecentsActivity> mActivityMonitor =
|
||||
new SimpleActivityRule(RecentsActivity.class);
|
||||
|
||||
|
||||
public FallbackRecentsTest() throws RemoteException {
|
||||
Instrumentation instrumentation = getInstrumentation();
|
||||
Context context = instrumentation.getContext();
|
||||
@@ -80,9 +98,12 @@ public class FallbackRecentsTest {
|
||||
mDevice.setOrientationNatural();
|
||||
mLauncher = new LauncherInstrumentation(instrumentation);
|
||||
|
||||
mOrderSensitiveRules = RuleChain.
|
||||
outerRule(new NavigationModeSwitchRule(mLauncher)).
|
||||
around(new FailureWatcher(mDevice));
|
||||
if (TestHelpers.isInLauncherProcess()) {
|
||||
Utilities.enableRunningInTestHarnessForTests();
|
||||
}
|
||||
|
||||
mOrderSensitiveRules = RuleChain.outerRule(new NavigationModeSwitchRule(mLauncher))
|
||||
.around(new FailureWatcher(mDevice));
|
||||
|
||||
mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
|
||||
getHomeIntentInPackage(context),
|
||||
@@ -105,7 +126,7 @@ public class FallbackRecentsTest {
|
||||
};
|
||||
}
|
||||
|
||||
@NavigationModeSwitch(mode = THREE_BUTTON)
|
||||
@NavigationModeSwitch
|
||||
@Test
|
||||
public void goToOverviewFromHome() {
|
||||
mDevice.pressHome();
|
||||
@@ -115,7 +136,7 @@ public class FallbackRecentsTest {
|
||||
mLauncher.getBackground().switchToOverview();
|
||||
}
|
||||
|
||||
@NavigationModeSwitch(mode = THREE_BUTTON)
|
||||
@NavigationModeSwitch
|
||||
@Test
|
||||
public void goToOverviewFromApp() {
|
||||
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
|
||||
@@ -123,15 +144,77 @@ public class FallbackRecentsTest {
|
||||
mLauncher.getBackground().switchToOverview();
|
||||
}
|
||||
|
||||
private void startAppFast(String packageName) {
|
||||
final Instrumentation instrumentation = getInstrumentation();
|
||||
final Intent intent = instrumentation.getContext().getPackageManager().
|
||||
getLaunchIntentForPackage(packageName);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
instrumentation.getTargetContext().startActivity(intent);
|
||||
assertTrue(packageName + " didn't start",
|
||||
mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), WAIT_TIME_MS));
|
||||
protected void executeOnRecents(Consumer<RecentsActivity> f) throws Exception {
|
||||
getFromRecents(r -> {
|
||||
f.accept(r);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> T getFromRecents(Function<RecentsActivity, T> f) throws Exception {
|
||||
if (!TestHelpers.isInLauncherProcess()) return null;
|
||||
return MAIN_EXECUTOR.submit(() -> f.apply(mActivityMonitor.getActivity())).get();
|
||||
}
|
||||
|
||||
private BaseOverview pressHomeAndGoToOverview() {
|
||||
mDevice.pressHome();
|
||||
return mLauncher.getBackground().switchToOverview();
|
||||
}
|
||||
|
||||
// TODO: Enable all modes after b/141184247 is fixed
|
||||
@NavigationModeSwitch(mode = ZERO_BUTTON)
|
||||
@Test
|
||||
public void testOverview() throws Exception {
|
||||
startAppFast(getAppPackageName());
|
||||
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
|
||||
startTestActivity(2);
|
||||
|
||||
BaseOverview overview = mLauncher.getBackground().switchToOverview();
|
||||
executeOnRecents(
|
||||
recents -> assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3));
|
||||
|
||||
// Test flinging forward and backward.
|
||||
overview.flingForward();
|
||||
final Integer currentTaskAfterFlingForward = getFromRecents(this::getCurrentOverviewPage);
|
||||
executeOnRecents(recents -> assertTrue("Current task in Overview is still 0",
|
||||
currentTaskAfterFlingForward > 0));
|
||||
|
||||
overview.flingBackward();
|
||||
executeOnRecents(recents -> assertTrue("Flinging back in Overview did nothing",
|
||||
getCurrentOverviewPage(recents) < currentTaskAfterFlingForward));
|
||||
|
||||
// Test opening a task.
|
||||
overview = pressHomeAndGoToOverview();
|
||||
|
||||
OverviewTask task = overview.getCurrentTask();
|
||||
assertNotNull("overview.getCurrentTask() returned null (1)", task);
|
||||
assertNotNull("OverviewTask.open returned null", task.open());
|
||||
assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject(
|
||||
By.pkg(getAppPackageName()).text("TestActivity2")),
|
||||
DEFAULT_UI_TIMEOUT));
|
||||
|
||||
|
||||
// Test dismissing a task.
|
||||
overview = pressHomeAndGoToOverview();
|
||||
final Integer numTasks = getFromRecents(this::getTaskCount);
|
||||
task = overview.getCurrentTask();
|
||||
assertNotNull("overview.getCurrentTask() returned null (2)", task);
|
||||
task.dismiss();
|
||||
executeOnRecents(
|
||||
recents -> assertEquals("Dismissing a task didn't remove 1 task from Overview",
|
||||
numTasks - 1, getTaskCount(recents)));
|
||||
|
||||
// Test dismissing all tasks.
|
||||
pressHomeAndGoToOverview().dismissAllTasks();
|
||||
assertTrue("Fallback Launcher not visible", mDevice.wait(Until.hasObject(By.pkg(
|
||||
mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
|
||||
}
|
||||
|
||||
private int getCurrentOverviewPage(RecentsActivity recents) {
|
||||
return recents.<RecentsView>getOverviewPanel().getCurrentPage();
|
||||
}
|
||||
|
||||
private int getTaskCount(RecentsActivity recents) {
|
||||
return recents.<RecentsView>getOverviewPanel().getTaskViewCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static junit.framework.TestCase.assertNull;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.KeyguardManagerCompat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
public class RecentTasksListTest {
|
||||
|
||||
private ActivityManagerWrapper mockActivityManagerWrapper;
|
||||
|
||||
// Class under test
|
||||
private RecentTasksList mRecentTasksList;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
LooperExecutor mockMainThreadExecutor = mock(LooperExecutor.class);
|
||||
KeyguardManagerCompat mockKeyguardManagerCompat = mock(KeyguardManagerCompat.class);
|
||||
mockActivityManagerWrapper = mock(ActivityManagerWrapper.class);
|
||||
mRecentTasksList = new RecentTasksList(mockMainThreadExecutor, mockKeyguardManagerCompat,
|
||||
mockActivityManagerWrapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTaskRemoved_reloadsAllTasks() {
|
||||
mRecentTasksList.onTaskRemoved(0);
|
||||
verify(mockActivityManagerWrapper, times(1))
|
||||
.getRecentTasks(anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTaskStackChanged_doesNotFetchTasks() {
|
||||
mRecentTasksList.onTaskStackChanged();
|
||||
verify(mockActivityManagerWrapper, times(0))
|
||||
.getRecentTasks(anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
|
||||
ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
|
||||
when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
|
||||
.thenReturn(Collections.singletonList(recentTaskInfo));
|
||||
|
||||
List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, true);
|
||||
|
||||
assertEquals(1, taskList.size());
|
||||
assertNull(taskList.get(0).taskDescription.getLabel());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() {
|
||||
String taskDescription = "Wheeee!";
|
||||
ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
|
||||
recentTaskInfo.taskDescription = new ActivityManager.TaskDescription(taskDescription);
|
||||
when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
|
||||
.thenReturn(Collections.singletonList(recentTaskInfo));
|
||||
|
||||
List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, false);
|
||||
|
||||
assertEquals(1, taskList.size());
|
||||
assertEquals(taskDescription, taskList.get(0).taskDescription.getLabel());
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,5 @@
|
||||
style="@style/BaseIcon"
|
||||
android:textColor="?attr/folderTextColor"
|
||||
android:includeFontPadding="false"
|
||||
android:hapticFeedbackEnabled="false"
|
||||
launcher:iconDisplay="folder" />
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"ስራ"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"መተግበሪያ አልተጫነም።"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"መተግበሪያ አይገኝም"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"İş"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Tətbiq quraşdırılmayıb."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Tətbiq əlçatmazdır"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"কাজ"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"অ্যাপ্লিকেশান ইনস্টল করা নেই৷"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"অ্যাপ্লিকেশান অনুপলব্ধ"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Posao"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Aplikacija nije dostupna"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Feina"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"L\'aplicació no s\'ha instal·lat."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"L\'aplicació no està disponible."</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Εργασία"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Η εφαρμογή δεν έχει εγκατασταθεί."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Η εφαρμογή δεν είναι διαθέσιμη"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Lana"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Aplikazioa instalatu gabe dago."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Ez dago erabilgarri aplikazioa"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Android Work"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Application indisponible"</string>
|
||||
@@ -136,7 +135,7 @@
|
||||
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Retrouvez ici vos applications professionnelles"</string>
|
||||
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Les applications professionnelles sont accompagnées d\'un badge et sont sécurisées par votre organisation. Vous pouvez les déplacer vers votre écran d\'accueil pour y accéder plus facilement."</string>
|
||||
<string name="work_mode_on_label" msgid="4781128097185272916">"Géré par votre organisation"</string>
|
||||
<string name="work_mode_off_label" msgid="3194894777601421047">"Les notifications et les applications sont désactivées"</string>
|
||||
<string name="work_mode_off_label" msgid="3194894777601421047">"Notifications et applications désactivées"</string>
|
||||
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fermer"</string>
|
||||
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fermé"</string>
|
||||
<string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Traballo"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"A aplicación non está instalada"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"A aplicación non está dispoñible"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"કાર્યાલય"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"ઍપ્લિકેશન ઇન્સ્ટોલ થઈ નથી."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"ઍપ્લિકેશન ઉપલબ્ધ નથી"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"कार्यस्थल"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"ऐप्लिकेशन इंस्टॉल नहीं है."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"ऐप्लिकेशन उपलब्ध नहीं है"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Posao"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Aplikacija nije dostupna"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Աշխատանքային"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Ծրագիրը տեղադրված չէ:"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Հավելվածը հասանելի չէ"</string>
|
||||
@@ -87,7 +86,7 @@
|
||||
<string name="allow_rotation_desc" msgid="8662546029078692509">"Հեռախոսը պտտելու դեպքում"</string>
|
||||
<string name="notification_dots_title" msgid="9062440428204120317">"Ծանուցումների կետիկներ"</string>
|
||||
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Միացված է"</string>
|
||||
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Անջատած է"</string>
|
||||
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Անջատված է"</string>
|
||||
<string name="title_missing_notification_access" msgid="7503287056163941064">"Անհրաժեշտ է ծանուցման թույլտվություն"</string>
|
||||
<string name="msg_missing_notification_access" msgid="281113995110910548">"Ծանուցումների կետիկները ցուցադրելու համար միացրեք ծանուցումները <xliff:g id="NAME">%1$s</xliff:g>-ի համար"</string>
|
||||
<string name="title_change_settings" msgid="1376365968844349552">"Փոխել կարգավորումները"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Kantor"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Aplikasi tidak dipasang."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Aplikasi tidak tersedia"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"ការងារ"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"មិនបានដំឡើងកម្មវិធី។"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"មិនមានកម្មវិធី"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"ಕೆಲಸ"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Жумуш"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Колдонмо орнотулган эмес."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Колдонмо жеткиликтүү эмес"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Стартер3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Работа"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Апликацијата не е инсталирана."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Апликацијата не е достапна"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"ဖွင့်တင်စက်၃"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"အလုပ်"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"အက်ပ်မထည့်သွင်းထားပါ"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"အက်ပ်လက်လှမ်း မမှီပါ"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Trabalho"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"A aplicação não está instalada."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"A aplicação não está disponível"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Tela de início 3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Trabalho"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"O app não está instalado."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"O app não está disponível"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Aplicația nu este instalată."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Aplicația nu este disponibilă"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Pracovné"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Aplikácia nie je nainštalovaná."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Aplikácia nie je k dispozícii"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Nisësi3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Puna"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacioni nuk është i instaluar."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Aplikacioni nuk mundësohet"</string>
|
||||
@@ -41,8 +40,8 @@
|
||||
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Kërko për më shumë aplikacione"</string>
|
||||
<string name="label_application" msgid="8531721983832654978">"Aplikacioni"</string>
|
||||
<string name="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
|
||||
<string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Prek dhe mbaj prekur për të zgjedhur një shkurtore."</string>
|
||||
<string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."</string>
|
||||
<string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Prek dhe mbaj të shtypur për të zgjedhur një shkurtore."</string>
|
||||
<string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Prek dy herë dhe mbaj të shtypur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."</string>
|
||||
<string name="out_of_space" msgid="4691004494942118364">"Nuk ka më hapësirë në këtë ekran bazë."</string>
|
||||
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Nuk ka më hapësirë në tabakanë \"Të preferuarat\""</string>
|
||||
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista e aplikacioneve"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Kazini"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Programu haijasakinishwa."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Programu haipatikani"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"பணியிடம்"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"ஆப்ஸ் நிறுவப்படவில்லை."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"ஆப்ஸ் இல்லை"</string>
|
||||
@@ -36,7 +35,7 @@
|
||||
<string name="add_item_request_drag_hint" msgid="5899764264480397019">"நீங்களே சேர்க்க, தொட்டுப் பிடித்திருக்கவும்"</string>
|
||||
<string name="place_automatically" msgid="8064208734425456485">"தானாகவே சேர்"</string>
|
||||
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"பயன்பாடுகளில் தேடுக"</string>
|
||||
<string name="all_apps_loading_message" msgid="5813968043155271636">"பயன்பாடுகளை ஏற்றுகிறது…"</string>
|
||||
<string name="all_apps_loading_message" msgid="5813968043155271636">"ஆப்ஸை ஏற்றுகிறது…"</string>
|
||||
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"</string>
|
||||
<string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
|
||||
<string name="label_application" msgid="8531721983832654978">"ஆப்ஸ்"</string>
|
||||
@@ -45,7 +44,7 @@
|
||||
<string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ஷார்ட்கட்டைச் சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் (அ) தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."</string>
|
||||
<string name="out_of_space" msgid="4691004494942118364">"முகப்புத் திரையில் இடமில்லை."</string>
|
||||
<string name="hotseat_out_of_space" msgid="7448809638125333693">"பிடித்தவை ட்ரேயில் இடமில்லை"</string>
|
||||
<string name="all_apps_button_label" msgid="8130441508702294465">"பயன்பாடுகளின் பட்டியல்"</string>
|
||||
<string name="all_apps_button_label" msgid="8130441508702294465">"ஆப்ஸின் பட்டியல்"</string>
|
||||
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"தனிப்பட்ட ஆப்ஸ் பட்டியல்"</string>
|
||||
<string name="all_apps_button_work_label" msgid="7270707118948892488">"பணி ஆப்ஸ் பட்டியல்"</string>
|
||||
<string name="all_apps_home_button_label" msgid="252062713717058851">"முகப்பு"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"కార్యాలయం"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"యాప్ ఇన్స్టాల్ చేయబడలేదు."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"యాప్ అందుబాటులో లేదు"</string>
|
||||
@@ -53,7 +52,7 @@
|
||||
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"అన్ఇన్స్టాల్ చేయి"</string>
|
||||
<string name="app_info_drop_target_label" msgid="692894985365717661">"యాప్ సమాచారం"</string>
|
||||
<string name="install_drop_target_label" msgid="2539096853673231757">"ఇన్స్టాల్ చేయండి"</string>
|
||||
<string name="permlab_install_shortcut" msgid="5632423390354674437">"సత్వరమార్గాలను ఇన్స్టాల్ చేయడం"</string>
|
||||
<string name="permlab_install_shortcut" msgid="5632423390354674437">"షార్ట్కట్లను ఇన్స్టాల్ చేయడం"</string>
|
||||
<string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
|
||||
<string name="permlab_read_settings" msgid="1941457408239617576">"హోమ్ సెట్టింగ్లు మరియు సత్వరమార్గాలను చదవడం"</string>
|
||||
<string name="permdesc_read_settings" msgid="5833423719057558387">"హోమ్లో సెట్టింగ్లు మరియు సత్వరమార్గాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"งาน"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"ไม่ได้ติดตั้งแอป"</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"แอปไม่พร้อมใช้งาน"</string>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name" msgid="649227358658669779">"Isiqalisi3"</string>
|
||||
<string name="folder_name" msgid="7371454440695724752"></string>
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Umsebenzi"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"Uhlelo lokusebenza alufakiwe."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"Uhlelo lokusebenza alutholakali"</string>
|
||||
|
||||
+8
-16
@@ -115,7 +115,8 @@
|
||||
<attr name="numFolderColumns" format="integer" />
|
||||
<!-- numHotseatIcons defaults to numColumns, if not specified -->
|
||||
<attr name="numHotseatIcons" format="integer" />
|
||||
|
||||
<!-- numAllAppsColumns defaults to numColumns, if not specified -->
|
||||
<attr name="numAllAppsColumns" format="integer" />
|
||||
<attr name="defaultLayoutId" format="reference" />
|
||||
<attr name="demoModeLayoutId" format="reference" />
|
||||
</declare-styleable>
|
||||
@@ -131,6 +132,12 @@
|
||||
<attr name="iconTextSize" format="float" />
|
||||
<!-- If true, this display option is used to determine the default grid -->
|
||||
<attr name="canBeDefault" format="boolean" />
|
||||
|
||||
<!-- The following values are only enabled if grid is supported. -->
|
||||
<!-- allAppsIconSize defaults to iconSize, if not specified -->
|
||||
<attr name="allAppsIconSize" format="float" />
|
||||
<!-- allAppsIconTextSize defaults to iconTextSize, if not specified -->
|
||||
<attr name="allAppsIconTextSize" format="float" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CellLayout">
|
||||
@@ -152,21 +159,6 @@
|
||||
<attr name="canThumbDetach" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CustomAppWidgetProviderInfo">
|
||||
<attr name="providerId" format="integer" />
|
||||
|
||||
<attr name="android:label" />
|
||||
<attr name="android:initialLayout" />
|
||||
<attr name="android:icon" />
|
||||
<attr name="android:previewImage" />
|
||||
<attr name="android:resizeMode" />
|
||||
|
||||
<attr name="numRows" />
|
||||
<attr name="numColumns" />
|
||||
<attr name="numMinRows" format="integer" />
|
||||
<attr name="numMinColumns" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="PreviewFragment">
|
||||
<attr name="android:name" />
|
||||
<attr name="android:id" />
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
|
||||
<!-- Application name -->
|
||||
<string name="app_name">Launcher3</string>
|
||||
<!-- Default folder name -->
|
||||
<string name="folder_name"></string>
|
||||
<!-- Work folder name -->
|
||||
<string name="work_folder_name">Work</string>
|
||||
<!-- Displayed when user selects a shortcut for an app that was uninstalled [CHAR_LIMIT=none]-->
|
||||
@@ -105,6 +103,9 @@
|
||||
<!-- Label for install drop target. [CHAR_LIMIT=20] -->
|
||||
<string name="install_drop_target_label">Install</string>
|
||||
|
||||
<!-- Label for install dismiss prediction. -->
|
||||
<string translatable="false" name="dismiss_prediction_label">Dismiss prediction</string>
|
||||
|
||||
<!-- Permissions: -->
|
||||
<skip />
|
||||
<!-- Permission short label -->
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<widgets>
|
||||
<!-- Sample widget definition
|
||||
<widget
|
||||
android:label="My custom widget"
|
||||
android:initialLayout="@layout/sample_widget_layout"
|
||||
android:icon="@drawable/ic_launcher_home"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
launcher:numRows="2"
|
||||
launcher:numColumns="3"
|
||||
launcher:numMinRows="1"
|
||||
launcher:numMinColumns="2"
|
||||
launcher:providerId="1" />
|
||||
-->
|
||||
</widgets>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user