Snap for 4690345 from 96992e9e05 to qt-release

Change-Id: Ia05cc073421d590b48a55860f89eb492ec0597bc
This commit is contained in:
android-build-team Robot
2018-03-30 09:32:22 +00:00
182 changed files with 4894 additions and 3909 deletions
+1 -1
View File
@@ -39,7 +39,7 @@
public int getY();
}
-keep class com.android.launcher3.dragndrop.DragLayer$LayoutParams {
-keep class com.android.launcher3.views.BaseDragLayer$LayoutParams {
public void setWidth(int);
public int getWidth();
public void setHeight(int);
+15 -1
View File
@@ -47,7 +47,21 @@
<!-- STOPSHIP: Change exported to false once all the integration is complete.
It is set to true so that the activity can be started from command line -->
<activity android:name="com.android.quickstep.RecentsActivity"
android:exported="true" />
android:exported="true"
android:excludeFromRecents="true" />
<!-- Content provider to settings search -->
<provider
android:name="com.android.quickstep.LauncherSearchIndexablesProvider"
android:authorities="com.android.launcher3"
android:grantUriPermissions="true"
android:multiprocess="true"
android:permission="android.permission.READ_SEARCH_INDEXABLES"
android:exported="true">
<intent-filter>
<action android:name="android.content.action.SEARCH_INDEXABLES_PROVIDER" />
</intent-filter>
</provider>
</application>
</manifest>
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 B

@@ -15,15 +15,17 @@
-->
<com.android.quickstep.RecentsRootView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.quickstep.FallbackRecentsView
xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="@style/HomeScreenElementTheme"
android:id="@+id/overview_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false" />
android:clipToPadding="false"
android:theme="@style/HomeScreenElementTheme" />
</com.android.quickstep.RecentsRootView>
+2 -2
View File
@@ -21,7 +21,7 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:alpha="0.0"
android:visibility="invisible" >
android:visibility="invisible"
android:focusableInTouchMode="true" >
</com.android.quickstep.views.LauncherRecentsView>
+1 -2
View File
@@ -22,7 +22,6 @@
<dimen name="task_corner_radius">2dp</dimen>
<dimen name="task_fade_length">20dp</dimen>
<dimen name="recents_page_spacing">10dp</dimen>
<dimen name="recents_page_fade_length">100dp</dimen>
<!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
loading full resolution screenshots. -->
@@ -34,7 +33,7 @@
<!-- Launcher app transition -->
<dimen name="content_trans_y">25dp</dimen>
<dimen name="workspace_trans_y">80dp</dimen>
<dimen name="recents_adjacent_trans_x">120dp</dimen>
<dimen name="recents_adjacent_trans_x">140dp</dimen>
<dimen name="recents_adjacent_trans_y">80dp</dimen>
<fraction name="recents_adjacent_scale">150%</fraction>
</resources>
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 Google Inc.
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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:key="pref_add_icon_to_home"
android:title="@string/auto_add_shortcuts_label"
android:summary="@string/auto_add_shortcuts_description"
android:defaultValue="true"
/>
<ListPreference
android:key="pref_override_icon_shape"
android:title="@string/icon_shape_override_label"
android:summary="@string/icon_shape_override_label_location"
android:entries="@array/icon_shape_override_paths_names"
android:entryValues="@array/icon_shape_override_paths_values"
android:defaultValue=""
android:persistent="false" />
</PreferenceScreen>
@@ -15,27 +15,92 @@
*/
package com.android.launcher3;
import static com.android.systemui.shared.recents.utilities.Utilities
.postAtFrontOfQueueAsynchronously;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.BinderThread;
import android.support.annotation.UiThread;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
@TargetApi(Build.VERSION_CODES.P)
public abstract class LauncherAnimationRunner extends AnimatorListenerAdapter
implements RemoteAnimationRunnerCompat {
public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
private static final int REFRESH_RATE_MS = 16;
AnimatorSet mAnimator;
private Launcher mLauncher;
private final Handler mHandler;
LauncherAnimationRunner(Launcher launcher) {
mLauncher = launcher;
private Runnable mSysFinishRunnable;
private AnimatorSet mAnimator;
public LauncherAnimationRunner(Handler handler) {
mHandler = handler;
}
@BinderThread
@Override
public void onAnimationStart(RemoteAnimationTargetCompat[] targetCompats, Runnable runnable) {
postAtFrontOfQueueAsynchronously(mHandler, () -> {
// Finish any previous animation
finishSystemAnimation();
mSysFinishRunnable = runnable;
mAnimator = getAnimator(targetCompats);
if (mAnimator == null) {
finishSystemAnimation();
return;
}
mAnimator.addListener(this);
mAnimator.start();
// Because t=0 has the app icon in its original spot, we can skip the
// first frame and have the same movement one frame earlier.
mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
});
}
@UiThread
public abstract AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats);
@UiThread
@Override
public void onAnimationEnd(Animator animation) {
if (animation == mAnimator) {
mAnimator = null;
finishSystemAnimation();
}
}
/**
* Called by the system
*/
@BinderThread
@Override
public void onAnimationCancelled() {
postAtFrontOfQueueAsynchronously(mLauncher.getWindow().getDecorView().getHandler(), () -> {
postAtFrontOfQueueAsynchronously(mHandler, () -> {
if (mAnimator != null) {
mAnimator.cancel();
mAnimator.removeListener(this);
mAnimator.end();
mAnimator = null;
}
});
}
@UiThread
private void finishSystemAnimation() {
if (mSysFinishRunnable != null) {
mSysFinishRunnable.run();
mSysFinishRunnable = null;
}
}
}
@@ -21,7 +21,6 @@ import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;
import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -41,6 +40,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Surface;
import android.view.View;
@@ -80,7 +80,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
implements OnDeviceProfileChangeListener {
private static final String TAG = "LauncherTransition";
private static final int REFRESH_RATE_MS = 16;
private static final int STATUS_BAR_TRANSITION_DURATION = 120;
private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
@@ -99,7 +98,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
private final DragLayer mDragLayer;
private final Launcher mLauncher;
private DeviceProfile mDeviceProfile;
private final Handler mHandler;
private final boolean mIsRtl;
private final float mContentTransY;
private final float mWorkspaceTransY;
@@ -107,17 +108,23 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
private final float mRecentsTransY;
private final float mRecentsScale;
private DeviceProfile mDeviceProfile;
private View mFloatingView;
private boolean mIsRtl;
private LauncherTransitionAnimator mCurrentAnimator;
private final AnimatorListenerAdapter mReapplyStateListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLauncher.getStateManager().reapplyState();
}
};
public LauncherAppTransitionManagerImpl(Context context) {
mLauncher = Launcher.getLauncher(context);
mDragLayer = mLauncher.getDragLayer();
mHandler = new Handler(Looper.getMainLooper());
mIsRtl = Utilities.isRtl(mLauncher.getResources());
mDeviceProfile = mLauncher.getDeviceProfile();
mIsRtl = Utilities.isRtl(mLauncher.getResources());
Resources res = mLauncher.getResources();
mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
@@ -135,26 +142,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
mDeviceProfile = dp;
}
private void setCurrentAnimator(LauncherTransitionAnimator animator) {
if (isAnimating()) {
mCurrentAnimator.cancel();
}
mCurrentAnimator = animator;
}
@Override
public void finishLauncherAnimation() {
if (isAnimating()) {
mCurrentAnimator.finishLauncherAnimation();
}
mCurrentAnimator = null;
}
@Override
public boolean isAnimating() {
return mCurrentAnimator != null && mCurrentAnimator.isRunning();
}
/**
* @return ActivityOptions with remote animations that controls how the window of the opening
* targets are displayed.
@@ -162,58 +149,26 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
@Override
public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) {
if (hasControlRemoteAppTransitionPermission()) {
TaskView taskView = findTaskViewToLaunch(launcher, v);
try {
RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mLauncher) {
RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mHandler) {
@Override
public void onAnimationStart(RemoteAnimationTargetCompat[] targets,
Runnable finishedCallback) {
// Post at front of queue ignoring sync barriers to make sure it gets
// processed before the next frame.
postAtFrontOfQueueAsynchronously(v.getHandler(), () -> {
final boolean removeTrackingView;
LauncherTransitionAnimator animator = composeRecentsLaunchAnimator(
taskView == null ? v : taskView, targets);
if (animator != null) {
// We are animating the task view directly, do not remove it after
removeTrackingView = false;
} else {
animator = composeAppLaunchAnimator(v, targets);
// A new floating view is created for the animation, remove it after
removeTrackingView = true;
}
setCurrentAnimator(animator);
mAnimator = animator.getAnimatorSet();
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// Reset launcher to normal state
v.setVisibility(View.VISIBLE);
if (removeTrackingView) {
((ViewGroup) mDragLayer.getParent()).removeView(
mFloatingView);
}
mDragLayer.setAlpha(1f);
mDragLayer.setTranslationY(0f);
View appsView = mLauncher.getAppsView();
appsView.setAlpha(1f);
appsView.setTranslationY(0f);
finishedCallback.run();
}
});
mAnimator.start();
// Because t=0 has the app icon in its original spot, we can skip the
// first frame and have the same movement one frame earlier.
mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
});
public AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats) {
Animator[] anims = composeRecentsLaunchAnimator(v, targetCompats);
AnimatorSet anim = new AnimatorSet();
if (anims != null) {
anim.playTogether(anims);
} else {
anim.play(getLauncherAnimators(v, targetCompats));
anim.play(getWindowAnimators(v, targetCompats));
}
mLauncher.getStateManager().setCurrentAnimation(anim);
return anim;
}
};
int duration = taskView != null ? RECENTS_LAUNCH_DURATION : APP_LAUNCH_DURATION;
int duration = findTaskViewToLaunch(launcher, v, null) != null
? RECENTS_LAUNCH_DURATION : APP_LAUNCH_DURATION;
int statusBarTransitionDelay = duration - STATUS_BAR_TRANSITION_DURATION;
return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
runner, duration, statusBarTransitionDelay));
@@ -232,18 +187,19 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
* Otherwise, we will assume we are using a normal app transition, but it's possible that the
* opening remote target (which we don't get until onAnimationStart) will resolve to a TaskView.
*/
private TaskView findTaskViewToLaunch(Launcher launcher, View v) {
private TaskView findTaskViewToLaunch(
BaseDraggingActivity activity, View v, RemoteAnimationTargetCompat[] targets) {
if (v instanceof TaskView) {
return (TaskView) v;
}
if (!launcher.isInState(LauncherState.OVERVIEW)) {
return null;
}
RecentsView recentsView = activity.getOverviewPanel();
// It's possible that the launched view can still be resolved to a visible task view, check
// the task id of the opening task and see if we can find a match.
if (v.getTag() instanceof ItemInfo) {
ItemInfo itemInfo = (ItemInfo) v.getTag();
ComponentName componentName = itemInfo.getTargetComponent();
if (componentName != null) {
RecentsView recentsView = launcher.getOverviewPanel();
for (int i = 0; i < recentsView.getChildCount(); i++) {
TaskView taskView = (TaskView) recentsView.getPageAt(i);
if (recentsView.isTaskViewVisible(taskView)) {
@@ -255,32 +211,10 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
}
}
return null;
}
/**
* Composes the animations for a launch from the recents list if possible.
*/
private LauncherTransitionAnimator composeRecentsLaunchAnimator(View v,
RemoteAnimationTargetCompat[] targets) {
RecentsView recentsView = mLauncher.getOverviewPanel();
boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
MutableBoolean skipLauncherChanges = new MutableBoolean(!launcherClosing);
if (v instanceof TaskView) {
// We already found a task view to launch, so use that for the animation.
TaskView taskView = (TaskView) v;
return new LauncherTransitionAnimator(getRecentsLauncherAnimator(recentsView, taskView),
getRecentsWindowAnimator(taskView, skipLauncherChanges, targets));
}
// It's possible that the launched view can still be resolved to a visible task view, check
// the task id of the opening task and see if we can find a match.
// Ensure recents is actually visible
if (!mLauncher.getStateManager().getState().overviewUi) {
if (targets == null) {
return null;
}
// Resolve the opening task id
int openingTaskId = -1;
for (RemoteAnimationTargetCompat target : targets) {
@@ -301,19 +235,35 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
if (taskView == null || !recentsView.isTaskViewVisible(taskView)) {
return null;
}
return taskView;
}
/**
* Composes the animations for a launch from the recents list if possible.
*/
private Animator[] composeRecentsLaunchAnimator(View v,
RemoteAnimationTargetCompat[] targets) {
// Ensure recents is actually visible
if (!mLauncher.getStateManager().getState().overviewUi) {
return null;
}
RecentsView recentsView = mLauncher.getOverviewPanel();
boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
boolean skipLauncherChanges = !launcherClosing;
TaskView taskView = findTaskViewToLaunch(mLauncher, v, targets);
if (taskView == null) {
return null;
}
// Found a visible recents task that matches the opening app, lets launch the app from there
Animator launcherAnim;
AnimatorListenerAdapter windowAnimEndListener;
final AnimatorListenerAdapter windowAnimEndListener;
if (launcherClosing) {
launcherAnim = getRecentsLauncherAnimator(recentsView, taskView);
windowAnimEndListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// Make sure recents gets fixed up by resetting task alphas and scales, etc.
mLauncher.getStateManager().reapplyState();
}
};
// Make sure recents gets fixed up by resetting task alphas and scales, etc.
windowAnimEndListener = mReapplyStateListener;
} else {
AnimatorPlaybackController controller =
mLauncher.getStateManager()
@@ -330,7 +280,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
Animator windowAnim = getRecentsWindowAnimator(taskView, skipLauncherChanges, targets);
windowAnim.addListener(windowAnimEndListener);
return new LauncherTransitionAnimator(launcherAnim, windowAnim, skipLauncherChanges);
return new Animator[] {launcherAnim, windowAnim};
}
/**
@@ -372,26 +322,24 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
} else {
// We are launching an adjacent task, so parallax the center and other adjacent task.
TaskView centerTask = (TaskView) recentsView.getPageAt(centerTaskIndex);
float translationX = Math.abs(v.getTranslationX());
ObjectAnimator centerTaskParallaxToRight =
float translationX = mRecentsTransX / 2;
ObjectAnimator centerTaskParallaxOffscreen =
LauncherAnimUtils.ofPropertyValuesHolder(centerTask,
new PropertyListBuilder()
.scale(v.getScaleX())
.translationX(isRtl ? -translationX : translationX)
.build());
launcherAnimator.play(centerTaskParallaxToRight);
launcherAnimator.play(centerTaskParallaxOffscreen);
int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - launchedTaskIndex);
if (otherAdjacentTaskIndex >= 0
&& otherAdjacentTaskIndex < recentsView.getPageCount()) {
TaskView otherAdjacentTask = (TaskView) recentsView.getPageAt(
otherAdjacentTaskIndex);
ObjectAnimator otherAdjacentTaskParallaxToRight =
ObjectAnimator otherAdjacentTaskParallaxOffscreen =
LauncherAnimUtils.ofPropertyValuesHolder(otherAdjacentTask,
new PropertyListBuilder()
.translationX(otherAdjacentTask.getTranslationX()
+ (isRtl ? -translationX : translationX))
.translationX(isRtl ? -translationX : translationX)
.build());
launcherAnimator.play(otherAdjacentTaskParallaxToRight);
launcherAnimator.play(otherAdjacentTaskParallaxOffscreen);
}
}
@@ -420,7 +368,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
* @return Animator that controls the window of the opening targets for the recents launch
* animation.
*/
private ValueAnimator getRecentsWindowAnimator(TaskView v, MutableBoolean skipLauncherChanges,
private ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipLauncherChanges,
RemoteAnimationTargetCompat[] targets) {
Rect taskViewBounds = new Rect();
mDragLayer.getDescendantRectRelativeToSelf(v, taskViewBounds);
@@ -456,7 +404,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
final float percent = animation.getAnimatedFraction();
TaskWindowBounds tw = recentsInterpolator.interpolate(percent);
if (!skipLauncherChanges.value) {
if (!skipLauncherChanges) {
v.setScaleX(tw.taskScale);
v.setScaleY(tw.taskScale);
v.setTranslationX(tw.taskX);
@@ -471,9 +419,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
crop.set(tw.winCrop);
// Fade in the app window.
float alphaDelay = 0;
float alphaDuration = 75;
float alpha = getValue(0f, 1f, alphaDelay, alphaDuration,
float alpha = getValue(0f, 1f, 0, alphaDuration,
appAnimator.getDuration() * percent, Interpolators.LINEAR);
TransactionCompat t = new TransactionCompat();
@@ -487,7 +434,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
t.setMatrix(target.leash, matrix);
t.setWindowCrop(target.leash, crop);
if (!skipLauncherChanges.value) {
if (!skipLauncherChanges) {
t.deferTransactionUntil(target.leash, surface, frameNumber);
}
}
@@ -504,15 +451,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
return appAnimator;
}
/**
* Composes the animations for a launch from an app icon.
*/
private LauncherTransitionAnimator composeAppLaunchAnimator(View v,
RemoteAnimationTargetCompat[] targets) {
return new LauncherTransitionAnimator(getLauncherAnimators(v, targets),
getWindowAnimators(v, targets));
}
/**
* @return Animators that control the movements of the Launcher and icon of the opening target.
*/
@@ -543,7 +481,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
if (mLauncher.isInState(LauncherState.ALL_APPS) && !mDeviceProfile.isVerticalBarLayout()) {
// All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
View appsView = mLauncher.getAppsView();
final View appsView = mLauncher.getAppsView();
final float startAlpha = appsView.getAlpha();
final float startY = appsView.getTranslationY();
appsView.setAlpha(alphas[0]);
appsView.setTranslationY(trans[0]);
@@ -556,6 +496,14 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
launcherAnimator.play(alpha);
launcherAnimator.play(transY);
launcherAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
appsView.setAlpha(startAlpha);
appsView.setTranslationY(startY);
}
});
} else {
mDragLayer.setAlpha(alphas[0]);
mDragLayer.setTranslationY(trans[0]);
@@ -570,6 +518,13 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
launcherAnimator.play(dragLayerAlpha);
launcherAnimator.play(dragLayerTransY);
launcherAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mDragLayer.setAlpha(1);
mDragLayer.setTranslationY(0);
}
});
}
return launcherAnimator;
}
@@ -588,22 +543,19 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
// Position the floating view exactly on top of the original
Rect rect = new Rect();
final boolean isDeepShortcutTextView = v instanceof DeepShortcutTextView
&& v.getParent() != null && v.getParent() instanceof DeepShortcutView;
if (isDeepShortcutTextView) {
// Deep shortcut views have their icon drawn in a sibling view.
final boolean fromDeepShortcutView = v.getParent() instanceof DeepShortcutView;
if (fromDeepShortcutView) {
// Deep shortcut views have their icon drawn in a separate view.
DeepShortcutView view = (DeepShortcutView) v.getParent();
mDragLayer.getDescendantRectRelativeToSelf(view.getIconView(), rect);
} else {
mDragLayer.getDescendantRectRelativeToSelf(v, rect);
}
final int viewLocationStart = mIsRtl
? mDeviceProfile.widthPx - rect.right
: rect.left;
final int viewLocationTop = rect.top;
int viewLocationLeft = rect.left;
int viewLocationTop = rect.top;
float startScale = 1f;
if (isBubbleTextView && !isDeepShortcutTextView) {
if (isBubbleTextView && !fromDeepShortcutView) {
BubbleTextView btv = (BubbleTextView) v;
btv.getIconBounds(rect);
Drawable dr = btv.getIcon();
@@ -613,12 +565,24 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
} else {
rect.set(0, 0, rect.width(), rect.height());
}
viewLocationLeft += rect.left;
viewLocationTop += rect.top;
int viewLocationStart = mIsRtl
? mDeviceProfile.widthPx - rect.right
: viewLocationLeft;
LayoutParams lp = new LayoutParams(rect.width(), rect.height());
lp.ignoreInsets = true;
lp.setMarginStart(viewLocationStart + rect.left);
lp.topMargin = viewLocationTop + rect.top;
lp.setMarginStart(viewLocationStart);
lp.topMargin = viewLocationTop;
mFloatingView.setLayoutParams(lp);
// Set the properties here already to make sure they'are available when running the first
// animation frame.
mFloatingView.setLeft(viewLocationLeft);
mFloatingView.setTop(viewLocationTop);
mFloatingView.setRight(viewLocationLeft + rect.width());
mFloatingView.setBottom(viewLocationTop + rect.height());
// Swap the two views in place.
((ViewGroup) mDragLayer.getParent()).addView(mFloatingView);
v.setVisibility(View.INVISIBLE);
@@ -663,6 +627,14 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
alpha.setInterpolator(Interpolators.LINEAR);
appIconAnimatorSet.play(alpha);
appIconAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// Reset launcher to normal state
v.setVisibility(View.VISIBLE);
((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView);
}
});
return appIconAnimatorSet;
}
@@ -671,10 +643,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
*/
private ValueAnimator getWindowAnimators(View v, RemoteAnimationTargetCompat[] targets) {
Rect bounds = new Rect();
boolean isDeepShortcutTextView = v instanceof DeepShortcutTextView
&& v.getParent() != null && v.getParent() instanceof DeepShortcutView;
if (isDeepShortcutTextView) {
// Deep shortcut views have their icon drawn in a sibling view.
if (v.getParent() instanceof DeepShortcutView) {
// Deep shortcut views have their icon drawn in a separate view.
DeepShortcutView view = (DeepShortcutView) v.getParent();
mDragLayer.getDescendantRectRelativeToSelf(view.getIconView(), bounds);
} else if (v instanceof BubbleTextView) {
@@ -728,9 +698,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
matrix.postTranslate(transX0, transY0);
// Fade in the app window.
float alphaDelay = 0;
float alphaDuration = 60;
float alpha = getValue(0f, 1f, alphaDelay, alphaDuration,
float alpha = getValue(0f, 1f, 0, alphaDuration,
appAnimator.getDuration() * percent, Interpolators.LINEAR);
// Animate the window crop so that it starts off as a square, and then reveals
@@ -775,6 +744,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
try {
RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
WindowManagerWrapper.ACTIVITY_TYPE_STANDARD,
new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(),
CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
@@ -802,40 +772,25 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
* ie. pressing home, swiping up from nav bar.
*/
private RemoteAnimationRunnerCompat getWallpaperOpenRunner() {
return new LauncherAnimationRunner(mLauncher) {
return new LauncherAnimationRunner(mHandler) {
@Override
public void onAnimationStart(RemoteAnimationTargetCompat[] targets,
Runnable finishedCallback) {
Handler handler = mLauncher.getWindow().getDecorView().getHandler();
postAtFrontOfQueueAsynchronously(handler, () -> {
if ((Utilities.getPrefs(mLauncher)
.getBoolean("pref_use_screenshot_for_swipe_up", false)
&& mLauncher.getStateManager().getState().overviewUi)
|| !launcherIsATargetWithMode(targets, MODE_OPENING)) {
// We use a separate transition for Overview mode. And we can skip the
// animation in cases where Launcher is not in the set of opening targets.
// This can happen when Launcher is already visible. ie. Closing a dialog.
setCurrentAnimator(null);
finishedCallback.run();
return;
}
public AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats) {
if (mLauncher.getStateManager().getState().overviewUi) {
// We use a separate transition for Overview mode.
return null;
}
LauncherTransitionAnimator animator = new LauncherTransitionAnimator(
getLauncherResumeAnimation(), getClosingWindowAnimators(targets));
setCurrentAnimator(animator);
mAnimator = animator.getAnimatorSet();
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
finishedCallback.run();
}
});
mAnimator.start();
AnimatorSet anim = new AnimatorSet();
anim.play(getClosingWindowAnimators(targetCompats));
// Because t=0 has the app icon in its original spot, we can skip the
// first frame and have the same movement one frame earlier.
mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
});
if (launcherIsATargetWithMode(targetCompats, MODE_OPENING)) {
AnimatorSet contentAnimation = getLauncherResumeAnimation();
anim.play(contentAnimation);
// Only register the content animation for cancellation when state changes
mLauncher.getStateManager().setCurrentAnimation(contentAnimation);
}
return anim;
}
};
}
@@ -906,12 +861,17 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
return contentAnimator;
} else {
AnimatorSet workspaceAnimator = new AnimatorSet();
mLauncher.getWorkspace().setTranslationY(mWorkspaceTransY);
mLauncher.getWorkspace().setAlpha(0f);
workspaceAnimator.play(ObjectAnimator.ofFloat(mLauncher.getWorkspace(),
View.TRANSLATION_Y, mWorkspaceTransY, 0));
workspaceAnimator.play(ObjectAnimator.ofFloat(mLauncher.getWorkspace(), View.ALPHA,
0, 1f));
View currentPage = ((CellLayout) mLauncher.getWorkspace()
.getChildAt(mLauncher.getWorkspace().getCurrentPage()))
.getShortcutsAndWidgets();
currentPage.setAlpha(0f);
workspaceAnimator.play(ObjectAnimator.ofFloat(currentPage, View.ALPHA, 0, 1f));
workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
workspaceAnimator.setDuration(333);
workspaceAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
@@ -939,6 +899,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
AnimatorSet resumeLauncherAnimation = new AnimatorSet();
resumeLauncherAnimation.play(workspaceAnimator);
resumeLauncherAnimation.playSequentially(allAppsSlideIn, allAppsOvershoot);
resumeLauncherAnimation.addListener(mReapplyStateListener);
return resumeLauncherAnimation;
}
}
@@ -0,0 +1,54 @@
/*
* 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.launcher3;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import android.annotation.TargetApi;
import android.os.Build;
import com.android.launcher3.states.InternalStateHandler;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import java.util.function.BiPredicate;
@TargetApi(Build.VERSION_CODES.P)
public class LauncherInitListener extends InternalStateHandler implements ActivityInitListener {
private final BiPredicate<Launcher, Boolean> mOnInitListener;
public LauncherInitListener(BiPredicate<Launcher, Boolean> onInitListener) {
mOnInitListener = onInitListener;
}
@Override
protected boolean init(Launcher launcher, boolean alreadyOnHome) {
// For the duration of the gesture, lock the screen orientation to ensure that we do not
// rotate mid-quickscrub
launcher.getRotationHelper().setStateHandlerRequest(REQUEST_LOCK);
return mOnInitListener.test(launcher, alreadyOnHome);
}
@Override
public void register() {
initWhenReady();
}
@Override
public void unregister() {
clearReference();
}
}
@@ -1,75 +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.launcher3;
import android.animation.Animator;
import android.animation.AnimatorSet;
/**
* Creates an AnimatorSet consisting on one Animator for Launcher transition, and one Animator for
* the Window transitions.
*
* Allows for ending the Launcher animator without ending the Window animator.
*/
public class LauncherTransitionAnimator {
private final MutableBoolean mLauncherAnimCancelState;
private AnimatorSet mAnimatorSet;
private Animator mLauncherAnimator;
private Animator mWindowAnimator;
LauncherTransitionAnimator(Animator launcherAnimator, Animator windowAnimator) {
this(launcherAnimator, windowAnimator, new MutableBoolean(false));
}
LauncherTransitionAnimator(Animator launcherAnimator, Animator windowAnimator,
MutableBoolean launcherAnimCancelState) {
mLauncherAnimCancelState = launcherAnimCancelState;
if (launcherAnimator != null) {
mLauncherAnimator = launcherAnimator;
}
mWindowAnimator = windowAnimator;
mAnimatorSet = new AnimatorSet();
if (launcherAnimator != null) {
mAnimatorSet.play(launcherAnimator);
}
mAnimatorSet.play(windowAnimator);
}
public AnimatorSet getAnimatorSet() {
return mAnimatorSet;
}
public void cancel() {
mAnimatorSet.cancel();
mLauncherAnimCancelState.value = true;
}
public boolean isRunning() {
return mAnimatorSet.isRunning();
}
public void finishLauncherAnimation() {
if (mLauncherAnimator != null) {
mLauncherAnimCancelState.value = true;
mLauncherAnimator.end();
}
}
}
@@ -1,25 +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.launcher3;
public class MutableBoolean {
public boolean value;
public MutableBoolean(boolean value) {
this.value = value;
}
}
@@ -24,7 +24,6 @@ import android.view.View;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -33,8 +32,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
*/
public class AllAppsState extends LauncherState {
private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY
| FLAG_SHOW_SCRIM | FLAG_ALL_APPS_SCRIM;
private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY | FLAG_ALL_APPS_SCRIM;
private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
@Override
@@ -85,8 +83,15 @@ public class AllAppsState extends LauncherState {
}
@Override
public float getHoseatAlpha(Launcher launcher) {
return 0;
public int getVisibleElements(Launcher launcher) {
return ALL_APPS_HEADER | ALL_APPS_HEADER_EXTRA | ALL_APPS_CONTENT;
}
@Override
public float[] getOverviewTranslationFactor(Launcher launcher) {
// Keep the same translation as in overview, so that we don't slide around when
// transitioning to All Apps.
return LauncherState.OVERVIEW.getOverviewTranslationFactor(launcher);
}
@Override
@@ -1,92 +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.uioverrides;
import com.android.launcher3.Alarm;
import com.android.launcher3.OnAlarmListener;
/**
* Utility class to detect a pause during a drag.
*/
public class DragPauseDetector implements OnAlarmListener {
private static final float MAX_VELOCITY_TO_PAUSE = 0.2f;
private static final long PAUSE_DURATION = 100;
private final Alarm mAlarm;
private final Runnable mOnPauseCallback;
private boolean mTriggered = false;
private int mDisabledFlags = 0;
public DragPauseDetector(Runnable onPauseCallback) {
mOnPauseCallback = onPauseCallback;
mAlarm = new Alarm();
mAlarm.setOnAlarmListener(this);
mAlarm.setAlarm(PAUSE_DURATION);
}
public void onDrag(float velocity) {
if (mTriggered || !isEnabled()) {
return;
}
if (Math.abs(velocity) > MAX_VELOCITY_TO_PAUSE) {
// Cancel any previous alarm and set a new alarm
mAlarm.setAlarm(PAUSE_DURATION);
}
}
@Override
public void onAlarm(Alarm alarm) {
if (!mTriggered && isEnabled()) {
mTriggered = true;
mOnPauseCallback.run();
}
}
public boolean isTriggered () {
return mTriggered;
}
public boolean isEnabled() {
return mDisabledFlags == 0;
}
public void addDisabledFlags(int flags) {
boolean wasEnabled = isEnabled();
mDisabledFlags |= flags;
resetAlarm(wasEnabled);
}
public void clearDisabledFlags(int flags) {
boolean wasEnabled = isEnabled();
mDisabledFlags &= ~flags;
resetAlarm(wasEnabled);
}
private void resetAlarm(boolean wasEnabled) {
boolean isEnabled = isEnabled();
if (wasEnabled == isEnabled) {
// Nothing has changed
} if (isEnabled && !mTriggered) {
mAlarm.setAlarm(PAUSE_DURATION);
} else if (!isEnabled) {
mAlarm.cancelAlarm();
}
}
}
@@ -1,165 +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.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.touch.SwipeDetector.DIRECTION_NEGATIVE;
import static com.android.launcher3.touch.SwipeDetector.DIRECTION_POSITIVE;
import static com.android.launcher3.touch.SwipeDetector.HORIZONTAL;
import static com.android.launcher3.touch.SwipeDetector.VERTICAL;
import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
import android.graphics.Rect;
import android.metrics.LogMaker;
import android.view.MotionEvent;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.VerticalSwipeController;
import com.android.quickstep.views.RecentsView;
class EventLogTags {
private EventLogTags() {
} // don't instantiate
/** 524292 sysui_multi_action (content|4) */
public static final int SYSUI_MULTI_ACTION = 524292;
public static void writeSysuiMultiAction(Object[] content) {
android.util.EventLog.writeEvent(SYSUI_MULTI_ACTION, content);
}
}
class MetricsLogger {
private static MetricsLogger sMetricsLogger;
private static MetricsLogger getLogger() {
if (sMetricsLogger == null) {
sMetricsLogger = new MetricsLogger();
}
return sMetricsLogger;
}
protected void saveLog(Object[] rep) {
EventLogTags.writeSysuiMultiAction(rep);
}
public void write(LogMaker content) {
if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
content.setType(4/*MetricsEvent.TYPE_ACTION*/);
}
saveLog(content.serialize());
}
}
/**
* Extension of {@link VerticalSwipeController} to go from NORMAL to OVERVIEW.
*/
public class EdgeSwipeController extends VerticalSwipeController implements
OnDeviceProfileChangeListener {
private static final Rect sTempRect = new Rect();
private final MetricsLogger mMetricsLogger = new MetricsLogger();
public EdgeSwipeController(Launcher l) {
super(l, NORMAL, OVERVIEW, l.getDeviceProfile().isVerticalBarLayout()
? HORIZONTAL : VERTICAL);
l.addOnDeviceProfileChangeListener(this);
}
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
mDetector.updateDirection(dp.isVerticalBarLayout() ? HORIZONTAL : VERTICAL);
}
@Override
protected boolean shouldInterceptTouch(MotionEvent ev) {
return mLauncher.isInState(NORMAL) && (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
}
@Override
protected int getSwipeDirection(MotionEvent ev) {
return isTransitionFlipped() ? DIRECTION_NEGATIVE : DIRECTION_POSITIVE;
}
public EdgeSwipeController(Launcher l, LauncherState baseState) {
super(l, baseState);
}
@Override
protected boolean isTransitionFlipped() {
return mLauncher.getDeviceProfile().isSeascape();
}
@Override
protected void onTransitionComplete(boolean wasFling, boolean stateChanged) {
if (stateChanged && mToState instanceof OverviewState) {
// Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
// "Recents" activity for app transition tests.
final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
builder.setPackageName("com.android.systemui");
builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
"com.android.systemui.recents.RecentsActivity");
builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
0/* zero time */);
mMetricsLogger.write(builder);
// Add user event logging for launcher pipeline
int direction = Direction.UP;
if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
direction = Direction.LEFT;
if (mLauncher.getDeviceProfile().isSeascape()) {
direction = Direction.RIGHT;
}
}
mLauncher.getUserEventDispatcher().logStateChangeAction(
wasFling ? Touch.FLING : Touch.SWIPE, direction,
ContainerType.NAVBAR, ContainerType.WORKSPACE, // src target
ContainerType.TASKSWITCHER, // dst target
mLauncher.getWorkspace().getCurrentPage());
}
}
@Override
protected float getShiftRange() {
return getShiftRange(mLauncher);
}
public static float getShiftRange(Launcher launcher) {
RecentsView.getPageRect(launcher.getDeviceProfile(), launcher, sTempRect);
DragLayer dl = launcher.getDragLayer();
Rect insets = dl.getInsets();
DeviceProfile dp = launcher.getDeviceProfile();
if (dp.isVerticalBarLayout()) {
if (dp.isSeascape()) {
return insets.left + sTempRect.left;
} else {
return dl.getWidth() - sTempRect.right + insets.right;
}
} else {
return dl.getHeight() - sTempRect.bottom + insets.bottom;
}
}
}
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.uioverrides;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.quickstep.QuickScrubController;
import com.android.quickstep.views.RecentsView;
@@ -25,12 +26,10 @@ import com.android.quickstep.views.RecentsView;
public class FastOverviewState extends OverviewState {
private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_DISABLE_RESTORE
| FLAG_DISABLE_INTERACTION | FLAG_OVERVIEW_UI;
private static final boolean DEBUG_DIFFERENT_UI = false;
| FLAG_DISABLE_INTERACTION | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON;
public FastOverviewState(int id) {
super(id, QuickScrubController.QUICK_SWITCH_START_DURATION, STATE_FLAGS);
super(id, QuickScrubController.QUICK_SCRUB_START_DURATION, STATE_FLAGS);
}
@Override
@@ -40,11 +39,18 @@ public class FastOverviewState extends OverviewState {
recentsView.getQuickScrubController().onFinishedTransitionToQuickScrub();
}
public void onStateEnabled(Launcher launcher) {
super.onStateEnabled(launcher);
AbstractFloatingView.closeAllOpenViews(launcher);
}
@Override
public float getHoseatAlpha(Launcher launcher) {
if (DEBUG_DIFFERENT_UI) {
return 0;
}
return super.getHoseatAlpha(launcher);
public int getVisibleElements(Launcher launcher) {
return NONE;
}
@Override
public float[] getOverviewTranslationFactor(Launcher launcher) {
return new float[] {0f, 0.5f};
}
}
@@ -0,0 +1,71 @@
package com.android.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.quickstep.util.SysuiEventLogger;
/**
* Touch controller for handling edge swipes in landscape/seascape UI
*/
public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchController {
public LandscapeEdgeSwipeController(Launcher l) {
super(l, SwipeDetector.HORIZONTAL);
}
@Override
protected boolean canInterceptTouch(MotionEvent ev) {
if (mCurrentAnimation != null) {
// If we are already animating from a previous state, we can intercept.
return true;
}
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
return false;
}
return mLauncher.isInState(NORMAL) && (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
}
@Override
protected int getSwipeDirection(MotionEvent ev) {
mFromState = NORMAL;
mToState = OVERVIEW;
return SwipeDetector.DIRECTION_BOTH;
}
@Override
protected float getShiftRange() {
return mLauncher.getDragLayer().getWidth();
}
@Override
protected float initCurrentAnimation() {
float range = getShiftRange();
long maxAccuracy = (long) (2 * range);
mCurrentAnimation = mLauncher.getStateManager()
.createAnimationToNewWorkspace(mToState, maxAccuracy);
return (mLauncher.getDeviceProfile().isSeascape() ? 2 : -2) / range;
}
@Override
protected int getDirectionForLog() {
return mLauncher.getDeviceProfile().isSeascape() ? Direction.RIGHT : Direction.LEFT;
}
@Override
protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
super.onSwipeInteractionCompleted(targetState, logAction);
if (mFromState == NORMAL && targetState == OVERVIEW) {
SysuiEventLogger.writeDummyRecentsTransition(0);
}
}
}
@@ -0,0 +1,70 @@
/*
* 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.uioverrides;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.views.RecentsView;
/**
* Touch controller from going from OVERVIEW to ALL_APPS
*/
public class LandscapeStatesTouchController extends PortraitStatesTouchController {
public LandscapeStatesTouchController(Launcher l) {
super(l);
}
@Override
protected boolean canInterceptTouch(MotionEvent ev) {
if (mCurrentAnimation != null) {
// If we are already animating from a previous state, we can intercept.
return true;
}
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
return false;
}
if (mLauncher.isInState(ALL_APPS)) {
// In all-apps only listen if the container cannot scroll itself
return mLauncher.getAppsView().shouldContainerScroll(ev);
} else if (mLauncher.isInState(NORMAL)) {
return true;
} else if (mLauncher.isInState(OVERVIEW)) {
RecentsView rv = mLauncher.getOverviewPanel();
return ev.getY() > (rv.getBottom() - rv.getPaddingBottom());
} else {
return false;
}
}
protected LauncherState getTargetState() {
if (mLauncher.isInState(ALL_APPS)) {
// Should swipe down go to OVERVIEW instead?
return TouchInteractionService.isConnected() ?
mLauncher.getStateManager().getLastState() : NORMAL;
} else {
return ALL_APPS;
}
}
}
@@ -22,6 +22,7 @@ import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
import android.graphics.Rect;
import android.view.View;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
@@ -56,6 +57,11 @@ public class OverviewState extends LauncherState {
return getScaleAndTranslationForPageRect(launcher, pageRect);
}
@Override
public float[] getOverviewTranslationFactor(Launcher launcher) {
return new float[] {0f, 0f};
}
@Override
public void onStateEnabled(Launcher launcher) {
RecentsView rv = launcher.getOverviewPanel();
@@ -100,4 +106,29 @@ public class OverviewState extends LauncherState {
return new float[] {scale, 0, translationY};
}
@Override
public int getVisibleElements(Launcher launcher) {
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
return NONE;
} else {
return launcher.getAppsView().getFloatingHeaderView().hasVisibleContent()
? HOTSEAT_EXTRA | ALL_APPS_HEADER_EXTRA : HOTSEAT_ICONS | HOTSEAT_EXTRA;
}
}
@Override
public float getVerticalProgress(Launcher launcher) {
if ((getVisibleElements(launcher) & ALL_APPS_HEADER_EXTRA) == 0) {
// We have no all apps content, so we're still at the fully down progress.
return super.getVerticalProgress(launcher);
}
return 1 - (getDefaultSwipeHeight(launcher)
/ launcher.getAllAppsController().getShiftRange());
}
public static float getDefaultSwipeHeight(Launcher launcher) {
DeviceProfile dp = launcher.getDeviceProfile();
return dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
}
}
@@ -1,71 +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.uioverrides;
import static com.android.launcher3.LauncherState.OVERVIEW;
import android.view.MotionEvent;
import com.android.launcher3.Launcher;
import com.android.launcher3.touch.SwipeDetector;
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;
import com.android.launcher3.util.VerticalSwipeController;
/**
* Extension of {@link VerticalSwipeController} which allows swipe up from OVERVIEW to ALL_APPS
* Note that the swipe down is handled by {@link TwoStepSwipeController}.
*/
public class OverviewSwipeUpController extends VerticalSwipeController {
public OverviewSwipeUpController(Launcher l) {
super(l, OVERVIEW);
}
@Override
protected boolean shouldInterceptTouch(MotionEvent ev) {
if (!mLauncher.isInState(OVERVIEW)) {
return false;
}
if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
return ev.getY() >
mLauncher.getDragLayer().getHeight() * OVERVIEW.getVerticalProgress(mLauncher);
} else {
return mLauncher.getDragLayer().isEventOverHotseat(ev);
}
}
@Override
protected int getSwipeDirection(MotionEvent ev) {
return SwipeDetector.DIRECTION_POSITIVE;
}
@Override
protected void onTransitionComplete(boolean wasFling, boolean stateChanged) {
if (stateChanged) {
// Transition complete. log the action
mLauncher.getUserEventDispatcher().logStateChangeAction(
wasFling ? Touch.FLING : Touch.SWIPE,
Direction.UP,
ContainerType.HOTSEAT,
ContainerType.TASKSWITCHER,
ContainerType.ALLAPPS,
mLauncher.getWorkspace().getCurrentPage());
}
}
}
@@ -0,0 +1,291 @@
/*
* 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.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATION;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.SysuiEventLogger;
/**
* Touch controller for handling various state transitions in portrait UI.
*/
public class PortraitStatesTouchController extends AbstractStateChangeTouchController {
private static final float TOTAL_DISTANCE_MULTIPLIER = 2f;
private static final float LINEAR_SCALE_LIMIT = 1 / TOTAL_DISTANCE_MULTIPLIER;
// Much be greater than LINEAR_SCALE_LIMIT;
private static final float MAXIMUM_DISTANCE_FACTOR = 0.9f;
// Maximum amount to overshoot.
private static final float MAX_OVERSHOOT = 0.3f;
private static final double PI_BY_2 = Math.PI / 2;
private InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper();
// If > 0, the animation progress is clamped at that value as long as user is dragging.
private float mClampProgressUpdate = -1;
// If true, we will finish the current animation instantly on second touch.
private boolean mFinishFastOnSecondTouch;
private final Interpolator mAllAppsDampedInterpolator = new Interpolator() {
private final double mAngleMultiplier = Math.PI /
(2 * (MAXIMUM_DISTANCE_FACTOR - LINEAR_SCALE_LIMIT));
@Override
public float getInterpolation(float v) {
if (v <= LINEAR_SCALE_LIMIT) {
return v * TOTAL_DISTANCE_MULTIPLIER;
}
float overshoot = (v - LINEAR_SCALE_LIMIT);
return (float) (1 + MAX_OVERSHOOT * Math.sin(overshoot * mAngleMultiplier));
}
};
private final Interpolator mOverviewBoundInterpolator = (v) -> {
if (v >= MAXIMUM_DISTANCE_FACTOR) {
return 1;
}
return FAST_OUT_SLOW_IN.getInterpolation(v / MAXIMUM_DISTANCE_FACTOR);
};
public PortraitStatesTouchController(Launcher l) {
super(l, SwipeDetector.VERTICAL);
}
@Override
protected boolean canInterceptTouch(MotionEvent ev) {
if (mCurrentAnimation != null) {
if (mFinishFastOnSecondTouch) {
// TODO: Animate to finish instead.
mCurrentAnimation.getAnimationPlayer().end();
}
// If we are already animating from a previous state, we can intercept.
return true;
}
if (mLauncher.isInState(ALL_APPS)) {
// In all-apps only listen if the container cannot scroll itself
if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
return false;
}
} else {
// For all other states, only listen if the event originated below the hotseat height
DeviceProfile dp = mLauncher.getDeviceProfile();
int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
if (ev.getY() < (mLauncher.getDragLayer().getHeight() - hotseatHeight)) {
return false;
}
}
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
return false;
}
return true;
}
@Override
protected int getSwipeDirection(MotionEvent ev) {
final int directionsToDetectScroll;
if (mLauncher.isInState(ALL_APPS)) {
directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
mStartContainerType = ContainerType.ALLAPPS;
} else if (mLauncher.isInState(NORMAL)) {
directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
mStartContainerType = ContainerType.HOTSEAT;
} else if (mLauncher.isInState(OVERVIEW)) {
directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
mStartContainerType = ContainerType.TASKSWITCHER;
} else {
return 0;
}
mFromState = mLauncher.getStateManager().getState();
mToState = getTargetState();
if (mFromState == mToState) {
return 0;
}
return directionsToDetectScroll;
}
protected LauncherState getTargetState() {
if (mLauncher.isInState(ALL_APPS)) {
// Should swipe down go to OVERVIEW instead?
return TouchInteractionService.isConnected() ?
mLauncher.getStateManager().getLastState() : NORMAL;
} else if (mLauncher.isInState(OVERVIEW)) {
return ALL_APPS;
} else {
return TouchInteractionService.isConnected() ? OVERVIEW : ALL_APPS;
}
}
private AnimatorSetBuilder getNormalToOverviewAnimation() {
mAllAppsInterpolatorWrapper.baseInterpolator = mAllAppsDampedInterpolator;
AnimatorSetBuilder builder = new AnimatorSetBuilder();
builder.setInterpolator(ANIM_VERTICAL_PROGRESS, mAllAppsInterpolatorWrapper);
builder.setInterpolator(ANIM_OVERVIEW_TRANSLATION, mOverviewBoundInterpolator);
return builder;
}
@Override
protected void updateProgress(float fraction) {
if (mClampProgressUpdate > 0) {
mCurrentAnimation.setPlayFraction(Math.min(fraction, mClampProgressUpdate));
} else {
super.updateProgress(fraction);
}
}
@Override
protected float initCurrentAnimation() {
float range = getShiftRange();
long maxAccuracy = (long) (2 * range);
float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
float totalShift = endVerticalShift - startVerticalShift;
final AnimatorSetBuilder builder;
if (mFromState == NORMAL && mToState == OVERVIEW && totalShift != 0) {
builder = getNormalToOverviewAnimation();
totalShift = totalShift * TOTAL_DISTANCE_MULTIPLIER;
mClampProgressUpdate = MAXIMUM_DISTANCE_FACTOR;
} else {
builder = new AnimatorSetBuilder();
mClampProgressUpdate = -1;
}
mCurrentAnimation = mLauncher.getStateManager()
.createAnimationToNewWorkspace(mToState, builder, maxAccuracy);
if (totalShift == 0) {
totalShift = Math.signum(mFromState.ordinal - mToState.ordinal)
* OverviewState.getDefaultSwipeHeight(mLauncher);
}
return 1 / totalShift;
}
@Override
protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
LauncherState targetState, float velocity, boolean isFling) {
if (mFromState == NORMAL && mToState == OVERVIEW && targetState == OVERVIEW) {
mFinishFastOnSecondTouch = true;
// Update all apps interpolator
float currentFraction = mCurrentAnimation.getProgressFraction();
float absVelocity = Math.abs(velocity);
float currentValue = mAllAppsDampedInterpolator.getInterpolation(currentFraction);
if (isFling && absVelocity > 1 && currentFraction < LINEAR_SCALE_LIMIT) {
// TODO: Clean up these magic calculations
// Linearly interpolate the max value based on the velocity.
float maxValue = Math.max(absVelocity > 4 ? 1 + MAX_OVERSHOOT :
1 + (absVelocity - 1) * MAX_OVERSHOOT / 3,
currentValue);
double angleToPeak = PI_BY_2 - Math.asin(currentValue / maxValue);
if (expectedDuration != 0 && angleToPeak != 0) {
float distanceLeft = 1 - currentFraction;
mAllAppsInterpolatorWrapper.baseInterpolator = (f) -> {
float scaledF = (f - currentFraction) / distanceLeft;
if (scaledF < 0.5f) {
double angle = PI_BY_2 - angleToPeak + scaledF * angleToPeak / 0.5f;
return (float) (maxValue * Math.sin(angle));
}
scaledF = ((scaledF - .5f) / .5f);
double angle = PI_BY_2 + 3 * scaledF * PI_BY_2;
float amplitude = (1 - scaledF) * (1 - scaledF) * (maxValue - 1);
return 1 + (float) (amplitude * Math.sin(angle));
};
animator.setDuration(expectedDuration).setInterpolator(LINEAR);
return;
}
}
if (currentFraction < LINEAR_SCALE_LIMIT) {
mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR;
super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState,
velocity, isFling);
return;
}
float extraValue = mAllAppsDampedInterpolator.getInterpolation(currentFraction) - 1;
float distanceLeft = 1 - currentFraction;
animator.setFloatValues(currentFraction, 1);
mAllAppsInterpolatorWrapper.baseInterpolator = (f) -> {
float scaledF = (f - currentFraction) / distanceLeft;
double angle = scaledF * 1.5 * Math.PI;
float amplitude = (1 - scaledF) * (1 - scaledF) * extraValue;
return 1 + (float) (amplitude * Math.sin(angle));
};
animator.setDuration(200).setInterpolator(LINEAR);
return;
}
mFinishFastOnSecondTouch = false;
super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState,
velocity, isFling);
}
@Override
protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
super.onSwipeInteractionCompleted(targetState, logAction);
if (mFromState == NORMAL && targetState == OVERVIEW) {
SysuiEventLogger.writeDummyRecentsTransition(0);
}
}
private static class InterpolatorWrapper implements Interpolator {
public TimeInterpolator baseInterpolator = LINEAR;
@Override
public float getInterpolation(float v) {
return baseInterpolator.getInterpolation(v);
}
}
}
@@ -16,36 +16,32 @@
package com.android.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.AlphaUpdateListener.updateVisibility;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATION;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_X_FACTOR;
import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.view.View;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.os.Build;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.AnimationConfig;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.PagedView;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.Interpolators;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.launcher3.anim.PropertySetter;
import com.android.quickstep.views.LauncherRecentsView;
@TargetApi(Build.VERSION_CODES.O)
public class RecentsViewStateController implements StateHandler {
private final Launcher mLauncher;
private final RecentsView mRecentsView;
private final AnimatedFloat mTransitionProgress = new AnimatedFloat(this::onTransitionProgress);
// The fraction representing the visibility of the RecentsView. This allows delaying the
// overall transition while the RecentsView is being shown or hidden.
private final AnimatedFloat mVisibilityMultiplier = new AnimatedFloat(this::onVisibilityProgress);
private boolean mIsRecentsSlidingInOrOut;
private final LauncherRecentsView mRecentsView;
public RecentsViewStateController(Launcher launcher) {
mLauncher = launcher;
@@ -54,8 +50,11 @@ public class RecentsViewStateController implements StateHandler {
@Override
public void setState(LauncherState state) {
setVisibility(state.overviewUi);
setTransitionProgress(state.overviewUi ? 1 : 0);
mRecentsView.setContentAlpha(state.overviewUi ? 1 : 0);
updateVisibility(mRecentsView, isAccessibilityEnabled(mLauncher));
float[] translationFactor = state.getOverviewTranslationFactor(mLauncher);
mRecentsView.setTranslationXFactor(translationFactor[0]);
mRecentsView.setTranslationYFactor(translationFactor[1]);
if (state.overviewUi) {
mRecentsView.resetTaskVisuals();
}
@@ -64,11 +63,9 @@ public class RecentsViewStateController implements StateHandler {
@Override
public void setStateWithAnimation(final LauncherState toState,
AnimatorSetBuilder builder, AnimationConfig config) {
LauncherState fromState = mLauncher.getStateManager().getState();
mIsRecentsSlidingInOrOut = fromState == NORMAL && toState.overviewUi
|| fromState.overviewUi && toState == NORMAL;
// Scroll to the workspace card before changing to the NORMAL state.
LauncherState fromState = mLauncher.getStateManager().getState();
int currPage = mRecentsView.getCurrentPage();
if (fromState.overviewUi && toState == NORMAL && currPage != 0 && !config.userControlled) {
int maxSnapDuration = PagedView.SLOW_PAGE_SNAP_ANIMATION_DURATION;
@@ -79,78 +76,24 @@ public class RecentsViewStateController implements StateHandler {
builder.setStartDelay(snapDuration / 4);
}
ObjectAnimator progressAnim =
mTransitionProgress.animateToValue(toState.overviewUi ? 1 : 0);
progressAnim.setDuration(config.duration);
progressAnim.setInterpolator(Interpolators.LINEAR);
progressAnim.addListener(new AnimationSuccessListener() {
PropertySetter setter = config.getProperSetter(builder);
float[] translationFactor = toState.getOverviewTranslationFactor(mLauncher);
setter.setFloat(mRecentsView, TRANSLATION_X_FACTOR,
translationFactor[0],
builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR,
translationFactor[1],
builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
setter.setFloat(mRecentsView, CONTENT_ALPHA, toState.overviewUi ? 1 : 0, LINEAR);
@Override
public void onAnimationSuccess(Animator animator) {
mRecentsView.setCurrentPage(mRecentsView.getPageNearestToCenterOfScreen());
}
});
builder.play(progressAnim);
ObjectAnimator visibilityAnim = animateVisibility(toState.overviewUi);
visibilityAnim.setDuration(config.duration);
visibilityAnim.setInterpolator(Interpolators.LINEAR);
builder.play(visibilityAnim);
}
public void setVisibility(boolean isVisible) {
mVisibilityMultiplier.cancelAnimation();
mRecentsView.setVisibility(isVisible ? View.VISIBLE : View.GONE);
mVisibilityMultiplier.updateValue(isVisible ? 1 : 0);
}
public ObjectAnimator animateVisibility(boolean isVisible) {
ObjectAnimator anim = mVisibilityMultiplier.animateToValue(isVisible ? 1 : 0);
if (isVisible) {
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mRecentsView.setVisibility(View.VISIBLE);
}
if (toState.overviewUi) {
ValueAnimator updateAnim = ValueAnimator.ofFloat(0, 1);
updateAnim.addUpdateListener(valueAnimator -> {
// While animating into recents, update the visible task data as needed
mRecentsView.loadVisibleTaskData();
});
} else {
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
mRecentsView.setVisibility(View.GONE);
}
});
}
return anim;
}
public void setTransitionProgress(float progress) {
mTransitionProgress.cancelAnimation();
mTransitionProgress.updateValue(progress);
}
private void onTransitionProgress() {
applyProgress();
if (mIsRecentsSlidingInOrOut) {
float interpolatedProgress = ACCEL.getInterpolation(mTransitionProgress.value);
// Slide in from the side as we swipe.
int translation = mRecentsView.getWidth();
if (mRecentsView.isRtl()) {
translation = -translation;
}
mRecentsView.setTranslationX(translation * (1 - interpolatedProgress));
}
}
private void onVisibilityProgress() {
applyProgress();
}
private void applyProgress() {
mRecentsView.setAlpha(mTransitionProgress.value * mVisibilityMultiplier.value);
if (mIsRecentsSlidingInOrOut) {
// While animating into recents, update the visible task data as needed
mRecentsView.loadVisibleTaskData();
updateAnim.setDuration(config.duration);
builder.play(updateAnim);
}
}
}
@@ -1,51 +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.uioverrides;
import android.animation.Animator;
import android.util.SparseArray;
import com.android.launcher3.anim.AnimatorSetBuilder;
import java.util.Collections;
import java.util.List;
public class TaggedAnimatorSetBuilder extends AnimatorSetBuilder {
/**
* Map of the index in {@link #mAnims} to tag. All the animations in {@link #mAnims} starting
* from this index correspond to the tag (until a new tag is specified for an index)
*/
private final SparseArray<Object> mTags = new SparseArray<>();
@Override
public void startTag(Object obj) {
mTags.put(mAnims.size(), obj);
}
public List<Animator> getAnimationsForTag(Object tag) {
int startIndex = mTags.indexOfValue(tag);
if (startIndex < 0) {
return Collections.emptyList();
}
int startPos = mTags.keyAt(startIndex);
int endIndex = startIndex + 1;
int endPos = endIndex >= mTags.size() ? mAnims.size() : mTags.keyAt(endIndex);
return mAnims.subList(startPos, endPos);
}
}
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
@@ -30,24 +28,21 @@ import android.view.View;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.touch.SwipeDetector;
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;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.PendingAnimation;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
/**
* Touch controller for swipe interaction in Overview state
* Touch controller for handling task view card swipes
*/
public class OverviewSwipeController extends AnimatorListenerAdapter
public class TaskViewTouchController extends AnimatorListenerAdapter
implements TouchController, SwipeDetector.Listener {
private static final String TAG = "OverviewSwipeController";
@@ -68,16 +63,14 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
private boolean mCurrentAnimationIsGoingUp;
private boolean mNoIntercept;
private boolean mSwipeDownEnabled;
private float mDisplacementShift;
private float mProgressMultiplier;
private float mEndDisplacement;
private int mStartingTarget;
private TaskView mTaskBeingDragged;
public OverviewSwipeController(Launcher launcher) {
public TaskViewTouchController(Launcher launcher) {
mLauncher = launcher;
mRecentsView = launcher.getOverviewPanel();
mDetector = new SwipeDetector(launcher, this, SwipeDetector.VERTICAL);
@@ -94,15 +87,6 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
return mLauncher.isInState(OVERVIEW);
}
private boolean isEventOverHotseat(MotionEvent ev) {
if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
return ev.getY() >
mLauncher.getDragLayer().getHeight() * OVERVIEW.getVerticalProgress(mLauncher);
} else {
return mLauncher.getDragLayer().isEventOverHotseat(ev);
}
}
@Override
public void onAnimationCancel(Animator animation) {
if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) {
@@ -129,22 +113,14 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
ignoreSlopWhenSettling = true;
} else {
mTaskBeingDragged = null;
mSwipeDownEnabled = true;
View view = mRecentsView.getChildAt(mRecentsView.getCurrentPage());
if (view instanceof TaskView && mLauncher.getDragLayer().isEventOverView(view, ev)) {
// The tile can be dragged down to open the task.
mTaskBeingDragged = (TaskView) view;
directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
mStartingTarget = LauncherLogProto.ItemType.TASK;
} else if (isEventOverHotseat(ev)) {
// The hotseat is being dragged
directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
mSwipeDownEnabled = false;
mStartingTarget = ContainerType.HOTSEAT;
} else {
mNoIntercept = true;
mStartingTarget = ContainerType.WORKSPACE;
return false;
}
}
@@ -167,9 +143,6 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
}
private void reInitAnimationController(boolean goingUp) {
if (!goingUp && !mSwipeDownEnabled) {
goingUp = true;
}
if (mCurrentAnimation != null && mCurrentAnimationIsGoingUp == goingUp) {
// No need to init
return;
@@ -187,31 +160,20 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
long maxDuration = (long) (2 * range);
DragLayer dl = mLauncher.getDragLayer();
if (mTaskBeingDragged == null) {
// User is either going to all apps or home
mCurrentAnimation = mLauncher.getStateManager()
.createAnimationToNewWorkspace(goingUp ? ALL_APPS : NORMAL, maxDuration);
if (goingUp) {
mEndDisplacement = -range;
} else {
mEndDisplacement = EdgeSwipeController.getShiftRange(mLauncher);
}
if (goingUp) {
mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
true /* animateTaskView */, true /* removeTask */, maxDuration);
mCurrentAnimation = AnimatorPlaybackController
.wrap(mPendingAnimation.anim, maxDuration);
mEndDisplacement = -mTaskBeingDragged.getHeight();
} else {
if (goingUp) {
mPendingAnimation = mRecentsView
.createTaskDismissAnimation(mTaskBeingDragged, maxDuration);
mCurrentAnimation = AnimatorPlaybackController
.wrap(mPendingAnimation.anim, maxDuration);
mEndDisplacement = -mTaskBeingDragged.getHeight();
} else {
AnimatorSet anim = new AnimatorSet();
// TODO: Setup a zoom animation
mCurrentAnimation = AnimatorPlaybackController.wrap(anim, maxDuration);
AnimatorSet anim = new AnimatorSet();
// TODO: Setup a zoom animation
mCurrentAnimation = AnimatorPlaybackController.wrap(anim, maxDuration);
mTempCords[1] = mTaskBeingDragged.getHeight();
dl.getDescendantCoordRelativeToSelf(mTaskBeingDragged, mTempCords);
mEndDisplacement = dl.getHeight() - mTempCords[1];
}
mTempCords[1] = mTaskBeingDragged.getHeight();
dl.getDescendantCoordRelativeToSelf(mTaskBeingDragged, mTempCords);
mEndDisplacement = dl.getHeight() - mTempCords[1];
}
mCurrentAnimation.getTarget().addListener(this);
@@ -249,9 +211,7 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
if (fling) {
logAction = Touch.FLING;
boolean goingUp = velocity < 0;
if (!goingUp && !mSwipeDownEnabled) {
goingToEnd = false;
} else if (goingUp != mCurrentAnimationIsGoingUp) {
if (goingUp != mCurrentAnimationIsGoingUp) {
// In case the fling is in opposite direction, make sure if is close enough
// from the start position
if (mCurrentAnimation.getProgressFraction()
@@ -277,7 +237,6 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
float nextFrameProgress = Utilities.boundToRange(
progress + velocity * SINGLE_FRAME_MS / Math.abs(mEndDisplacement), 0f, 1f);
mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd, logAction));
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
@@ -292,25 +251,13 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
mPendingAnimation.finish(wasSuccess);
mPendingAnimation = null;
}
if (mTaskBeingDragged == null) {
LauncherState state = wasSuccess ?
(mCurrentAnimationIsGoingUp ? ALL_APPS : NORMAL) : OVERVIEW;
mLauncher.getStateManager().goToState(state, false);
} else if (wasSuccess) {
if (wasSuccess) {
if (!mCurrentAnimationIsGoingUp) {
mTaskBeingDragged.launchTask(false);
mLauncher.getUserEventDispatcher().logTaskLaunch(logAction,
Direction.DOWN, mTaskBeingDragged.getTask().getTopComponent());
}
}
if (mTaskBeingDragged == null || (wasSuccess && mCurrentAnimationIsGoingUp)) {
mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
mCurrentAnimationIsGoingUp ? Direction.UP : Direction.DOWN,
mStartingTarget, ContainerType.TASKSWITCHER,
mLauncher.getStateManager().getState().containerType,
mRecentsView.getCurrentPage());
}
mDetector.finishedScrolling();
mTaskBeingDragged = null;
mCurrentAnimation = null;
@@ -1,447 +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.uioverrides;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.util.Log;
import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.LauncherStateManager.AnimationConfig;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.touch.SwipeDetector;
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;
import com.android.launcher3.util.FloatRange;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.TouchInteractionService;
/**
* Handles vertical touch gesture on the DragLayer
*/
public class TwoStepSwipeController extends AnimatorListenerAdapter
implements TouchController, SwipeDetector.Listener {
private static final String TAG = "TwoStepSwipeController";
private static final float RECATCH_REJECTION_FRACTION = .0875f;
private static final int SINGLE_FRAME_MS = 16;
private static final long QUICK_SNAP_TO_OVERVIEW_DURATION = 250;
// Progress after which the transition is assumed to be a success in case user does not fling
private static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
/**
* Index of the vertical swipe handles in {@link LauncherStateManager#getStateHandlers()}.
*/
private static final int SWIPE_HANDLER_INDEX = 0;
/**
* Index of various UI handlers in {@link LauncherStateManager#getStateHandlers()} not related
* to vertical swipe.
*/
private static final int OTHER_HANDLERS_START_INDEX = SWIPE_HANDLER_INDEX + 1;
// Swipe progress range (when starting from NORMAL state) where OVERVIEW state is allowed
private static final float MIN_PROGRESS_TO_OVERVIEW = 0.1f;
private static final float MAX_PROGRESS_TO_OVERVIEW = 0.4f;
private static final int FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE = 1 << 0;
private static final int FLAG_OVERVIEW_DISABLED_FLING = 1 << 1;
private static final int FLAG_OVERVIEW_DISABLED_CANCEL_STATE = 1 << 2;
private static final int FLAG_OVERVIEW_DISABLED = 1 << 4;
private static final int FLAG_DISABLED_TWO_TARGETS = 1 << 5;
private static final int FLAG_DISABLED_BACK_TARGET = 1 << 6;
private final Launcher mLauncher;
private final SwipeDetector mDetector;
private boolean mNoIntercept;
private int mStartContainerType;
private DragPauseDetector mDragPauseDetector;
private FloatRange mOverviewProgressRange;
private TaggedAnimatorSetBuilder mTaggedAnimatorSetBuilder;
private AnimatorSet mQuickOverviewAnimation;
private boolean mAnimatingToOverview;
private CroppedAnimationController mCroppedAnimationController;
private AnimatorPlaybackController mCurrentAnimation;
private LauncherState mFromState;
private LauncherState mToState;
private float mStartProgress;
// Ratio of transition process [0, 1] to drag displacement (px)
private float mProgressMultiplier;
public TwoStepSwipeController(Launcher l) {
mLauncher = l;
mDetector = new SwipeDetector(l, this, SwipeDetector.VERTICAL);
}
private boolean canInterceptTouch(MotionEvent ev) {
if (mCurrentAnimation != null) {
// If we are already animating from a previous state, we can intercept.
return true;
}
if (mLauncher.isInState(NORMAL)) {
if ((ev.getEdgeFlags() & EDGE_NAV_BAR) != 0 &&
!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
// On normal swipes ignore edge swipes
return false;
}
} else if (mLauncher.isInState(ALL_APPS)) {
if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
return false;
}
} else {
// Don't listen for the swipe gesture if we are already in some other state.
return false;
}
if (mAnimatingToOverview) {
return false;
}
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
return false;
}
return true;
}
@Override
public void onAnimationCancel(Animator animation) {
if (mCurrentAnimation != null && animation == mCurrentAnimation.getOriginalTarget()) {
Log.e(TAG, "Who dare cancel the animation when I am in control", new Exception());
clearState();
}
}
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mNoIntercept = !canInterceptTouch(ev);
if (mNoIntercept) {
return false;
}
// Now figure out which direction scroll events the controller will start
// calling the callbacks.
final int directionsToDetectScroll;
boolean ignoreSlopWhenSettling = false;
if (mCurrentAnimation != null) {
if (mCurrentAnimation.getProgressFraction() > 1 - RECATCH_REJECTION_FRACTION) {
directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
} else if (mCurrentAnimation.getProgressFraction() < RECATCH_REJECTION_FRACTION ) {
directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
} else {
directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
ignoreSlopWhenSettling = true;
}
} else {
if (mLauncher.isInState(ALL_APPS)) {
directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
mStartContainerType = ContainerType.ALLAPPS;
} else {
directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
mStartContainerType = mLauncher.getDragLayer().isEventOverHotseat(ev) ?
ContainerType.HOTSEAT : ContainerType.WORKSPACE;
}
}
mDetector.setDetectableScrollConditions(
directionsToDetectScroll, ignoreSlopWhenSettling);
}
if (mNoIntercept) {
return false;
}
onControllerTouchEvent(ev);
return mDetector.isDraggingOrSettling();
}
@Override
public boolean onControllerTouchEvent(MotionEvent ev) {
return mDetector.onTouchEvent(ev);
}
@Override
public void onDragStart(boolean start) {
if (mCurrentAnimation == null) {
float range = getShiftRange();
long maxAccuracy = (long) (2 * range);
mDragPauseDetector = new DragPauseDetector(this::onDragPauseDetected);
mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE);
if (FeatureFlags.ENABLE_TWO_SWIPE_TARGETS) {
mDragPauseDetector.addDisabledFlags(FLAG_DISABLED_TWO_TARGETS);
}
mOverviewProgressRange = new FloatRange();
mOverviewProgressRange.start = mLauncher.isInState(NORMAL)
? MIN_PROGRESS_TO_OVERVIEW
: 1 - MAX_PROGRESS_TO_OVERVIEW;
mOverviewProgressRange.end = mOverviewProgressRange.start
+ MAX_PROGRESS_TO_OVERVIEW - MIN_PROGRESS_TO_OVERVIEW;
// Build current animation
mFromState = mLauncher.getStateManager().getState();
mToState = mLauncher.isInState(ALL_APPS) ? NORMAL : ALL_APPS;
if (mToState == NORMAL && mLauncher.getStateManager().getLastState() == OVERVIEW) {
mToState = OVERVIEW;
mDragPauseDetector.addDisabledFlags(FLAG_DISABLED_BACK_TARGET);
}
mTaggedAnimatorSetBuilder = new TaggedAnimatorSetBuilder();
mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(
mToState, mTaggedAnimatorSetBuilder, maxAccuracy);
if (!TouchInteractionService.isConnected()) {
mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED);
}
mCurrentAnimation.getTarget().addListener(this);
mStartProgress = 0;
mProgressMultiplier = (mLauncher.isInState(ALL_APPS) ? 1 : -1) / range;
mCurrentAnimation.dispatchOnStart();
} else {
mCurrentAnimation.pause();
mStartProgress = mCurrentAnimation.getProgressFraction();
mDragPauseDetector.clearDisabledFlags(FLAG_OVERVIEW_DISABLED_FLING);
updatePauseDetectorRangeFlag();
}
}
private float getShiftRange() {
return mLauncher.getAllAppsController().getShiftRange();
}
@Override
public boolean onDrag(float displacement, float velocity) {
float deltaProgress = mProgressMultiplier * displacement;
mCurrentAnimation.setPlayFraction(deltaProgress + mStartProgress);
updatePauseDetectorRangeFlag();
mDragPauseDetector.onDrag(velocity);
return true;
}
private void updatePauseDetectorRangeFlag() {
if (mOverviewProgressRange.contains(mCurrentAnimation.getProgressFraction())) {
mDragPauseDetector.clearDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE);
} else {
mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE);
}
}
@Override
public void onDragEnd(float velocity, boolean fling) {
mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_FLING);
final int logAction;
LauncherState targetState;
final float progress = mCurrentAnimation.getProgressFraction();
if (fling) {
logAction = Touch.FLING;
targetState = velocity < 0 ? ALL_APPS : mLauncher.getStateManager().getLastState();
// snap to top or bottom using the release velocity
} else {
logAction = Touch.SWIPE;
targetState = (progress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
}
float endProgress;
if (mDragPauseDetector.isTriggered() && targetState == NORMAL) {
targetState = OVERVIEW;
endProgress = OVERVIEW.getVerticalProgress(mLauncher);
if (mFromState == NORMAL) {
endProgress = 1 - endProgress;
}
} else if (targetState == mToState) {
endProgress = 1;
} else {
endProgress = 0;
}
LauncherState targetStateFinal = targetState;
mCurrentAnimation.setEndAction(() ->
onSwipeInteractionCompleted(targetStateFinal, logAction));
float nextFrameProgress = Utilities.boundToRange(
progress + velocity * SINGLE_FRAME_MS / getShiftRange(), 0f, 1f);
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
anim.setFloatValues(nextFrameProgress, endProgress);
anim.setDuration(
SwipeDetector.calculateDuration(velocity, Math.abs(endProgress - progress)));
anim.setInterpolator(scrollInterpolatorForVelocity(velocity));
anim.start();
}
private void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
if (targetState != mFromState) {
// Transition complete. log the action
mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
mToState == ALL_APPS ? Direction.UP : Direction.DOWN,
mStartContainerType,
mFromState.containerType,
mToState.containerType,
mLauncher.getWorkspace().getCurrentPage());
}
clearState();
// TODO: mQuickOverviewAnimation might still be running in which changing a state instantly
// may cause a jump. Animate the state change with a short duration in this case?
mLauncher.getStateManager().goToState(targetState, false /* animated */);
}
private void onDragPauseDetected() {
final ValueAnimator twoStepAnimator = ValueAnimator.ofFloat(0, 1);
twoStepAnimator.setDuration(mCurrentAnimation.getDuration());
StateHandler[] handlers = mLauncher.getStateManager().getStateHandlers();
// Change the current animation to only play the vertical handle
AnimatorSet anim = new AnimatorSet();
anim.playTogether(mTaggedAnimatorSetBuilder.getAnimationsForTag(
handlers[SWIPE_HANDLER_INDEX]));
anim.play(twoStepAnimator);
mCurrentAnimation = mCurrentAnimation.cloneFor(anim);
AnimatorSetBuilder builder = new AnimatorSetBuilder();
AnimationConfig config = new AnimationConfig();
config.duration = QUICK_SNAP_TO_OVERVIEW_DURATION;
for (int i = OTHER_HANDLERS_START_INDEX; i < handlers.length; i++) {
handlers[i].setStateWithAnimation(OVERVIEW, builder, config);
}
mQuickOverviewAnimation = builder.build();
mQuickOverviewAnimation.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
onQuickOverviewAnimationComplete(twoStepAnimator);
}
});
mQuickOverviewAnimation.start();
}
private void onQuickOverviewAnimationComplete(ValueAnimator animator) {
if (mAnimatingToOverview) {
return;
}
// For the remainder to the interaction, the user can either go to the ALL_APPS state or
// the OVERVIEW state.
// The remaining state handlers are on the OVERVIEW state. Create one animation towards the
// ALL_APPS state and only call it when the user moved above the current range.
AnimationConfig config = new AnimationConfig();
config.duration = (long) (2 * getShiftRange());
config.userControlled = true;
AnimatorSetBuilder builderToAllAppsState = new AnimatorSetBuilder();
StateHandler[] handlers = mLauncher.getStateManager().getStateHandlers();
for (int i = OTHER_HANDLERS_START_INDEX; i < handlers.length; i++) {
handlers[i].setStateWithAnimation(ALL_APPS, builderToAllAppsState, config);
}
mCroppedAnimationController = new CroppedAnimationController(
AnimatorPlaybackController.wrap(builderToAllAppsState.build(), config.duration),
new FloatRange(animator.getAnimatedFraction(), mToState == ALL_APPS ? 1 : 0));
animator.addUpdateListener(mCroppedAnimationController);
}
private void clearState() {
mCurrentAnimation = null;
mTaggedAnimatorSetBuilder = null;
if (mDragPauseDetector != null) {
mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_CANCEL_STATE);
}
mDragPauseDetector = null;
if (mQuickOverviewAnimation != null) {
mQuickOverviewAnimation.cancel();
mQuickOverviewAnimation = null;
}
mCroppedAnimationController = null;
mAnimatingToOverview = false;
mDetector.finishedScrolling();
}
/**
* {@link AnimatorUpdateListener} which controls another animation for a fraction of range
*/
private static class CroppedAnimationController implements AnimatorUpdateListener {
private final AnimatorPlaybackController mTarget;
private final FloatRange mRange;
CroppedAnimationController(AnimatorPlaybackController target, FloatRange range) {
mTarget = target;
mRange = range;
}
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float fraction = valueAnimator.getAnimatedFraction();
if (mRange.start < mRange.end) {
if (fraction <= mRange.start) {
mTarget.setPlayFraction(0);
} else if (fraction >= mRange.end) {
mTarget.setPlayFraction(1);
} else {
mTarget.setPlayFraction((fraction - mRange.start) / (mRange.end - mRange.start));
}
} else if (mRange.start > mRange.end) {
if (fraction >= mRange.start) {
mTarget.setPlayFraction(0);
} else if (fraction <= mRange.end) {
mTarget.setPlayFraction(1);
} else {
mTarget.setPlayFraction((fraction - mRange.start) / (mRange.end - mRange.start));
}
} else {
// mRange.start == mRange.end
mTarget.setPlayFraction(0);
}
}
}
}
@@ -16,16 +16,19 @@
package com.android.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.Utilities.getPrefs;
import static com.android.quickstep.OverviewInteractionState.KEY_SWIPE_UP_ENABLED;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Hotseat;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.R;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.OverviewInteractionState;
import com.android.quickstep.RecentsModel;
@@ -34,15 +37,25 @@ import com.android.quickstep.views.RecentsView;
public class UiFactory {
public static TouchController[] createTouchControllers(Launcher launcher) {
if (FeatureFlags.ENABLE_TWO_SWIPE_TARGETS) {
SharedPreferences prefs = getPrefs(launcher);
boolean swipeUpEnabled = prefs.getBoolean(KEY_SWIPE_UP_ENABLED, true);
if (!swipeUpEnabled) {
return new TouchController[] {
new EdgeSwipeController(launcher),
new TwoStepSwipeController(launcher),
new OverviewSwipeController(launcher)};
launcher.getDragController(),
new LandscapeStatesTouchController(launcher),
new TaskViewTouchController(launcher)};
}
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
return new TouchController[] {
launcher.getDragController(),
new LandscapeStatesTouchController(launcher),
new LandscapeEdgeSwipeController(launcher),
new TaskViewTouchController(launcher)};
} else {
return new TouchController[] {
new TwoStepSwipeController(launcher),
new OverviewSwipeController(launcher)};
launcher.getDragController(),
new PortraitStatesTouchController(launcher),
new TaskViewTouchController(launcher)};
}
}
@@ -57,21 +70,15 @@ public class UiFactory {
}
public static void onLauncherStateOrFocusChanged(Launcher launcher) {
boolean shouldBackButtonBeVisible = launcher == null
|| !launcher.isInState(NORMAL)
|| !launcher.hasWindowFocus();
if (!shouldBackButtonBeVisible) {
boolean shouldBackButtonBeHidden = launcher != null
&& launcher.getStateManager().getState().hideBackButton
&& launcher.hasWindowFocus();
if (shouldBackButtonBeHidden) {
// Show the back button if there is a floating view visible.
DragLayer dragLayer = launcher.getDragLayer();
for (int i = dragLayer.getChildCount() - 1; i >= 0; i--) {
View child = dragLayer.getChildAt(i);
if (child instanceof AbstractFloatingView) {
shouldBackButtonBeVisible = true;
break;
}
}
shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenView(launcher) == null;
}
OverviewInteractionState.setBackButtonVisible(launcher, shouldBackButtonBeVisible);
OverviewInteractionState.getInstance(launcher)
.setBackButtonVisible(!shouldBackButtonBeHidden);
}
public static void resetOverview(Launcher launcher) {
@@ -79,17 +86,24 @@ public class UiFactory {
recents.reset();
}
public static void onStart(Launcher launcher) {
RecentsModel model = RecentsModel.getInstance(launcher);
public static void onStart(Context context) {
RecentsModel model = RecentsModel.getInstance(context);
if (model != null) {
model.onStart();
}
}
public static void onTrimMemory(Launcher launcher, int level) {
RecentsModel model = RecentsModel.getInstance(launcher);
public static void onTrimMemory(Context context, int level) {
RecentsModel model = RecentsModel.getInstance(context);
if (model != null) {
model.onTrimMemory(level);
}
}
public static View[] getHotseatExtraContent(Hotseat hotseat) {
return new View[] {
hotseat.findViewById(R.id.drag_indicator),
hotseat.findViewById(R.id.search_container_hotseat),
};
}
}
@@ -0,0 +1,367 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.quickstep;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.view.View;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherInitListener;
import com.android.launcher3.LauncherState;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.quickstep.views.LauncherLayoutListener;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.AssistDataReceiver;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import java.util.function.BiPredicate;
/**
* Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
*/
public interface ActivityControlHelper<T extends BaseDraggingActivity> {
LayoutListener createLayoutListener(T activity);
void onQuickstepGestureStarted(T activity, boolean activityVisible);
void onQuickInteractionStart(T activity, boolean activityVisible);
void executeOnNextDraw(T activity, TaskView targetView, Runnable action);
void onTransitionCancelled(T activity, boolean activityVisible);
int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect);
void onSwipeUpComplete(T activity);
void prepareRecentsUI(T activity, boolean activityVisible);
AnimatorPlaybackController createControllerForVisibleActivity(T activity);
AnimatorPlaybackController createControllerForHiddenActivity(T activity, int transitionLength);
ActivityInitListener createActivityInitListener(BiPredicate<T, Boolean> onInitListener);
void startRecents(Context context, Intent intent, AssistDataReceiver assistDataReceiver,
RecentsAnimationListener remoteAnimationListener);
@UiThread
@Nullable
RecentsView getVisibleRecentsView();
@UiThread
boolean switchToRecentsIfVisible();
class LauncherActivityControllerHelper implements ActivityControlHelper<Launcher> {
@Override
public LayoutListener createLayoutListener(Launcher activity) {
return new LauncherLayoutListener(activity);
}
@Override
public void onQuickstepGestureStarted(Launcher activity, boolean activityVisible) {
activity.onQuickstepGestureStarted(activityVisible);
}
@Override
public void onQuickInteractionStart(Launcher activity, boolean activityVisible) {
activity.getStateManager().goToState(FAST_OVERVIEW, activityVisible);
}
@Override
public void executeOnNextDraw(Launcher activity, TaskView targetView, Runnable action) {
ViewOnDrawExecutor executor = new ViewOnDrawExecutor() {
@Override
public void onViewDetachedFromWindow(View v) {
if (!isCompleted()) {
runAllTasks();
}
}
};
executor.attachTo(activity, targetView, false /* waitForLoadAnimation */);
executor.execute(action);
}
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
RecentsView.getPageRect(dp, context, outRect);
if (dp.isVerticalBarLayout()) {
Rect targetInsets = dp.getInsets();
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
return dp.hotseatBarSizePx + dp.hotseatBarSidePaddingPx + hotseatInset;
} else {
return dp.heightPx - outRect.bottom;
}
}
@Override
public void onTransitionCancelled(Launcher activity, boolean activityVisible) {
LauncherState startState = activity.getStateManager().getRestState();
activity.getStateManager().goToState(startState, activityVisible);
}
@Override
public void onSwipeUpComplete(Launcher activity) {
// Re apply state in case we did something funky during the transition.
activity.getStateManager().reapplyState();
}
@Override
public void prepareRecentsUI(Launcher activity, boolean activityVisible) {
LauncherState startState = activity.getStateManager().getState();
if (startState.disableRestore) {
startState = activity.getStateManager().getRestState();
}
activity.getStateManager().setRestState(startState);
if (!activityVisible) {
// Since the launcher is not visible, we can safely reset the scroll position.
// This ensures then the next swipe up to all-apps starts from scroll 0.
activity.getAppsView().reset(false /* animate */);
activity.getStateManager().goToState(OVERVIEW, false);
// Optimization, hide the all apps view to prevent layout while initializing
activity.getAppsView().getContentView().setVisibility(View.GONE);
}
}
@Override
public AnimatorPlaybackController createControllerForVisibleActivity(Launcher activity) {
DeviceProfile dp = activity.getDeviceProfile();
long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
return activity.getStateManager().createAnimationToNewWorkspace(OVERVIEW, accuracy);
}
@Override
public AnimatorPlaybackController createControllerForHiddenActivity(
Launcher activity, int transitionLength) {
AllAppsTransitionController controller = activity.getAllAppsController();
AnimatorSet anim = new AnimatorSet();
if (activity.getDeviceProfile().isVerticalBarLayout()) {
// TODO:
} else {
float scrollRange = Math.max(controller.getShiftRange(), 1);
float progressDelta = (transitionLength / scrollRange);
float endProgress = OVERVIEW.getVerticalProgress(activity);
float startProgress = endProgress + progressDelta;
ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(
controller, ALL_APPS_PROGRESS, startProgress, endProgress);
shiftAnim.setInterpolator(LINEAR);
anim.play(shiftAnim);
}
// TODO: Link this animation to state animation, so that it is cancelled
// automatically on state change
anim.setDuration(transitionLength * 2);
return AnimatorPlaybackController.wrap(anim, transitionLength * 2);
}
@Override
public ActivityInitListener createActivityInitListener(
BiPredicate<Launcher, Boolean> onInitListener) {
return new LauncherInitListener(onInitListener);
}
@Override
public void startRecents(Context context, Intent intent,
AssistDataReceiver assistDataReceiver,
RecentsAnimationListener remoteAnimationListener) {
ActivityManagerWrapper.getInstance().startRecentsActivity(
intent, assistDataReceiver, remoteAnimationListener, null, null);
}
@Nullable
@UiThread
private Launcher getVisibleLaucher() {
LauncherAppState app = LauncherAppState.getInstanceNoCreate();
if (app == null) {
return null;
}
Launcher launcher = (Launcher) app.getModel().getCallback();
return (launcher != null) && launcher.isStarted() && launcher.hasWindowFocus() ?
launcher : null;
}
@Nullable
@Override
public RecentsView getVisibleRecentsView() {
Launcher launcher = getVisibleLaucher();
return launcher != null && launcher.isInState(OVERVIEW)
? launcher.getOverviewPanel() : null;
}
@Override
public boolean switchToRecentsIfVisible() {
Launcher launcher = getVisibleLaucher();
if (launcher != null) {
launcher.getStateManager().goToState(OVERVIEW);
return true;
}
return false;
}
}
class FallbackActivityControllerHelper implements ActivityControlHelper<RecentsActivity> {
@Override
public void onQuickstepGestureStarted(RecentsActivity activity, boolean activityVisible) {
// TODO:
}
@Override
public void onQuickInteractionStart(RecentsActivity activity, boolean activityVisible) {
// TODO:
}
@Override
public void executeOnNextDraw(RecentsActivity activity, TaskView targetView,
Runnable action) {
// TODO:
new Handler(Looper.getMainLooper()).post(action);
}
@Override
public void onTransitionCancelled(RecentsActivity activity, boolean activityVisible) {
// TODO:
}
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
FallbackRecentsView.getCenterPageRect(dp, context, outRect);
if (dp.isVerticalBarLayout()) {
Rect targetInsets = dp.getInsets();
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
return dp.hotseatBarSizePx + dp.hotseatBarSidePaddingPx + hotseatInset;
} else {
return dp.heightPx - outRect.bottom;
}
}
@Override
public void onSwipeUpComplete(RecentsActivity activity) {
// TODO:
}
@Override
public void prepareRecentsUI(RecentsActivity activity, boolean activityVisible) {
// TODO:
}
@Override
public AnimatorPlaybackController createControllerForVisibleActivity(
RecentsActivity activity) {
DeviceProfile dp = activity.getDeviceProfile();
return createControllerForHiddenActivity(activity, Math.max(dp.widthPx, dp.heightPx));
}
@Override
public AnimatorPlaybackController createControllerForHiddenActivity(
RecentsActivity activity, int transitionLength) {
// We do not animate anything. Create a empty controller
AnimatorSet anim = new AnimatorSet();
return AnimatorPlaybackController.wrap(anim, transitionLength * 2);
}
@Override
public LayoutListener createLayoutListener(RecentsActivity activity) {
// We do not change anything as part of layout changes in fallback activity. Return a
// default layout listener.
return new LayoutListener() {
@Override
public void open() { }
@Override
public void setHandler(WindowTransformSwipeHandler handler) { }
@Override
public void finish() { }
};
}
@Override
public ActivityInitListener createActivityInitListener(
BiPredicate<RecentsActivity, Boolean> onInitListener) {
return new RecentsActivityTracker(onInitListener);
}
@Override
public void startRecents(Context context, Intent intent,
AssistDataReceiver assistDataReceiver,
final RecentsAnimationListener remoteAnimationListener) {
ActivityOptions options =
ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
new FallbackActivityOptions(remoteAnimationListener), 10000, 10000));
context.startActivity(intent, options.toBundle());
}
@Nullable
@Override
public RecentsView getVisibleRecentsView() {
RecentsActivity activity = RecentsActivityTracker.getCurrentActivity();
if (activity != null && activity.hasWindowFocus()) {
return activity.getOverviewPanel();
}
return null;
}
@Override
public boolean switchToRecentsIfVisible() {
return false;
}
}
interface LayoutListener {
void open();
void setHandler(WindowTransformSwipeHandler handler);
void finish();
}
interface ActivityInitListener {
void register();
void unregister();
}
}
@@ -1,50 +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.support.annotation.WorkerThread;
import com.android.launcher3.states.InternalStateHandler;
import com.android.quickstep.TouchConsumer.InteractionType;
public abstract class BaseSwipeInteractionHandler extends InternalStateHandler {
protected Runnable mGestureEndCallback;
protected boolean mIsGoingToHome;
public void setGestureEndCallback(Runnable gestureEndCallback) {
mGestureEndCallback = gestureEndCallback;
}
public void reset() {}
@WorkerThread
public abstract void onGestureStarted();
@WorkerThread
public abstract void onGestureEnded(float endVelocity);
public abstract void updateInteractionType(@InteractionType int interactionType);
@WorkerThread
public abstract void onQuickScrubEnd();
@WorkerThread
public abstract void onQuickScrubProgress(float progress);
@WorkerThread
public abstract void updateDisplacement(float displacement);
}
@@ -0,0 +1,82 @@
/*
* 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.graphics.Rect;
import android.util.Log;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
/**
* Temporary class to create activity options to emulate recents transition for fallback activtiy.
*/
public class FallbackActivityOptions implements RemoteAnimationRunnerCompat {
private final RecentsAnimationListener mListener;
public FallbackActivityOptions(RecentsAnimationListener listener) {
mListener = listener;
}
@Override
public void onAnimationStart(RemoteAnimationTargetCompat[] targetCompats,
Runnable runnable) {
DummyRecentsAnimationControllerCompat dummyRecentsAnim =
new DummyRecentsAnimationControllerCompat(runnable);
Rect insets = new Rect();
WindowManagerWrapper.getInstance().getStableInsets(insets);
mListener.onAnimationStart(dummyRecentsAnim, targetCompats, insets, null);
}
@Override
public void onAnimationCancelled() {
mListener.onAnimationCanceled();
}
private static class DummyRecentsAnimationControllerCompat
extends RecentsAnimationControllerCompat {
final Runnable mFinishCallback;
public DummyRecentsAnimationControllerCompat(Runnable finishCallback) {
mFinishCallback = finishCallback;
}
@Override
public ThumbnailData screenshotTask(int taskId) {
return new ThumbnailData();
}
@Override
public void setInputConsumerEnabled(boolean enabled) { }
@Override
public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) { }
@Override
public void finish(boolean toHome) {
if (toHome) {
mFinishCallback.run();
}
}
}
}
@@ -48,10 +48,21 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> implements
setPadding(padding.left, padding.top, padding.right, padding.bottom);
}
public static void verticalCenter(Rect padding, DeviceProfile dp) {
private static void verticalCenter(Rect padding, DeviceProfile dp) {
Rect insets = dp.getInsets();
int totalSpace = (padding.top + padding.bottom - insets.top - insets.bottom) / 2;
padding.top = insets.top + totalSpace;
padding.bottom = insets.bottom + totalSpace;
}
public static void getCenterPageRect(DeviceProfile grid, Context context, Rect outRect) {
Rect targetPadding = getPadding(grid, context);
verticalCenter(targetPadding, grid);
Rect insets = grid.getInsets();
outRect.set(
targetPadding.left + insets.left,
targetPadding.top + insets.top,
grid.widthPx - targetPadding.right - insets.right,
grid.heightPx - targetPadding.bottom - insets.bottom);
}
}
@@ -0,0 +1,96 @@
/*
* 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.annotation.TargetApi;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.ResolveInfo;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Build;
import android.provider.SearchIndexablesContract.XmlResource;
import android.provider.SearchIndexablesProvider;
import android.util.Xml;
import com.android.launcher3.R;
import com.android.launcher3.graphics.IconShapeOverride;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS;
import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS;
import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS;
@TargetApi(Build.VERSION_CODES.O)
public class LauncherSearchIndexablesProvider extends SearchIndexablesProvider {
@Override
public boolean onCreate() {
return true;
}
@Override
public Cursor queryXmlResources(String[] strings) {
MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
ResolveInfo settingsActivity = getContext().getPackageManager().resolveActivity(
new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
.setPackage(getContext().getPackageName()), 0);
cursor.newRow()
.add(XmlResource.COLUMN_XML_RESID, R.xml.indexable_launcher_prefs)
.add(XmlResource.COLUMN_INTENT_ACTION, Intent.ACTION_APPLICATION_PREFERENCES)
.add(XmlResource.COLUMN_INTENT_TARGET_PACKAGE, getContext().getPackageName())
.add(XmlResource.COLUMN_INTENT_TARGET_CLASS, settingsActivity.activityInfo.name);
return cursor;
}
@Override
public Cursor queryRawData(String[] projection) {
return new MatrixCursor(INDEXABLES_RAW_COLUMNS);
}
@Override
public Cursor queryNonIndexableKeys(String[] projection) {
MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
if (!getContext().getSystemService(LauncherApps.class).hasShortcutHostPermission()) {
// We are not the current launcher. Hide all preferences
try (XmlResourceParser parser = getContext().getResources()
.getXml(R.xml.indexable_launcher_prefs)) {
final int depth = parser.getDepth();
final int[] attrs = new int[] { android.R.attr.key };
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type == XmlPullParser.START_TAG) {
TypedArray a = getContext().obtainStyledAttributes(
Xml.asAttributeSet(parser), attrs);
cursor.addRow(new String[] {a.getString(0)});
a.recycle();
}
}
} catch (IOException |XmlPullParserException e) {
throw new RuntimeException(e);
}
} else if (!IconShapeOverride.isSupported(getContext())) {
cursor.addRow(new String[] {IconShapeOverride.KEY_PREFERENCE});
}
return cursor;
}
}
@@ -19,9 +19,7 @@ import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_MASK;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;
import android.annotation.TargetApi;
import android.os.Build;
@@ -43,17 +41,17 @@ public class MotionEventQueue {
private static final int ACTION_VIRTUAL = ACTION_MASK - 1;
private static final int ACTION_QUICK_SWITCH =
ACTION_VIRTUAL | (1 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_QUICK_SCRUB_START =
ACTION_VIRTUAL | (2 << ACTION_POINTER_INDEX_SHIFT);
ACTION_VIRTUAL | (1 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_QUICK_SCRUB_PROGRESS =
ACTION_VIRTUAL | (3 << ACTION_POINTER_INDEX_SHIFT);
ACTION_VIRTUAL | (2 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_QUICK_SCRUB_END =
ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
ACTION_VIRTUAL | (3 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_RESET =
ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_DEFER_INIT =
ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_SHOW_OVERVIEW_FROM_ALT_TAB =
ACTION_VIRTUAL | (6 << ACTION_POINTER_INDEX_SHIFT);
private final EventArray mEmptyArray = new EventArray();
@@ -143,9 +141,6 @@ public class MotionEventQueue {
MotionEvent event = array.get(i);
if (event.getActionMasked() == ACTION_VIRTUAL) {
switch (event.getAction()) {
case ACTION_QUICK_SWITCH:
mConsumer.updateTouchTracking(INTERACTION_QUICK_SWITCH);
break;
case ACTION_QUICK_SCRUB_START:
mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
break;
@@ -161,6 +156,10 @@ public class MotionEventQueue {
case ACTION_DEFER_INIT:
mConsumer.deferInit();
break;
case ACTION_SHOW_OVERVIEW_FROM_ALT_TAB:
mConsumer.onShowOverviewFromAltTab();
mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
break;
default:
Log.e(TAG, "Invalid virtual event: " + event.getAction());
}
@@ -189,14 +188,14 @@ public class MotionEventQueue {
queueNoPreProcess(MotionEvent.obtain(0, 0, action, progress, 0, 0));
}
public void onQuickSwitch() {
queueVirtualAction(ACTION_QUICK_SWITCH, 0);
}
public void onQuickScrubStart() {
queueVirtualAction(ACTION_QUICK_SCRUB_START, 0);
}
public void onOverviewShownFromAltTab() {
queueVirtualAction(ACTION_SHOW_OVERVIEW_FROM_ALT_TAB, 0);
}
public void onQuickScrubProgress(float progress) {
queueVirtualAction(ACTION_QUICK_SCRUB_PROGRESS, progress);
}
@@ -1,394 +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.quickstep;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;
import static com.android.quickstep.TouchConsumer.isInteractionQuick;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.RectEvaluator;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.UiThread;
import android.view.View;
import android.view.ViewTreeObserver.OnPreDrawListener;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Hotseat;
import com.android.launcher3.Launcher;
import com.android.launcher3.Launcher.OnResumeCallback;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.TouchConsumer.InteractionType;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.WindowManagerWrapper;
@TargetApi(Build.VERSION_CODES.O)
public class NavBarSwipeInteractionHandler extends BaseSwipeInteractionHandler implements
OnResumeCallback {
private static final int STATE_LAUNCHER_READY = 1 << 0;
private static final int STATE_ACTIVITY_MULTIPLIER_COMPLETE = 1 << 4;
private static final int STATE_SCALED_SNAPSHOT_RECENTS = 1 << 5;
private static final int STATE_SCALED_SNAPSHOT_APP = 1 << 6;
private static final long MAX_SWIPE_DURATION = 200;
private static final long MIN_SWIPE_DURATION = 80;
// Ideal velocity for a smooth transition
private static final float PIXEL_PER_MS = 2f;
private static final float MIN_PROGRESS_FOR_OVERVIEW = 0.5f;
private final Rect mStableInsets = new Rect();
private final Rect mSourceRect = new Rect();
private final Rect mTargetRect = new Rect();
private final Rect mCurrentRect = new Rect();
private final RectEvaluator mRectEvaluator = new RectEvaluator(mCurrentRect);
// Shift in the range of [0, 1].
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
// 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
// visible.
private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
// Activity multiplier in the range of [0, 1]. When the activity becomes visible, this is
// animated to 1, so allow for a smooth transition.
private final AnimatedFloat mActivityMultiplier = new AnimatedFloat(this::updateFinalShift);
private final int mRunningTaskId;
private final Context mContext;
private final MultiStateCallback mStateCallback;
private Launcher mLauncher;
private SnapshotDragView mDragView;
private RecentsView mRecentsView;
private QuickScrubController mQuickScrubController;
private Hotseat mHotseat;
private boolean mWasLauncherAlreadyVisible;
private boolean mLauncherReady;
private boolean mTouchEndHandled;
private float mCurrentDisplacement;
private @InteractionType int mInteractionType;
private boolean mStartedQuickScrubFromHome;
private Bitmap mTaskSnapshot;
NavBarSwipeInteractionHandler(RunningTaskInfo runningTaskInfo, Context context,
@InteractionType int interactionType) {
mContext = context;
mInteractionType = interactionType;
mRunningTaskId = runningTaskInfo.id;
WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
DeviceProfile dp = LauncherAppState.getIDP(mContext).getDeviceProfile(mContext);
// TODO: If in multi window mode, dp = dp.getMultiWindowProfile()
dp = dp.copy(mContext);
// TODO: Use different insets for multi-window mode
dp.updateInsets(mStableInsets);
RecentsView.getPageRect(dp, mContext, mTargetRect);
mSourceRect.set(0, 0, dp.widthPx - mStableInsets.left - mStableInsets.right,
dp.heightPx - mStableInsets.top - mStableInsets.bottom);
// Build the state callback
mStateCallback = new MultiStateCallback();
mStateCallback.addCallback(STATE_LAUNCHER_READY, this::onLauncherReady);
mStateCallback.addCallback(STATE_SCALED_SNAPSHOT_APP, this::resumeLastTask);
mStateCallback.addCallback(
STATE_SCALED_SNAPSHOT_RECENTS | STATE_ACTIVITY_MULTIPLIER_COMPLETE,
this::onAnimationToLauncherComplete);
mStateCallback.addCallback(STATE_LAUNCHER_READY | STATE_SCALED_SNAPSHOT_APP,
this::cleanupLauncher);
}
private void onLauncherReady() {
mLauncherReady = true;
executeFrameUpdate();
long duration = Math.min(MAX_SWIPE_DURATION,
Math.max((long) (-mCurrentDisplacement / PIXEL_PER_MS), MIN_SWIPE_DURATION));
if (mCurrentShift.getCurrentAnimation() != null) {
ObjectAnimator anim = mCurrentShift.getCurrentAnimation();
long theirDuration = anim.getDuration() - anim.getCurrentPlayTime();
// TODO: Find a better heuristic
duration = (duration + theirDuration) / 2;
}
ObjectAnimator anim = mActivityMultiplier.animateToValue(1)
.setDuration(duration);
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
mStateCallback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE);
}
});
anim.start();
}
public void setTaskSnapshot(Bitmap taskSnapshot) {
mTaskSnapshot = taskSnapshot;
}
@Override
public void onLauncherResume() {
TraceHelper.partitionSection("TouchInt", "Launcher On resume");
mDragView.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mDragView.getViewTreeObserver().removeOnPreDrawListener(this);
mStateCallback.setState(STATE_LAUNCHER_READY);
TraceHelper.partitionSection("TouchInt", "Launcher drawn");
return true;
}
});
}
@Override
protected boolean init(Launcher launcher, boolean alreadyOnHome) {
launcher.setOnResumeCallback(this);
mLauncher = launcher;
mRecentsView = launcher.getOverviewPanel();
mRecentsView.showTask(mRunningTaskId);
mHotseat = mLauncher.getHotseat();
mWasLauncherAlreadyVisible = alreadyOnHome;
AbstractFloatingView.closeAllOpenViews(mLauncher, alreadyOnHome);
mLauncher.getStateManager().goToState(LauncherState.OVERVIEW, alreadyOnHome);
mDragView = new SnapshotDragView(mLauncher, mTaskSnapshot);
mLauncher.getDragLayer().addView(mDragView);
mDragView.setPivotX(0);
mDragView.setPivotY(0);
if (isInteractionQuick(mInteractionType)) {
updateUiForQuickScrub();
}
// Optimization
if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
// All-apps search box is visible in vertical bar layout.
mLauncher.getAppsView().setVisibility(View.GONE);
}
TraceHelper.partitionSection("TouchInt", "Launcher on new intent");
return false;
}
public void updateInteractionType(@InteractionType int interactionType) {
Preconditions.assertUIThread();
if (mInteractionType != INTERACTION_NORMAL) {
throw new IllegalArgumentException(
"Can't change interaction type from " + mInteractionType);
}
if (!isInteractionQuick(interactionType)) {
throw new IllegalArgumentException(
"Can't change interaction type to " + interactionType);
}
mInteractionType = interactionType;
if (mLauncher != null) {
updateUiForQuickScrub();
}
}
private void updateUiForQuickScrub() {
mStartedQuickScrubFromHome = mWasLauncherAlreadyVisible;
mQuickScrubController = mRecentsView.getQuickScrubController();
mQuickScrubController.onQuickScrubStart(mStartedQuickScrubFromHome);
animateToProgress(1f, MAX_SWIPE_DURATION);
if (mStartedQuickScrubFromHome) {
mDragView.setVisibility(View.INVISIBLE);
}
}
@UiThread
public void updateDisplacement(float displacement) {
mCurrentDisplacement = displacement;
executeFrameUpdate();
}
private void executeFrameUpdate() {
if (mLauncherReady) {
final float displacement = -mCurrentDisplacement;
int hotseatSize = getHotseatSize();
float translation = Utilities.boundToRange(displacement, 0, hotseatSize);
float shift = hotseatSize == 0 ? 0 : translation / hotseatSize;
mCurrentShift.updateValue(shift);
}
}
@UiThread
private void updateFinalShift() {
if (!mLauncherReady || mStartedQuickScrubFromHome) {
return;
}
float shift = mCurrentShift.value * mActivityMultiplier.value;
AllAppsTransitionController controller = mLauncher.getAllAppsController();
float range = getHotseatSize() / controller.getShiftRange();
controller.setProgress(1 + (1 - shift) * range);
mRectEvaluator.evaluate(shift, mSourceRect, mTargetRect);
float scale = (float) mCurrentRect.width() / mSourceRect.width();
mDragView.setTranslationX(mCurrentRect.left - mStableInsets.left * scale * shift);
mDragView.setTranslationY(mCurrentRect.top - mStableInsets.top * scale * shift);
mDragView.setScaleX(scale);
mDragView.setScaleY(scale);
// TODO: mDragView.getViewBounds().setClipLeft((int) (mStableInsets.left * shift));
mDragView.getViewBounds().setClipTop((int) (mStableInsets.top * shift));
// TODO: mDragView.getViewBounds().setClipRight((int) (mStableInsets.right * shift));
mDragView.getViewBounds().setClipBottom((int) (mStableInsets.bottom * shift));
}
private int getHotseatSize() {
return mLauncher.getDeviceProfile().isVerticalBarLayout()
? mHotseat.getWidth() : mHotseat.getHeight();
}
@Override
public void onGestureStarted() { }
@UiThread
public void onGestureEnded(float endVelocity) {
if (mTouchEndHandled) {
return;
}
mTouchEndHandled = true;
Resources res = mContext.getResources();
float flingThreshold = res.getDimension(R.dimen.quickstep_fling_threshold_velocity);
boolean isFling = Math.abs(endVelocity) > flingThreshold;
long duration = MAX_SWIPE_DURATION;
final float endShift;
if (!isFling) {
endShift = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? 1 : 0;
} else {
endShift = endVelocity < 0 ? 1 : 0;
float minFlingVelocity = res.getDimension(R.dimen.quickstep_fling_min_velocity);
if (Math.abs(endVelocity) > minFlingVelocity && mLauncherReady) {
float distanceToTravel = (endShift - mCurrentShift.value) * getHotseatSize();
// we want the page's snap velocity to approximately match the velocity at
// which the user flings, so we scale the duration by a value near to the
// derivative of the scroll interpolator at zero, ie. 5.
duration = 5 * Math.round(1000 * Math.abs(distanceToTravel / endVelocity));
}
}
animateToProgress(endShift, duration);
}
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
private void animateToProgress(float progress, long duration) {
mIsGoingToHome = Float.compare(progress, 1) == 0;
ObjectAnimator anim = mCurrentShift.animateToValue(progress).setDuration(duration);
anim.setInterpolator(Interpolators.SCROLL);
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
mStateCallback.setState(mIsGoingToHome
? STATE_SCALED_SNAPSHOT_RECENTS : STATE_SCALED_SNAPSHOT_APP);
}
});
anim.start();
}
@UiThread
private void resumeLastTask() {
RecentsTaskLoadPlan loadPlan = RecentsModel.getInstance(mContext).getLastLoadPlan();
if (loadPlan != null) {
Task task = loadPlan.getTaskStack().findTaskWithId(mRunningTaskId);
if (task != null) {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(task.key, opts,
null, null);
}
}
}
public void reset() {
mCurrentShift.cancelAnimation();
if (mGestureEndCallback != null) {
mGestureEndCallback.run();
}
}
private void cleanupLauncher() {
reset();
// TODO: These should be done as part of ActivityOptions#OnAnimationStarted
mLauncher.getStateManager().reapplyState();
mLauncher.setOnResumeCallback(() -> mDragView.close(false));
}
private void onAnimationToLauncherComplete() {
reset();
mDragView.close(false);
View currentRecentsPage = mRecentsView.getPageAt(mRecentsView.getCurrentPage());
if (currentRecentsPage instanceof TaskView) {
((TaskView) currentRecentsPage).animateIconToScale(1f);
}
if (mInteractionType == INTERACTION_QUICK_SWITCH) {
if (mQuickScrubController != null) {
mQuickScrubController.onQuickSwitch();
}
}
}
public void onQuickScrubEnd() {
if (mQuickScrubController != null) {
mQuickScrubController.onQuickScrubEnd();
} else {
// TODO:
}
}
public void onQuickScrubProgress(float progress) {
if (mQuickScrubController != null) {
mQuickScrubController.onQuickScrubProgress(progress);
} else {
// TODO:
}
}
}
@@ -21,28 +21,20 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.INVALID_POINTER_ID;
import static com.android.quickstep.RemoteRunnable.executeSafely;
import static com.android.quickstep.TouchInteractionService.DEBUG_SHOW_OVERVIEW_BUTTON;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.os.SystemClock;
import android.view.Choreographer;
import android.view.Display;
import android.view.MotionEvent;
@@ -52,9 +44,7 @@ import android.view.ViewConfiguration;
import android.view.WindowManager;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.TraceHelper;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.AssistDataReceiver;
import com.android.systemui.shared.system.BackgroundExecutor;
@@ -73,16 +63,15 @@ import java.util.concurrent.TimeUnit;
*/
@TargetApi(Build.VERSION_CODES.P)
public class OtherActivityTouchConsumer extends ContextWrapper implements TouchConsumer {
private static final String TAG = "ActivityTouchConsumer";
private static final long LAUNCHER_DRAW_TIMEOUT_MS = 150;
private static final int[] DEFERRED_HIT_TARGETS = DEBUG_SHOW_OVERVIEW_BUTTON
private static final int[] DEFERRED_HIT_TARGETS = false
? new int[] {HIT_TARGET_BACK, HIT_TARGET_OVERVIEW} : new int[] {HIT_TARGET_BACK};
private final RunningTaskInfo mRunningTask;
private final RecentsModel mRecentsModel;
private final Intent mHomeIntent;
private final ISystemUiProxy mISystemUiProxy;
private final ActivityControlHelper mActivityControlHelper;
private final MainThreadExecutor mMainThreadExecutor;
private final Choreographer mBackgroundThreadChoreographer;
@@ -93,7 +82,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
private boolean mTouchThresholdCrossed;
private int mTouchSlop;
private float mStartDisplacement;
private BaseSwipeInteractionHandler mInteractionHandler;
private WindowTransformSwipeHandler mInteractionHandler;
private int mDisplayRotation;
private Rect mStableInsets = new Rect();
@@ -102,7 +91,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
private boolean mIsGoingToHome;
public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
RecentsModel recentsModel, Intent homeIntent, ISystemUiProxy systemUiProxy,
RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer,
@HitTarget int downHitTarget, VelocityTracker velocityTracker) {
super(base);
@@ -110,12 +99,17 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
mRecentsModel = recentsModel;
mHomeIntent = homeIntent;
mVelocityTracker = velocityTracker;
mISystemUiProxy = systemUiProxy;
mActivityControlHelper = activityControl;
mMainThreadExecutor = mainThreadExecutor;
mBackgroundThreadChoreographer = backgroundThreadChoreographer;
mIsDeferredDownTarget = Arrays.binarySearch(DEFERRED_HIT_TARGETS, downHitTarget) >= 0;
}
@Override
public void onShowOverviewFromAltTab() {
startTouchTrackingForWindowAnimation(SystemClock.uptimeMillis());
}
@Override
public void accept(MotionEvent ev) {
if (mVelocityTracker == null) {
@@ -132,7 +126,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
// Start the window animation on down to give more time for launcher to draw if the
// user didn't start the gesture over the back button
if (!isUsingScreenShot() && !mIsDeferredDownTarget) {
if (!mIsDeferredDownTarget) {
startTouchTrackingForWindowAnimation(ev.getEventTime());
}
@@ -172,14 +166,11 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
if (mTouchThresholdCrossed) {
mStartDisplacement = Math.signum(displacement) * mTouchSlop;
if (isUsingScreenShot()) {
startTouchTrackingForScreenshotAnimation();
} else if (mIsDeferredDownTarget) {
if (mIsDeferredDownTarget) {
// If we deferred starting the window animation on touch down, then
// start tracking now
startTouchTrackingForWindowAnimation(ev.getEventTime());
}
notifyGestureStarted();
}
} else if (mInteractionHandler != null) {
@@ -205,11 +196,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
}
// Notify the handler that the gesture has actually started
mInteractionHandler.onGestureStarted();
// Notify the system that we have started tracking the event
if (mISystemUiProxy != null) {
executeSafely(mISystemUiProxy::onRecentsAnimationStarted);
}
}
private boolean isNavBarOnRight() {
@@ -220,69 +206,10 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
return mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
}
private boolean isUsingScreenShot() {
return Utilities.getPrefs(this).getBoolean("pref_use_screenshot_for_swipe_up", false);
}
/**
* Called when the gesture has started.
*/
private void startTouchTrackingForScreenshotAnimation() {
// Create the shared handler
final NavBarSwipeInteractionHandler handler =
new NavBarSwipeInteractionHandler(mRunningTask, this, INTERACTION_NORMAL);
TraceHelper.partitionSection("TouchInt", "Thershold crossed ");
// Start the recents activity on a background thread
BackgroundExecutor.get().submit(() -> {
// Get the snap shot before
handler.setTaskSnapshot(getCurrentTaskSnapshot());
// Start the launcher activity with our custom handler
Intent homeIntent = handler.addToIntent(new Intent(mHomeIntent));
startActivity(homeIntent, ActivityOptions.makeCustomAnimation(this, 0, 0).toBundle());
TraceHelper.partitionSection("TouchInt", "Home started");
});
// Preload the plan
mRecentsModel.loadTasks(mRunningTask.id, null);
mInteractionHandler = handler;
mInteractionHandler.setGestureEndCallback(mEventQueue::reset);
}
private Bitmap getCurrentTaskSnapshot() {
TraceHelper.beginSection("TaskSnapshot");
// TODO: We are using some hardcoded layers for now, to best approximate the activity layers
Point displaySize = new Point();
Display display = getSystemService(WindowManager.class).getDefaultDisplay();
display.getRealSize(displaySize);
int rotation = display.getRotation();
// The rotation is backwards in landscape, so flip it.
if (rotation == Surface.ROTATION_270) {
rotation = Surface.ROTATION_90;
} else if (rotation == Surface.ROTATION_90) {
rotation = Surface.ROTATION_270;
}
try {
return mISystemUiProxy.screenshot(new Rect(), displaySize.x, displaySize.y, 0, 100000,
false, rotation).toBitmap();
} catch (Exception e) {
Log.e(TAG, "Error capturing snapshot", e);
// Return a dummy bitmap
Bitmap bitmap = Bitmap.createBitmap(displaySize.x, displaySize.y, Config.RGB_565);
bitmap.eraseColor(Color.WHITE);
return bitmap;
} finally {
TraceHelper.endSection("TaskSnapshot");
}
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
// Create the shared handler
final WindowTransformSwipeHandler handler =
new WindowTransformSwipeHandler(mRunningTask, this, touchTimeMs);
final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
mRunningTask, this, touchTimeMs, mActivityControlHelper);
// Preload the plan
mRecentsModel.loadTasks(mRunningTask.id, null);
@@ -299,8 +226,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
handler.initWhenReady();
TraceHelper.beginSection("RecentsController");
Runnable startActivity = () -> ActivityManagerWrapper.getInstance()
.startRecentsActivity(mHomeIntent,
Runnable startActivity = () -> mActivityControlHelper.startRecents(this, mHomeIntent,
new AssistDataReceiver() {
@Override
public void onHandleAssistData(Bundle bundle) {
@@ -329,7 +255,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
handler.onRecentsAnimationCanceled();
}
}
}, null, null);
});
if (Looper.myLooper() != Looper.getMainLooper()) {
startActivity.run();
@@ -358,7 +284,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
: isNavBarOnLeft() ? -mVelocityTracker.getXVelocity(mActivePointerId)
: mVelocityTracker.getYVelocity(mActivePointerId);
mInteractionHandler.onGestureEnded(velocity);
} else if (!isUsingScreenShot()) {
} else {
// Since we start touch tracking on DOWN, we may reach this state without actually
// starting the gesture. In that case, just cleanup immediately.
reset();
@@ -375,7 +301,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
public void reset() {
// Clean up the old interaction handler
if (mInteractionHandler != null) {
final BaseSwipeInteractionHandler handler = mInteractionHandler;
final WindowTransformSwipeHandler handler = mInteractionHandler;
mInteractionHandler = null;
mIsGoingToHome = handler.mIsGoingToHome;
mMainThreadExecutor.execute(handler::reset);
@@ -385,24 +311,15 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
@Override
public void updateTouchTracking(int interactionType) {
notifyGestureStarted();
if (isUsingScreenShot()) {
mMainThreadExecutor.execute(() -> {
if (mInteractionHandler != null) {
mInteractionHandler.updateInteractionType(interactionType);
}
});
} else {
if (mInteractionHandler != null) {
mInteractionHandler.updateInteractionType(interactionType);
}
if (mInteractionHandler != null) {
mInteractionHandler.updateInteractionType(interactionType);
}
}
@Override
public Choreographer getIntrimChoreographer(MotionEventQueue queue) {
mEventQueue = queue;
return isUsingScreenShot() ? null : mBackgroundThreadChoreographer;
return mBackgroundThreadChoreographer;
}
@Override
@@ -16,24 +16,55 @@
package com.android.quickstep;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.quickstep.TouchInteractionService.DEBUG_SHOW_OVERVIEW_BUTTON;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager.RecentTaskInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityOptions;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import android.util.SparseArray;
import android.view.ViewConfiguration;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.InternalStateHandler;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.ActivityControlHelper.FallbackActivityControllerHelper;
import com.android.quickstep.ActivityControlHelper.LauncherActivityControllerHelper;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
import com.android.systemui.shared.recents.view.RecentsTransition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.AssistDataReceiver;
import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
/**
* Helper class to handle various atomic commands for switching between Overview.
@@ -41,56 +72,263 @@ import com.android.systemui.shared.system.ActivityManagerWrapper;
@TargetApi(Build.VERSION_CODES.P)
public class OverviewCommandHelper extends InternalStateHandler {
private static final boolean DEBUG_START_FALLBACK_ACTIVITY = DEBUG_SHOW_OVERVIEW_BUTTON;
private static final int RID_RESET_SWIPE_HANDLER = 0;
private static final int RID_CANCEL_CONTROLLER = 1;
private static final int RID_CANCEL_ZOOM_OUT_ANIMATION = 2;
private static final long RECENTS_LAUNCH_DURATION = 150;
private static final String TAG = "OverviewCommandHelper";
private static final boolean DEBUG_START_FALLBACK_ACTIVITY = false;
private final Context mContext;
private final ActivityManagerWrapper mAM;
private final RecentsModel mRecentsModel;
private final MainThreadExecutor mMainThreadExecutor;
public final Intent homeIntent;
public final ComponentName launcher;
private final SparseArray<Runnable> mCurrentCommandFinishRunnables = new SparseArray<>();
// Monotonically increasing command ids.
private int mCurrentCommandId = 0;
private long mLastToggleTime;
private WindowTransformSwipeHandler mWindowTransformSwipeHandler;
private final Point mWindowSize = new Point();
private final Rect mTaskTargetRect = new Rect();
private final RectF mTempTaskTargetRect = new RectF();
public OverviewCommandHelper(Context context) {
mContext = context;
mAM = ActivityManagerWrapper.getInstance();
mMainThreadExecutor = new MainThreadExecutor();
mRecentsModel = RecentsModel.getInstance(mContext);
homeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)
.setPackage(context.getPackageName())
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ResolveInfo info = context.getPackageManager().resolveActivity(homeIntent, 0);
launcher = new ComponentName(context.getPackageName(), info.activityInfo.name);
if (DEBUG_START_FALLBACK_ACTIVITY) {
launcher = new ComponentName(context, RecentsActivity.class);
homeIntent.addCategory(Intent.CATEGORY_DEFAULT)
.removeCategory(Intent.CATEGORY_HOME);
} else {
launcher = new ComponentName(context.getPackageName(), info.activityInfo.name);
}
// Clear the packageName as system can fail to dedupe it b/64108432
homeIntent.setComponent(launcher).setPackage(null);
}
public void onOverviewToggle() {
if (DEBUG_START_FALLBACK_ACTIVITY) {
mContext.startActivity(new Intent(mContext, RecentsActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));
return;
}
private void openRecents() {
Intent intent = addToIntent(new Intent(homeIntent));
mContext.startActivity(intent);
initWhenReady();
}
long elapsedTime = SystemClock.elapsedRealtime() - mLastToggleTime;
mLastToggleTime = SystemClock.elapsedRealtime();
if (isOverviewAlmostVisible()) {
boolean isQuickTap = elapsedTime < ViewConfiguration.getDoubleTapTimeout();
startNonLauncherTask(isQuickTap ? 2 : 1);
@UiThread
private void addFinishCommand(int requestId, int id, Runnable action) {
if (requestId < mCurrentCommandId) {
action.run();
} else {
Intent intent = addToIntent(new Intent(homeIntent));
mContext.startActivity(intent);
initWhenReady();
mCurrentCommandFinishRunnables.put(id, action);
}
}
private void startNonLauncherTask(int backStackCount) {
for (RecentTaskInfo rti : mAM.getRecentTasks(backStackCount, UserHandle.myUserId())) {
backStackCount--;
if (backStackCount == 0) {
mAM.startActivityFromRecents(rti.id, null);
@UiThread
private void clearFinishCommand(int requestId, int id) {
if (requestId == mCurrentCommandId) {
mCurrentCommandFinishRunnables.remove(id);
}
}
@UiThread
private void initSwipeHandler(ActivityControlHelper helper, long time,
Consumer<WindowTransformSwipeHandler> onAnimationInitCallback) {
final int commandId = mCurrentCommandId;
RunningTaskInfo taskInfo = ActivityManagerWrapper.getInstance().getRunningTask();
final WindowTransformSwipeHandler handler =
new WindowTransformSwipeHandler(taskInfo, mContext, time, helper);
// Preload the plan
mRecentsModel.loadTasks(taskInfo.id, null);
mWindowTransformSwipeHandler = handler;
mTempTaskTargetRect.setEmpty();
handler.setGestureEndCallback(() -> {
if (mWindowTransformSwipeHandler == handler) {
mWindowTransformSwipeHandler = null;
mTempTaskTargetRect.setEmpty();
}
clearFinishCommand(commandId, RID_RESET_SWIPE_HANDLER);
clearFinishCommand(commandId, RID_CANCEL_CONTROLLER);
});
handler.initWhenReady();
addFinishCommand(commandId, RID_RESET_SWIPE_HANDLER, handler::reset);
TraceHelper.beginSection(TAG);
Runnable startActivity = () -> helper.startRecents(mContext, homeIntent,
new AssistDataReceiver() {
@Override
public void onHandleAssistData(Bundle bundle) {
mRecentsModel.preloadAssistData(taskInfo.id, bundle);
}
},
new RecentsAnimationListener() {
public void onAnimationStart(
RecentsAnimationControllerCompat controller,
RemoteAnimationTargetCompat[] apps, Rect homeContentInsets,
Rect minimizedHomeBounds) {
if (mWindowTransformSwipeHandler == handler) {
TraceHelper.partitionSection(TAG, "Received");
handler.onRecentsAnimationStart(controller, apps, homeContentInsets,
minimizedHomeBounds);
mTempTaskTargetRect.set(handler.getTargetRect(mWindowSize));
mMainThreadExecutor.execute(() -> {
addFinishCommand(commandId,
RID_CANCEL_CONTROLLER, () -> controller.finish(true));
if (commandId == mCurrentCommandId) {
onAnimationInitCallback.accept(handler);
}
});
} else {
TraceHelper.endSection(TAG, "Finishing no handler");
controller.finish(false /* toHome */);
}
}
public void onAnimationCanceled() {
TraceHelper.endSection(TAG, "Cancelled: " + handler);
if (mWindowTransformSwipeHandler == handler) {
handler.onRecentsAnimationCanceled();
}
}
});
// We should almost always get touch-town on background thread. This is an edge case
// when the background Choreographer has not yet initialized.
BackgroundExecutor.get().submit(startActivity);
}
@UiThread
private void startZoomOutAnim(final WindowTransformSwipeHandler handler) {
final int commandId = mCurrentCommandId;
ValueAnimator anim = ValueAnimator.ofInt(0, -handler.getTransitionLength());
anim.addUpdateListener((a) -> handler.updateDisplacement((Integer) a.getAnimatedValue()));
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
handler.onGestureEnded(0);
clearFinishCommand(commandId, RID_CANCEL_ZOOM_OUT_ANIMATION);
}
});
handler.onGestureStarted();
anim.setDuration(RECENTS_LAUNCH_DURATION);
anim.setInterpolator(Interpolators.AGGRESSIVE_EASE);
anim.start();
addFinishCommand(commandId, RID_CANCEL_ZOOM_OUT_ANIMATION, anim::cancel);
}
public void onOverviewToggle() {
long time = SystemClock.elapsedRealtime();
mMainThreadExecutor.execute(() -> {
long elapsedTime = time - mLastToggleTime;
mLastToggleTime = time;
mCurrentCommandId++;
mTempTaskTargetRect.round(mTaskTargetRect);
boolean isQuickTap = elapsedTime < ViewConfiguration.getDoubleTapTimeout();
int runnableCount = mCurrentCommandFinishRunnables.size();
if (runnableCount > 0) {
for (int i = 0; i < runnableCount; i++) {
mCurrentCommandFinishRunnables.valueAt(i).run();
}
mCurrentCommandFinishRunnables.clear();
isQuickTap = true;
}
ActivityControlHelper helper = getActivityControlHelper();
RecentsView recents = helper.getVisibleRecentsView();
if (recents != null) {
int childCount = recents.getChildCount();
if (childCount != 0) {
((TaskView) recents.getChildAt(childCount >= 2 ? 1 : 0)).launchTask(true);
}
// There are not enough tasks. Skip
return;
}
if (isQuickTap) {
// Focus last task. Start is on background thread so that all ActivityManager calls
// are serialized
BackgroundExecutor.get().submit(this::startLastTask);
return;
}
if (helper.switchToRecentsIfVisible()) {
return;
}
initSwipeHandler(helper, time, this::startZoomOutAnim);
});
}
public void onOverviewShown() {
getLauncher().runOnUiThread(() -> {
if (isOverviewAlmostVisible()) {
final RecentsView rv = getLauncher().getOverviewPanel();
rv.snapToTaskAfterNext();
} else {
openRecents();
}
}
);
}
public void onOverviewHidden() {
getLauncher().runOnUiThread(() -> {
if (isOverviewAlmostVisible()) {
final RecentsView rv = getLauncher().getOverviewPanel();
rv.launchNextTask();
}
}
);
}
@WorkerThread
private void startLastTask() {
// TODO: This should go through recents model.
List<RecentTaskInfo> tasks = mAM.getRecentTasks(2, UserHandle.myUserId());
if (tasks.size() > 1) {
RecentTaskInfo rti = tasks.get(1);
final ActivityOptions options;
if (!mTaskTargetRect.isEmpty()) {
final Rect targetRect = new Rect(mTaskTargetRect);
targetRect.offset(Utilities.isRtl(mContext.getResources())
? - mTaskTargetRect.width() : mTaskTargetRect.width(), 0);
final AppTransitionAnimationSpecCompat specCompat =
new AppTransitionAnimationSpecCompat(rti.id, null, targetRect);
AppTransitionAnimationSpecsFuture specFuture =
new AppTransitionAnimationSpecsFuture(mMainThreadExecutor.getHandler()) {
@Override
public List<AppTransitionAnimationSpecCompat> composeSpecs() {
return Collections.singletonList(specCompat);
}
};
options = RecentsTransition.createAspectScaleAnimation(mContext,
mMainThreadExecutor.getHandler(), true /* scaleUp */,
specFuture, () -> {});
} else {
options = ActivityOptions.makeBasic();
}
mAM.startActivityFromRecents(rti.id, options);
}
}
@@ -117,4 +355,15 @@ public class OverviewCommandHelper extends InternalStateHandler {
return false;
}
public boolean isUsingFallbackActivity() {
return DEBUG_START_FALLBACK_ACTIVITY;
}
public ActivityControlHelper getActivityControlHelper() {
if (DEBUG_START_FALLBACK_ACTIVITY) {
return new FallbackActivityControllerHelper();
} else {
return new LauncherActivityControllerHelper();
}
}
}
@@ -15,20 +15,28 @@
*/
package com.android.quickstep;
import static com.android.quickstep.TouchInteractionService.DEBUG_SHOW_OVERVIEW_BUTTON;
import static com.android.launcher3.Utilities.getPrefs;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.WorkerThread;
import android.util.Log;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.util.UiThreadHelper;
import com.android.systemui.shared.recents.ISystemUiProxy;
import java.util.concurrent.ExecutionException;
/**
* Sets overview interaction flags, such as:
*
@@ -39,55 +47,109 @@ import com.android.systemui.shared.recents.ISystemUiProxy;
*
* @see com.android.systemui.shared.system.NavigationBarCompat.InteractionType and associated flags.
*/
public class OverviewInteractionState {
public class OverviewInteractionState implements OnSharedPreferenceChangeListener {
private static final String TAG = "OverviewFlags";
private static final Handler sUiHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
updateOverviewInteractionFlag((Context) msg.obj, msg.what, msg.arg1 == 1);
}
};
private static final Handler sBackgroundHandler = new Handler(
UiThreadHelper.getBackgroundLooper()) {
@Override
public void handleMessage(Message msg) {
ISystemUiProxy systemUiProxy = (ISystemUiProxy) msg.obj;
int flags = msg.what;
try {
systemUiProxy.setInteractionState(flags);
} catch (RemoteException e) {
Log.w(TAG, "Unable to update overview interaction flags", e);
// We do not need any synchronization for this variable as its only written on UI thread.
private static OverviewInteractionState INSTANCE;
public static OverviewInteractionState getInstance(final Context context) {
if (INSTANCE == null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
INSTANCE = new OverviewInteractionState(context.getApplicationContext());
} else {
try {
return new MainThreadExecutor().submit(
() -> OverviewInteractionState.getInstance(context)).get();
} catch (InterruptedException|ExecutionException e) {
throw new RuntimeException(e);
}
}
}
};
private static int sFlags = DEBUG_SHOW_OVERVIEW_BUTTON ? FLAG_SHOW_OVERVIEW_BUTTON : 0;
public static void setBackButtonVisible(Context context, boolean visible) {
updateFlagOnUi(context, FLAG_HIDE_BACK_BUTTON, !visible);
return INSTANCE;
}
private static void updateFlagOnUi(Context context, int flag, boolean enabled) {
sUiHandler.removeMessages(flag);
sUiHandler.sendMessage(sUiHandler.obtainMessage(flag, enabled ? 1 : 0, 0, context));
public static final String KEY_SWIPE_UP_ENABLED = "pref_enable_quickstep";
private static final int MSG_SET_PROXY = 200;
private static final int MSG_SET_BACK_BUTTON_VISIBLE = 201;
private static final int MSG_SET_SWIPE_UP_ENABLED = 202;
private final Handler mUiHandler;
private final Handler mBgHandler;
// These are updated on the background thread
private ISystemUiProxy mISystemUiProxy;
private boolean mBackButtonVisible = true;
private boolean mSwipeUpEnabled = true;
private OverviewInteractionState(Context context) {
mUiHandler = new Handler(this::handleUiMessage);
mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
SharedPreferences prefs = getPrefs(context);
prefs.registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(prefs, KEY_SWIPE_UP_ENABLED);
}
private static void updateOverviewInteractionFlag(Context context, int flag, boolean enabled) {
if (enabled) {
sFlags |= flag;
} else {
sFlags &= ~flag;
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String s) {
if (KEY_SWIPE_UP_ENABLED.equals(s)) {
mUiHandler.removeMessages(MSG_SET_SWIPE_UP_ENABLED);
boolean swipeUpEnabled = prefs.getBoolean(s, true);
mUiHandler.obtainMessage(MSG_SET_SWIPE_UP_ENABLED,
swipeUpEnabled ? 1 : 0, 0).sendToTarget();
}
}
ISystemUiProxy systemUiProxy = RecentsModel.getInstance(context).getSystemUiProxy();
if (systemUiProxy == null) {
Log.w(TAG, "Unable to update overview interaction flags; not bound to service");
public void setBackButtonVisible(boolean visible) {
mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_VISIBLE);
mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_VISIBLE, visible ? 1 : 0, 0)
.sendToTarget();
}
public void setSystemUiProxy(ISystemUiProxy proxy) {
mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
}
private boolean handleUiMessage(Message msg) {
mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2).sendToTarget();
return true;
}
private boolean handleBgMessage(Message msg) {
switch (msg.what) {
case MSG_SET_PROXY:
mISystemUiProxy = (ISystemUiProxy) msg.obj;
break;
case MSG_SET_BACK_BUTTON_VISIBLE:
mBackButtonVisible = msg.arg1 != 0;
break;
case MSG_SET_SWIPE_UP_ENABLED:
mSwipeUpEnabled = msg.arg1 != 0;
break;
}
applyFlags();
return true;
}
@WorkerThread
private void applyFlags() {
if (mISystemUiProxy == null) {
return;
}
// If we aren't already setting these flags, do so now on the background thread.
if (!sBackgroundHandler.hasMessages(sFlags)) {
sBackgroundHandler.sendMessage(sBackgroundHandler.obtainMessage(sFlags, systemUiProxy));
int flags;
if (mSwipeUpEnabled) {
flags = mBackButtonVisible ? 0 : FLAG_HIDE_BACK_BUTTON;
} else {
flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON;
}
try {
mISystemUiProxy.setInteractionState(flags);
} catch (RemoteException e) {
Log.w(TAG, "Unable to update overview interaction flags", e);
}
}
}
@@ -36,7 +36,7 @@ import com.android.quickstep.views.TaskView;
*/
public class QuickScrubController implements OnAlarmListener {
public static final int QUICK_SWITCH_START_DURATION = 210;
public static final int QUICK_SCRUB_START_DURATION = 210;
private static final boolean ENABLE_AUTO_ADVANCE = true;
private static final int NUM_QUICK_SCRUB_SECTIONS = 3;
@@ -53,7 +53,6 @@ public class QuickScrubController implements OnAlarmListener {
private int mQuickScrubSection;
private boolean mStartedFromHome;
private boolean mHasAlarmRun;
private boolean mQuickSwitched;
private boolean mFinishedTransitionToQuickScrub;
public QuickScrubController(BaseActivity activity, RecentsView recentsView) {
@@ -70,7 +69,6 @@ public class QuickScrubController implements OnAlarmListener {
mStartedFromHome = startingFromHome;
mQuickScrubSection = 0;
mHasAlarmRun = false;
mQuickSwitched = false;
mFinishedTransitionToQuickScrub = false;
snapToNextTaskIfAvailable();
@@ -84,7 +82,13 @@ public class QuickScrubController implements OnAlarmListener {
}
int page = mRecentsView.getNextPage();
Runnable launchTaskRunnable = () -> {
((TaskView) mRecentsView.getPageAt(page)).launchTask(true);
TaskView taskView = ((TaskView) mRecentsView.getPageAt(page));
if (taskView != null) {
taskView.launchTask(true);
} else {
// Break out of quick scrub so user can interact with launcher.
mActivity.onBackPressed();
}
};
int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
* QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
@@ -119,48 +123,24 @@ public class QuickScrubController implements OnAlarmListener {
}
}
public void onQuickSwitch() {
mQuickSwitched = true;
quickSwitchIfReady();
}
public void onFinishedTransitionToQuickScrub() {
mFinishedTransitionToQuickScrub = true;
quickSwitchIfReady();
}
/**
* Immediately launches the current task (which we snapped to in onQuickScrubStart) if we've
* gotten the onQuickSwitch callback and the transition to quick scrub has completed.
*/
private void quickSwitchIfReady() {
if (mQuickSwitched && mFinishedTransitionToQuickScrub) {
onQuickScrubEnd();
mActivity.getUserEventDispatcher().logActionOnControl(Touch.FLING,
ControlType.QUICK_SCRUB_BUTTON, null, mStartedFromHome ?
ContainerType.WORKSPACE : ContainerType.APP);
}
}
public void snapToNextTaskIfAvailable() {
if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
int toPage = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1;
goToPageWithHaptic(toPage, QUICK_SWITCH_START_DURATION);
mRecentsView.snapToPage(toPage, QUICK_SCRUB_START_DURATION);
}
}
private void goToPageWithHaptic(int pageToGoTo) {
goToPageWithHaptic(pageToGoTo, -1);
}
private void goToPageWithHaptic(int pageToGoTo, int overrideDuration) {
pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getPageCount() - 1);
if (pageToGoTo != mRecentsView.getNextPage()) {
int duration = overrideDuration > -1 ? overrideDuration
: Math.abs(pageToGoTo - mRecentsView.getNextPage())
int duration = Math.abs(pageToGoTo - mRecentsView.getNextPage())
* QUICKSCRUB_SNAP_DURATION_PER_PAGE;
mRecentsView.snapToPage(pageToGoTo, duration);
mRecentsView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
}
@@ -15,17 +15,26 @@
*/
package com.android.quickstep;
import android.app.ActivityOptions;
import android.os.Bundle;
import android.view.View;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.badge.BadgeInfo;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.views.BaseDragLayer;
/**
* A simple activity to show the recently launched tasks
*/
public class RecentsActivity extends BaseActivity {
public class RecentsActivity extends BaseDraggingActivity {
private RecentsRootView mRecentsRootView;
private FallbackRecentsView mFallbackRecentsView;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -39,5 +48,55 @@ public class RecentsActivity extends BaseActivity {
: new InvariantDeviceProfile(this).getDeviceProfile(this));
setContentView(R.layout.fallback_recents_activity);
mRecentsRootView = findViewById(R.id.drag_layer);
mFallbackRecentsView = findViewById(R.id.overview_panel);
RecentsActivityTracker.onRecentsActivityCreate(this);
}
@Override
public BaseDragLayer getDragLayer() {
return mRecentsRootView;
}
@Override
public View getRootView() {
return mRecentsRootView;
}
@Override
public <T extends View> T getOverviewPanel() {
return (T) mFallbackRecentsView;
}
@Override
public BadgeInfo getBadgeInfoForItem(ItemInfo info) {
return null;
}
@Override
public ActivityOptions getActivityLaunchOptions(View v, boolean useDefaultLaunchOptions) {
return null;
}
@Override
public void invalidateParent(ItemInfo info) { }
@Override
protected void onStart() {
super.onStart();
UiFactory.onStart(this);
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
UiFactory.onTrimMemory(this, level);
}
@Override
protected void onDestroy() {
super.onDestroy();
RecentsActivityTracker.onRecentsActivityDestroy(this);
}
}
@@ -0,0 +1,81 @@
/*
* 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.annotation.TargetApi;
import android.os.Build;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import java.lang.ref.WeakReference;
import java.util.function.BiPredicate;
/**
* Utility class to track create/destroy for RecentsActivity
*/
@TargetApi(Build.VERSION_CODES.P)
public class RecentsActivityTracker implements ActivityInitListener {
private static final Object LOCK = new Object();
private static WeakReference<RecentsActivityTracker> sTracker = new WeakReference<>(null);
private static WeakReference<RecentsActivity> sCurrentActivity = new WeakReference<>(null);
private final BiPredicate<RecentsActivity, Boolean> mOnInitListener;
public RecentsActivityTracker(BiPredicate<RecentsActivity, Boolean> onInitListener) {
mOnInitListener = onInitListener;
}
@Override
public void register() {
synchronized (LOCK) {
sTracker = new WeakReference<>(this);
}
}
@Override
public void unregister() {
synchronized (LOCK) {
if (sTracker.get() == this) {
sTracker.clear();
}
}
}
public static void onRecentsActivityCreate(RecentsActivity activity) {
synchronized (LOCK) {
RecentsActivityTracker tracker = sTracker.get();
if (tracker != null && tracker.mOnInitListener.test(activity, false)) {
sTracker.clear();
}
sCurrentActivity = new WeakReference<>(activity);
}
}
public static void onRecentsActivityDestroy(RecentsActivity activity) {
synchronized (LOCK) {
if (sCurrentActivity.get() == activity) {
sCurrentActivity.clear();
}
}
}
public static RecentsActivity getCurrentActivity() {
synchronized (LOCK) {
return sCurrentActivity.get();
}
}
}
@@ -30,6 +30,7 @@ import android.os.UserHandle;
import android.support.annotation.WorkerThread;
import android.util.LruCache;
import android.util.SparseArray;
import android.view.accessibility.AccessibilityManager;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
@@ -85,6 +86,7 @@ public class RecentsModel extends TaskStackChangeListener {
private ISystemUiProxy mSystemUiProxy;
private boolean mClearAssistCacheOnStackChange = true;
private final boolean mPreloadTasksInBackground;
private final AccessibilityManager mAccessibilityManager;
private RecentsModel(Context context) {
mContext = context;
@@ -111,6 +113,7 @@ public class RecentsModel extends TaskStackChangeListener {
mTaskChangeId = 1;
loadTasks(-1, null);
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
}
public RecentsTaskLoader getRecentsTaskLoader() {
@@ -140,7 +143,7 @@ public class RecentsModel extends TaskStackChangeListener {
// Preload the plan
RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(mContext);
PreloadOptions opts = new PreloadOptions();
opts.loadTitles = false;
opts.loadTitles = mAccessibilityManager.isEnabled();
loadPlan.preloadPlan(opts, mRecentsTaskLoader, taskId, UserHandle.myUserId());
// Set the load plan on UI thread
mMainThreadExecutor.execute(() -> {
@@ -187,7 +190,7 @@ public class RecentsModel extends TaskStackChangeListener {
launchOpts.onlyLoadPausedActivities = true;
launchOpts.loadThumbnails = true;
PreloadOptions preloadOpts = new PreloadOptions();
preloadOpts.loadTitles = false;
preloadOpts.loadTitles = mAccessibilityManager.isEnabled();
plan.preloadPlan(preloadOpts, mRecentsTaskLoader, -1, userId);
mRecentsTaskLoader.loadTasks(plan, launchOpts);
}
@@ -21,17 +21,19 @@ import android.graphics.Rect;
import android.util.AttributeSet;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
public class RecentsRootView extends InsettableFrameLayout {
public class RecentsRootView extends BaseDragLayer<RecentsActivity> {
private final BaseActivity mActivity;
public RecentsRootView(Context context, AttributeSet attrs) {
super(context, attrs);
mActivity = BaseActivity.fromContext(context);
mControllers = new TouchController[0];
}
@TargetApi(23)
@@ -1,92 +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.quickstep;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.systemui.shared.recents.view.AnimateableViewBounds;
/**
* Floating view which shows the task snapshot allowing it to be dragged and placed.
*/
public class SnapshotDragView extends AbstractFloatingView implements Insettable {
private final Launcher mLauncher;
private final Bitmap mSnapshot;
private final AnimateableViewBounds mViewBounds;
public SnapshotDragView(Launcher launcher, Bitmap snapshot) {
super(launcher, null);
mLauncher = launcher;
mSnapshot = snapshot;
mViewBounds = new AnimateableViewBounds(this, 0);
setWillNotDraw(false);
setClipToOutline(true);
setOutlineProvider(mViewBounds);
}
AnimateableViewBounds getViewBounds() {
return mViewBounds;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mSnapshot != null) {
setMeasuredDimension(mSnapshot.getWidth(), mSnapshot.getHeight());
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
public void setInsets(Rect insets) {
}
@Override
protected void onDraw(Canvas canvas) {
if (mSnapshot != null) {
canvas.drawBitmap(mSnapshot, 0, 0, null);
}
}
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
return false;
}
@Override
protected void handleClose(boolean animate) {
// We dont suupport animate.
mLauncher.getDragLayer().removeView(this);
}
@Override
public void logActionCommand(int command) {
// We should probably log the weather
}
@Override
protected boolean isOfType(int type) {
return (type & TYPE_QUICKSTEP_PREVIEW) != 0;
}
}
@@ -30,13 +30,15 @@ import android.view.View;
import android.view.ViewTreeObserver.OnPreDrawListener;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.util.InstantAppResolver;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.model.Task;
@@ -70,11 +72,12 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
}
@Override
public View.OnClickListener getOnClickListener(Launcher launcher, ItemInfo itemInfo) {
public View.OnClickListener getOnClickListener(
BaseDraggingActivity activity, ItemInfo itemInfo) {
return null;
}
public View.OnClickListener getOnClickListener(final Launcher launcher, final TaskView view) {
public View.OnClickListener getOnClickListener(BaseDraggingActivity activity, TaskView view) {
Task task = view.getTask();
ShortcutInfo dummyInfo = new ShortcutInfo();
@@ -82,14 +85,14 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
ComponentName component = task.getTopComponent();
dummyInfo.intent.setComponent(component);
dummyInfo.user = UserHandle.of(task.key.userId);
dummyInfo.title = TaskUtils.getTitle(launcher, task);
dummyInfo.title = TaskUtils.getTitle(activity, task);
return getOnClickListenerForTask(launcher, task, dummyInfo);
return getOnClickListenerForTask(activity, task, dummyInfo);
}
protected View.OnClickListener getOnClickListenerForTask(final Launcher launcher,
final Task task, final ItemInfo dummyInfo) {
return mSystemShortcut.getOnClickListener(launcher, dummyInfo);
protected View.OnClickListener getOnClickListenerForTask(
BaseDraggingActivity activity, Task task, ItemInfo dummyInfo) {
return mSystemShortcut.getOnClickListener(activity, dummyInfo);
}
public static class AppInfo extends TaskSystemShortcut<SystemShortcut.AppInfo> {
@@ -98,10 +101,13 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
}
}
public static class SplitScreen extends TaskSystemShortcut implements OnPreDrawListener {
public static class SplitScreen extends TaskSystemShortcut implements OnPreDrawListener,
DeviceProfile.OnDeviceProfileChangeListener, View.OnLayoutChangeListener {
private Handler mHandler;
private RecentsView mRecentsView;
private TaskView mTaskView;
private BaseDraggingActivity mActivity;
public SplitScreen() {
super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
@@ -109,22 +115,27 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
}
@Override
public View.OnClickListener getOnClickListener(Launcher launcher, TaskView taskView) {
if (launcher.getDeviceProfile().isMultiWindowMode) {
public View.OnClickListener getOnClickListener(
BaseDraggingActivity activity, TaskView taskView) {
if (activity.getDeviceProfile().isMultiWindowMode) {
return null;
}
final Task task = taskView.getTask();
final int taskId = task.key.id;
if (!task.isDockable) {
return null;
}
mActivity = activity;
mRecentsView = activity.getOverviewPanel();
mTaskView = taskView;
final TaskThumbnailView thumbnailView = taskView.getThumbnail();
return (v -> {
AbstractFloatingView.closeOpenViews(launcher, true,
AbstractFloatingView.closeOpenViews(activity, true,
AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
if (ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key.id,
if (ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
ActivityOptionsCompat.makeSplitScreenOptions(true))) {
ISystemUiProxy sysUiProxy = RecentsModel.getInstance(launcher).getSystemUiProxy();
ISystemUiProxy sysUiProxy = RecentsModel.getInstance(activity).getSystemUiProxy();
try {
sysUiProxy.onSplitScreenInvoked();
} catch (RemoteException e) {
@@ -132,26 +143,35 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
return;
}
// Add a device profile change listener to kick off animating the side tasks
// once we enter multiwindow mode and relayout
activity.addOnDeviceProfileChangeListener(this);
final Runnable animStartedListener = () -> {
// Hide the task view and wait for the window to be resized
// TODO: Consider animating in launcher and do an in-place start activity
// afterwards
mRecentsView.addIgnoreResetTask(mTaskView);
mTaskView.setAlpha(0f);
mTaskView.getViewTreeObserver().addOnPreDrawListener(SplitScreen.this);
launcher.<RecentsView>getOverviewPanel().removeView(taskView);
};
final int[] position = new int[2];
taskView.getLocationOnScreen(position);
final int width = (int) (taskView.getWidth() * taskView.getScaleX());
final int height = (int) (taskView.getHeight() * taskView.getScaleY());
thumbnailView.getLocationOnScreen(position);
final int width = (int) (thumbnailView.getWidth() * taskView.getScaleX());
final int height = (int) (thumbnailView.getHeight() * taskView.getScaleY());
final Rect taskBounds = new Rect(position[0], position[1],
position[0] + width, position[1] + height);
Bitmap thumbnail = RecentsTransition.drawViewIntoHardwareBitmap(
taskBounds.width(), taskBounds.height(), taskView, 1f, Color.BLACK);
taskBounds.width(), taskBounds.height(), thumbnailView, 1f,
Color.BLACK);
AppTransitionAnimationSpecsFuture future =
new AppTransitionAnimationSpecsFuture(mHandler) {
@Override
public List<AppTransitionAnimationSpecCompat> composeSpecs() {
return Collections.singletonList(new AppTransitionAnimationSpecCompat(
task.key.id, thumbnail, taskBounds));
taskId, thumbnail, taskBounds));
}
};
WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
@@ -166,6 +186,24 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
WindowManagerWrapper.getInstance().endProlongedAnimations();
return true;
}
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
mActivity.removeOnDeviceProfileChangeListener(this);
if (dp.isMultiWindowMode) {
mTaskView.getRootView().addOnLayoutChangeListener(this);
}
}
@Override
public void onLayoutChange(View v, int l, int t, int r, int b,
int oldL, int oldT, int oldR, int oldB) {
mTaskView.getRootView().removeOnLayoutChangeListener(this);
mRecentsView.removeIgnoreResetTask(mTaskView);
// Start animating in the side pages once launcher has been resized
mRecentsView.dismissTask(mTaskView, false, false);
}
}
public static class Pin extends TaskSystemShortcut {
@@ -178,8 +216,9 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
}
@Override
public View.OnClickListener getOnClickListener(Launcher launcher, TaskView taskView) {
ISystemUiProxy sysUiProxy = RecentsModel.getInstance(launcher).getSystemUiProxy();
public View.OnClickListener getOnClickListener(
BaseDraggingActivity activity, TaskView taskView) {
ISystemUiProxy sysUiProxy = RecentsModel.getInstance(activity).getSystemUiProxy();
if (sysUiProxy == null) {
return null;
}
@@ -211,11 +250,11 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
}
@Override
protected View.OnClickListener getOnClickListenerForTask(Launcher launcher, Task task,
ItemInfo itemInfo) {
if (InstantAppResolver.newInstance(launcher).isInstantApp(launcher,
protected View.OnClickListener getOnClickListenerForTask(
BaseDraggingActivity activity, Task task, ItemInfo itemInfo) {
if (InstantAppResolver.newInstance(activity).isInstantApp(activity,
task.getTopComponent().getPackageName())) {
return mSystemShortcut.createOnClickListener(launcher, itemInfo);
return mSystemShortcut.createOnClickListener(activity, itemInfo);
}
return null;
}
@@ -16,12 +16,12 @@
package com.android.quickstep;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.util.Log;
import com.android.launcher3.Launcher;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.systemui.shared.recents.model.Task;
@@ -34,10 +34,10 @@ public class TaskUtils {
private static final String TAG = "TaskUtils";
public static CharSequence getTitle(Launcher launcher, Task task) {
LauncherAppsCompat launcherAppsCompat = LauncherAppsCompat.getInstance(launcher);
UserManagerCompat userManagerCompat = UserManagerCompat.getInstance(launcher);
PackageManager packageManager = launcher.getPackageManager();
public static CharSequence getTitle(Context context, Task task) {
LauncherAppsCompat launcherAppsCompat = LauncherAppsCompat.getInstance(context);
UserManagerCompat userManagerCompat = UserManagerCompat.getInstance(context);
PackageManager packageManager = context.getPackageManager();
UserHandle user = UserHandle.of(task.key.userId);
ApplicationInfo applicationInfo = launcherAppsCompat.getApplicationInfo(
task.getTopComponent().getPackageName(), 0, user);
@@ -29,21 +29,14 @@ import java.util.function.Consumer;
@FunctionalInterface
public interface TouchConsumer extends Consumer<MotionEvent> {
static boolean isInteractionQuick(@InteractionType int interactionType) {
return interactionType == INTERACTION_QUICK_SCRUB ||
interactionType == INTERACTION_QUICK_SWITCH;
}
@IntDef(flag = true, value = {
INTERACTION_NORMAL,
INTERACTION_QUICK_SWITCH,
INTERACTION_QUICK_SCRUB
})
@Retention(RetentionPolicy.SOURCE)
@interface InteractionType {}
int INTERACTION_NORMAL = 0;
int INTERACTION_QUICK_SWITCH = 1;
int INTERACTION_QUICK_SCRUB = 2;
int INTERACTION_QUICK_SCRUB = 1;
default void reset() { }
@@ -72,4 +65,6 @@ public interface TouchConsumer extends Consumer<MotionEvent> {
default boolean forceToLauncherConsumer() {
return false;
}
default void onShowOverviewFromAltTab() {}
}
@@ -23,6 +23,7 @@ import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
@@ -47,7 +48,6 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.IOverviewProxy;
@@ -61,7 +61,7 @@ import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
@TargetApi(Build.VERSION_CODES.O)
public class TouchInteractionService extends Service {
public static final boolean DEBUG_SHOW_OVERVIEW_BUTTON = false;
public static final boolean DEBUG_OPEN_OVERVIEW_VIA_ALT_TAB = false;
private static final SparseArray<String> sMotionEventNames;
@@ -86,7 +86,7 @@ public class TouchInteractionService extends Service {
@Override
public void onPreMotionEvent(@HitTarget int downHitTarget) throws RemoteException {
TraceHelper.beginSection("SysUiBinder");
onBinderPreMotionEvent(downHitTarget);
setupTouchConsumer(downHitTarget);
TraceHelper.partitionSection("SysUiBinder", "Down target " + downHitTarget);
}
@@ -106,15 +106,7 @@ public class TouchInteractionService extends Service {
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
RemoteRunnable.executeSafely(() -> mISystemUiProxy.setRecentsOnboardingText(
getResources().getString(R.string.recents_swipe_up_onboarding)));
Launcher launcher = (Launcher) LauncherAppState.getInstance(
TouchInteractionService.this).getModel().getCallback();
UiFactory.onLauncherStateOrFocusChanged(launcher);
}
@Override
public void onQuickSwitch() {
mEventQueue.onQuickSwitch();
TraceHelper.endSection("SysUiBinder", "onQuickSwitch");
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
}
@Override
@@ -140,10 +132,29 @@ public class TouchInteractionService extends Service {
}
@Override
public void onOverviewShown(boolean triggeredFromAltTab) { }
public void onOverviewShown(boolean triggeredFromAltTab) {
if (DEBUG_OPEN_OVERVIEW_VIA_ALT_TAB) {
if (triggeredFromAltTab) {
setupTouchConsumer(HIT_TARGET_NONE);
mEventQueue.onOverviewShownFromAltTab();
}
}
}
@Override
public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { }
public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
if (DEBUG_OPEN_OVERVIEW_VIA_ALT_TAB) {
if (triggeredFromAltTab && !triggeredFromHomeKey) {
// onOverviewShownFromAltTab initiates quick scrub. Ending it here.
mEventQueue.onQuickScrubEnd();
}
}
}
@Override
public void onQuickStep(MotionEvent motionEvent) {
}
};
private final TouchConsumer mNoOpTouchConsumer = (ev) -> {};
@@ -160,6 +171,7 @@ public class TouchInteractionService extends Service {
private MainThreadExecutor mMainThreadExecutor;
private ISystemUiProxy mISystemUiProxy;
private OverviewCommandHelper mOverviewCommandHelper;
private OverviewInteractionState mOverviewInteractionState;
private Choreographer mMainThreadChoreographer;
private Choreographer mBackgroundThreadChoreographer;
@@ -173,6 +185,7 @@ public class TouchInteractionService extends Service {
mOverviewCommandHelper = new OverviewCommandHelper(this);
mMainThreadChoreographer = Choreographer.getInstance();
mEventQueue = new MotionEventQueue(mMainThreadChoreographer, mNoOpTouchConsumer);
mOverviewInteractionState = OverviewInteractionState.getInstance(this);
sConnected = true;
@@ -193,7 +206,7 @@ public class TouchInteractionService extends Service {
return mMyBinder;
}
private void onBinderPreMotionEvent(@HitTarget int downHitTarget) {
private void setupTouchConsumer(@HitTarget int downHitTarget) {
mEventQueue.reset();
TouchConsumer oldConsumer = mEventQueue.getConsumer();
if (oldConsumer.deferNextEventToMainThread()) {
@@ -221,7 +234,8 @@ public class TouchInteractionService extends Service {
tracker = VelocityTracker.obtain();
}
return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
mOverviewCommandHelper.homeIntent, mISystemUiProxy, mMainThreadExecutor,
mOverviewCommandHelper.homeIntent,
mOverviewCommandHelper.getActivityControlHelper(), mMainThreadExecutor,
mBackgroundThreadChoreographer, downHitTarget, tracker);
}
}
@@ -314,14 +328,10 @@ public class TouchInteractionService extends Service {
if (mInvalidated) {
return;
}
if (TouchConsumer.isInteractionQuick(interactionType)) {
if (interactionType == INTERACTION_QUICK_SCRUB) {
Runnable action = () -> {
Runnable onComplete = null;
if (interactionType == INTERACTION_QUICK_SWITCH) {
onComplete = mQuickScrubController::onQuickSwitch;
}
LauncherState fromState = mLauncher.getStateManager().getState();
mLauncher.getStateManager().goToState(FAST_OVERVIEW, true, onComplete);
mLauncher.getStateManager().goToState(FAST_OVERVIEW, true);
mQuickScrubController.onQuickScrubStart(fromState == NORMAL);
};
@@ -15,22 +15,16 @@
*/
package com.android.quickstep;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_START_DURATION;
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_DURATION;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;
import static com.android.quickstep.TouchConsumer.isInteractionQuick;
import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
import static com.android.systemui.shared.recents.utilities.Utilities
.postAtFrontOfQueueAsynchronously;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
@@ -41,7 +35,6 @@ import android.graphics.Matrix.ScaleToFit;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.metrics.LogMaker;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -51,16 +44,15 @@ import android.support.annotation.WorkerThread;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver.OnDrawListener;
import android.view.animation.Interpolator;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
@@ -69,8 +61,10 @@ 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;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.ActivityControlHelper.LayoutListener;
import com.android.quickstep.TouchConsumer.InteractionType;
import com.android.quickstep.util.SysuiEventLogger;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -84,42 +78,8 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
import java.util.StringJoiner;
class EventLogTags {
private EventLogTags() {
} // don't instantiate
/** 524292 sysui_multi_action (content|4) */
public static final int SYSUI_MULTI_ACTION = 524292;
public static void writeSysuiMultiAction(Object[] content) {
android.util.EventLog.writeEvent(SYSUI_MULTI_ACTION, content);
}
}
class MetricsLogger {
private static MetricsLogger sMetricsLogger;
private static MetricsLogger getLogger() {
if (sMetricsLogger == null) {
sMetricsLogger = new MetricsLogger();
}
return sMetricsLogger;
}
protected void saveLog(Object[] rep) {
EventLogTags.writeSysuiMultiAction(rep);
}
public void write(LogMaker content) {
if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
content.setType(4/*MetricsEvent.TYPE_ACTION*/);
}
saveLog(content.serialize());
}
}
@TargetApi(Build.VERSION_CODES.O)
public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
private static final boolean DEBUG_STATES = false;
@@ -142,9 +102,8 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
// States for quick switch/scrub
private static final int STATE_SWITCH_TO_SCREENSHOT_COMPLETE = 1 << 10;
private static final int STATE_QUICK_SWITCH = 1 << 11;
private static final int STATE_QUICK_SCRUB_START = 1 << 12;
private static final int STATE_QUICK_SCRUB_END = 1 << 13;
private static final int STATE_QUICK_SCRUB_START = 1 << 11;
private static final int STATE_QUICK_SCRUB_END = 1 << 12;
private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
@@ -193,6 +152,8 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
// The clip rect in source app window coordinates
private final Rect mClipRect = new Rect();
private final RectFEvaluator mRectFEvaluator = new RectFEvaluator();
protected Runnable mGestureEndCallback;
protected boolean mIsGoingToHome;
private DeviceProfile mDp;
private int mTransitionDragLength;
@@ -206,12 +167,14 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
private final Context mContext;
private final int mRunningTaskId;
private final ActivityControlHelper<T> mActivityControlHelper;
private final ActivityInitListener mActivityInitListener;
private MultiStateCallback mStateCallback;
private AnimatorPlaybackController mLauncherTransitionController;
private Launcher mLauncher;
private LauncherLayoutListener mLauncherLayoutListener;
private T mActivity;
private LayoutListener mLayoutListener;
private RecentsView mRecentsView;
private QuickScrubController mQuickScrubController;
@@ -232,12 +195,16 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
private Matrix mTmpMatrix = new Matrix();
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
private final MetricsLogger mMetricsLogger = new MetricsLogger();
WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs) {
WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs,
ActivityControlHelper<T> controller) {
mContext = context;
mRunningTaskId = runningTaskInfo.id;
mTouchTimeMs = touchTimeMs;
mActivityControlHelper = controller;
mActivityInitListener = mActivityControlHelper
.createActivityInitListener(this::onActivityInit);
// Register the input consumer on the UI thread, to ensure that it runs after any pending
// unregister calls
mMainExecutor.execute(mInputConsumer::registerInputConsumer);
@@ -283,13 +250,10 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SWITCH,
this::onQuickInteractionStart);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SCRUB_START,
this::onQuickInteractionStart);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SWITCH_TO_SCREENSHOT_COMPLETE
| STATE_QUICK_SWITCH, this::switchToFinalAppAfterQuickSwitch);
this::onQuickScrubStart);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SCRUB_START
| STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SWITCH_TO_SCREENSHOT_COMPLETE
| STATE_QUICK_SCRUB_END, this::switchToFinalAppAfterQuickScrub);
}
@@ -310,7 +274,8 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
mSourceStackBounds.height() - mSourceInsets.bottom);
Rect tempRect = new Rect();
RecentsView.getPageRect(dp, mContext, tempRect);
mTransitionDragLength = mActivityControlHelper
.getSwipeUpDestinationAndLength(dp, mContext, tempRect);
mTargetRect.set(tempRect);
mTargetRect.offset(mHomeStackBounds.left - mSourceStackBounds.left,
@@ -331,14 +296,15 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
Math.max(mSourceStackBounds.width() - scaledTargetRect.right, 0),
Math.max(mSourceStackBounds.height() - scaledTargetRect.bottom, 0));
mSourceRect.set(scaledTargetRect);
}
Rect targetInsets = dp.getInsets();
if (dp.isVerticalBarLayout()) {
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
mTransitionDragLength = dp.hotseatBarSizePx + dp.hotseatBarSidePaddingPx + hotseatInset;
} else {
mTransitionDragLength = dp.heightPx - tempRect.bottom;
}
public int getTransitionLength() {
return mTransitionDragLength;
}
public RectF getTargetRect(Point outWindowSize) {
outWindowSize.set(mDp.widthPx, mDp.heightPx);
return mInitialTargetRect;
}
private long getFadeInDuration() {
@@ -353,40 +319,39 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
}
@Override
protected boolean init(final Launcher launcher, boolean alreadyOnHome) {
if (launcher == mLauncher) {
public void initWhenReady() {
mActivityInitListener.register();
}
private boolean onActivityInit(final T activity, Boolean alreadyOnHome) {
if (mActivity == activity) {
return true;
}
if (mLauncher != null) {
if (mActivity != null) {
// The launcher may have been recreated as a result of device rotation.
int oldState = mStateCallback.getState() & ~LAUNCHER_UI_STATES;
initStateCallbacks();
mStateCallback.setState(oldState);
mLauncherLayoutListener.setHandler(null);
mLayoutListener.setHandler(null);
}
mWasLauncherAlreadyVisible = alreadyOnHome;
mLauncher = launcher;
mActivity = activity;
// For the duration of the gesture, lock the screen orientation to ensure that we do not
// rotate mid-quickscrub
mLauncher.getRotationHelper().setStateHandlerRequest(REQUEST_LOCK);
mRecentsView = mLauncher.getOverviewPanel();
mRecentsView = activity.getOverviewPanel();
mQuickScrubController = mRecentsView.getQuickScrubController();
mLauncherLayoutListener = new LauncherLayoutListener(mLauncher);
mLayoutListener = mActivityControlHelper.createLayoutListener(mActivity);
mStateCallback.setState(STATE_LAUNCHER_PRESENT);
if (alreadyOnHome) {
onLauncherStart(launcher);
onLauncherStart(activity);
} else {
launcher.setOnStartCallback(this::onLauncherStart);
activity.setOnStartCallback(this::onLauncherStart);
}
return true;
}
private void onLauncherStart(final Launcher launcher) {
if (mLauncher != launcher) {
private void onLauncherStart(final T activity) {
if (mActivity != activity) {
return;
}
if ((mStateCallback.getState() & STATE_HANDLER_INVALIDATED) != 0) {
@@ -394,31 +359,20 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
mStateCallback.setState(STATE_LAUNCHER_STARTED);
LauncherState startState = mLauncher.getStateManager().getState();
if (startState.disableRestore) {
startState = mLauncher.getStateManager().getRestState();
}
mLauncher.getStateManager().setRestState(startState);
mActivityControlHelper.prepareRecentsUI(mActivity, mWasLauncherAlreadyVisible);
AbstractFloatingView.closeAllOpenViews(activity, mWasLauncherAlreadyVisible);
AbstractFloatingView.closeAllOpenViews(mLauncher, mWasLauncherAlreadyVisible);
if (mWasLauncherAlreadyVisible && !mLauncher.getAppTransitionManager().isAnimating()) {
DeviceProfile dp = mLauncher.getDeviceProfile();
long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
mLauncherTransitionController = mLauncher.getStateManager()
.createAnimationToNewWorkspace(OVERVIEW, accuracy);
if (mWasLauncherAlreadyVisible) {
mLauncherTransitionController = mActivityControlHelper
.createControllerForVisibleActivity(activity);
mLauncherTransitionController.dispatchOnStart();
mLauncherTransitionController.setPlayFraction(mCurrentShift.value);
mStateCallback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_DRAWN);
} else {
TraceHelper.beginSection("WTS-init");
mLauncher.getStateManager().goToState(OVERVIEW, false);
TraceHelper.partitionSection("WTS-init", "State changed");
// TODO: Implement a better animation for fading in
View rootView = mLauncher.getRootView();
View rootView = activity.getRootView();
rootView.setAlpha(0);
rootView.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
@@ -427,21 +381,18 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
TraceHelper.endSection("WTS-init", "Launcher frame is drawn");
rootView.post(() ->
rootView.getViewTreeObserver().removeOnDrawListener(this));
if (launcher != mLauncher) {
if (activity != mActivity) {
return;
}
mStateCallback.setState(STATE_LAUNCHER_DRAWN);
}
});
// Optimization, hide the all apps view to prevent layout while initializing
mLauncher.getAppsView().setVisibility(View.GONE);
}
mRecentsView.showTask(mRunningTaskId);
mRecentsView.setFirstTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
mLauncherLayoutListener.open();
mLayoutListener.open();
}
public void setLauncherOnDrawCallback(Runnable callback) {
@@ -449,7 +400,7 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
private void launcherFrameDrawn() {
View rootView = mLauncher.getRootView();
View rootView = mActivity.getRootView();
if (rootView.getAlpha() < 1) {
if (mGestureStarted) {
final MultiStateCallback callback = mStateCallback;
@@ -468,19 +419,12 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
private void initializeLauncherAnimationController() {
mLauncherLayoutListener.setHandler(this);
mLayoutListener.setHandler(this);
onLauncherLayoutChanged();
final long transitionDelay = mLauncherFrameDrawnTime - mTouchTimeMs;
// Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
// "Recents" activity for app transition tests for the app-to-recents case.
final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
builder.setPackageName("com.android.systemui");
builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
"com.android.systemui.recents.RecentsActivity");
builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
transitionDelay);
mMetricsLogger.write(builder);
SysuiEventLogger.writeDummyRecentsTransition(transitionDelay);
if (LatencyTrackerCompat.isEnabled(mContext)) {
LatencyTrackerCompat.logToggleRecents((int) transitionDelay);
}
@@ -491,23 +435,16 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
throw new IllegalArgumentException(
"Can't change interaction type from " + mInteractionType);
}
if (!isInteractionQuick(interactionType)) {
if (interactionType != INTERACTION_QUICK_SCRUB) {
throw new IllegalArgumentException(
"Can't change interaction type to " + interactionType);
}
mInteractionType = interactionType;
setStateOnUiThread(interactionType == INTERACTION_QUICK_SWITCH
? STATE_QUICK_SWITCH : STATE_QUICK_SCRUB_START);
setStateOnUiThread(STATE_QUICK_SCRUB_START);
// Start the window animation without waiting for launcher.
animateToProgress(1f, QUICK_SWITCH_START_DURATION);
}
private void onQuickInteractionStart() {
mLauncher.getStateManager().goToState(FAST_OVERVIEW,
mWasLauncherAlreadyVisible || mGestureStarted);
mQuickScrubController.onQuickScrubStart(false);
animateToProgress(1f, QUICK_SCRUB_START_DURATION);
}
@WorkerThread
@@ -520,32 +457,14 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
/**
* Called by {@link #mLauncherLayoutListener} when launcher layout changes
* Called by {@link #mLayoutListener} when launcher layout changes
*/
public void onLauncherLayoutChanged() {
initTransitionEndpoints(mLauncher.getDeviceProfile());
initTransitionEndpoints(mActivity.getDeviceProfile());
if (!mWasLauncherAlreadyVisible) {
float startProgress;
AllAppsTransitionController controller = mLauncher.getAllAppsController();
if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
startProgress = 1;
} else {
float scrollRange = Math.max(controller.getShiftRange(), 1);
startProgress = (mTransitionDragLength / scrollRange) + 1;
}
AnimatorSet anim = new AnimatorSet();
ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(controller, ALL_APPS_PROGRESS,
startProgress, OVERVIEW.getVerticalProgress(mLauncher));
shiftAnim.setInterpolator(LINEAR);
anim.play(shiftAnim);
// TODO: Link this animation to state animation, so that it is cancelled
// automatically on state change
anim.setDuration(mTransitionDragLength * 2);
mLauncherTransitionController =
AnimatorPlaybackController.wrap(anim, mTransitionDragLength * 2);
mLauncherTransitionController = mActivityControlHelper
.createControllerForHiddenActivity(mActivity, mTransitionDragLength);
mLauncherTransitionController.setPlayFraction(mCurrentShift.value);
}
}
@@ -558,7 +477,12 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
if (mRecentsAnimationWrapper.controller != null) {
RectF currentRect;
synchronized (mTargetRect) {
currentRect = mRectFEvaluator.evaluate(shift, mSourceRect, mTargetRect);
Interpolator interpolator = mInteractionType == INTERACTION_QUICK_SCRUB
? ACCEL_2 : LINEAR;
float interpolated = interpolator.getInterpolation(shift);
currentRect = mRectFEvaluator.evaluate(interpolated, mSourceRect, mTargetRect);
// Stay lined up with the center of the target, since it moves for quick scrub.
currentRect.offset(mTargetRect.centerX() - currentRect.centerX(), 0);
}
mClipRect.left = (int) (mSourceWindowClipInsets.left * shift);
@@ -598,13 +522,18 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
View firstTask = mRecentsView.getPageAt(0);
int scrollForFirstTask = mRecentsView.getScrollForPage(0);
int offsetFromFirstTask = (scrollForFirstTask - mRecentsView.getScrollX());
if (offsetFromFirstTask != 0) {
synchronized (mTargetRect) {
mTargetRect.set(mInitialTargetRect);
Utilities.scaleRectFAboutCenter(mTargetRect, firstTask.getScaleX());
float offsetX = offsetFromFirstTask + firstTask.getTranslationX();
mTargetRect.offset(offsetX, 0);
}
synchronized (mTargetRect) {
mTargetRect.set(mInitialTargetRect);
Utilities.scaleRectFAboutCenter(mTargetRect, firstTask.getScaleX());
float offsetX = offsetFromFirstTask + firstTask.getTranslationX();
float offsetY = mRecentsView.getTranslationY();
mTargetRect.offset(offsetX, offsetY);
}
if (mRecentsAnimationWrapper.controller != null) {
// TODO: This logic is spartanic!
mRecentsAnimationWrapper.controller.setAnimationTargetsBehindSystemBars(
shift < 0.12f);
}
};
if (Looper.getMainLooper() == Looper.myLooper()) {
@@ -652,14 +581,13 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
}
}
mRecentsAnimationWrapper.setController(controller, apps);
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
}
public void onRecentsAnimationCanceled() {
mRecentsAnimationWrapper.setController(null, null);
clearReference();
mActivityInitListener.unregister();
setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
}
@@ -675,9 +603,10 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
* on both background and UI threads
*/
private void notifyGestureStarted() {
final Launcher curLauncher = mLauncher;
if (curLauncher != null) {
curLauncher.onQuickstepGestureStarted(mWasLauncherAlreadyVisible);
final T curActivity = mActivity;
if (curActivity != null) {
mActivityControlHelper.onQuickstepGestureStarted(
curActivity, mWasLauncherAlreadyVisible);
}
}
@@ -761,25 +690,20 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
mGestureEndCallback.run();
}
clearReference();
mActivityInitListener.unregister();
mInputConsumer.unregisterInputConsumer();
}
private void invalidateHandlerWithLauncher() {
mLauncherTransitionController = null;
mLauncherLayoutListener.setHandler(null);
mLauncherLayoutListener.close(false);
// Restore the requested orientation to the user preference after the gesture has ended
mLauncher.getRotationHelper().setStateHandlerRequest(REQUEST_NONE);
mLayoutListener.finish();
mRecentsView.setFirstTaskIconScaledDown(false /* isScaledDown */, false /* animate */);
}
private void resetStateForAnimationCancel() {
LauncherState startState = mLauncher.getStateManager().getRestState();
boolean animate = mWasLauncherAlreadyVisible || mGestureStarted;
mLauncher.getStateManager().goToState(startState, animate);
boolean wasVisible = mWasLauncherAlreadyVisible || mGestureStarted;
mActivityControlHelper.onTransitionCancelled(mActivity, wasVisible);
}
public void layoutListenerClosed() {
@@ -808,17 +732,8 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
if (taskView != null) {
// Defer finishing the animation until the next launcher frame with the
// new thumbnail
ViewOnDrawExecutor executor = new ViewOnDrawExecutor() {
@Override
public void onViewDetachedFromWindow(View v) {
if (!isCompleted()) {
runAllTasks();
}
}
};
executor.attachTo(mLauncher, taskView,
false /* waitForLoadAnimation */);
executor.execute(finishTransitionRunnable);
mActivityControlHelper.executeOnNextDraw(mActivity, taskView,
finishTransitionRunnable);
finishTransitionPosted = true;
}
}
@@ -834,8 +749,7 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
private void setupLauncherUiAfterSwipeUpAnimation() {
// Re apply state in case we did something funky during the transition.
mLauncher.getStateManager().reapplyState();
mActivityControlHelper.onSwipeUpComplete(mActivity);
// Animate the first icon.
mRecentsView.setFirstTaskIconScaledDown(false /* isScaledDown */, true /* animate */);
@@ -843,21 +757,13 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
reset();
}
public void onQuickScrubEnd() {
setStateOnUiThread(STATE_QUICK_SCRUB_END);
private void onQuickScrubStart() {
mActivityControlHelper.onQuickInteractionStart(mActivity, mWasLauncherAlreadyVisible);
mQuickScrubController.onQuickScrubStart(false);
}
private void switchToFinalAppAfterQuickSwitch() {
mQuickScrubController.onQuickSwitch();
}
private void switchToFinalAppAfterQuickScrub() {
mQuickScrubController.onQuickScrubEnd();
// Normally this is handled in reset(), but since we are still scrubbing after the
// transition into recents, we need to defer the handler invalidation for quick scrub until
// after the gesture ends
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
private void onFinishedTransitionToQuickScrub() {
mQuickScrubController.onFinishedTransitionToQuickScrub();
}
public void onQuickScrubProgress(float progress) {
@@ -870,6 +776,19 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
mQuickScrubController.onQuickScrubProgress(progress);
}
public void onQuickScrubEnd() {
setStateOnUiThread(STATE_QUICK_SCRUB_END);
}
private void switchToFinalAppAfterQuickScrub() {
mQuickScrubController.onQuickScrubEnd();
// Normally this is handled in reset(), but since we are still scrubbing after the
// transition into recents, we need to defer the handler invalidation for quick scrub until
// after the gesture ends
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
}
private void debugNewState(int stateFlag) {
if (!DEBUG_STATES) {
return;
@@ -889,4 +808,8 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
Log.d(TAG, "[" + System.identityHashCode(this) + "] Adding " + stateFlagStr + " to "
+ currentStateStr);
}
public void setGestureEndCallback(Runnable gestureEndCallback) {
mGestureEndCallback = gestureEndCallback;
}
}
@@ -0,0 +1,47 @@
/*
* 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.util;
import android.metrics.LogMaker;
import android.util.EventLog;
/**
* Utility class for writing logs on behalf of systemUI
*/
public class SysuiEventLogger {
/** 524292 sysui_multi_action (content|4) */
public static final int SYSUI_MULTI_ACTION = 524292;
private static void write(LogMaker content) {
if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
content.setType(4/*MetricsEvent.TYPE_ACTION*/);
}
EventLog.writeEvent(SYSUI_MULTI_ACTION, content.serialize());
}
public static void writeDummyRecentsTransition(long transitionDelay) {
// Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
// "Recents" activity for app transition tests for the app-to-recents case.
final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
builder.setPackageName("com.android.systemui");
builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
"com.android.systemui.recents.RecentsActivity");
builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
transitionDelay);
write(builder);
}
}
@@ -13,7 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.quickstep;
package com.android.quickstep.views;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
import android.graphics.Rect;
import android.view.MotionEvent;
@@ -21,11 +23,14 @@ import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.quickstep.ActivityControlHelper.LayoutListener;
import com.android.quickstep.WindowTransformSwipeHandler;
/**
* Floating view which shows the task snapshot allowing it to be dragged and placed.
*/
public class LauncherLayoutListener extends AbstractFloatingView implements Insettable {
public class LauncherLayoutListener extends AbstractFloatingView
implements Insettable, LayoutListener {
private final Launcher mLauncher;
private WindowTransformSwipeHandler mHandler;
@@ -36,6 +41,7 @@ public class LauncherLayoutListener extends AbstractFloatingView implements Inse
setVisibility(INVISIBLE);
}
@Override
public void setHandler(WindowTransformSwipeHandler handler) {
mHandler = handler;
}
@@ -65,6 +71,7 @@ public class LauncherLayoutListener extends AbstractFloatingView implements Inse
}
}
@Override
public void open() {
if (!mIsOpen) {
mLauncher.getDragLayer().addView(this);
@@ -86,4 +93,11 @@ public class LauncherLayoutListener extends AbstractFloatingView implements Inse
protected boolean isOfType(int type) {
return (type & TYPE_QUICKSTEP_PREVIEW) != 0;
}
@Override
public void finish() {
setHandler(null);
close(false);
mLauncher.getRotationHelper().setStateHandlerRequest(REQUEST_NONE);
}
}
@@ -17,20 +17,12 @@ package com.android.quickstep.views;
import static com.android.launcher3.LauncherState.NORMAL;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.widget.FrameLayout;
import com.android.launcher3.DeviceProfile;
@@ -41,13 +33,40 @@ import com.android.launcher3.R;
/**
* {@link RecentsView} used in Launcher activity
*/
@TargetApi(Build.VERSION_CODES.O)
public class LauncherRecentsView extends RecentsView<Launcher> implements Insettable {
private Bitmap mScrim;
private Paint mFadePaint;
private Shader mFadeShader;
private Matrix mFadeMatrix;
private boolean mScrimOnLeft;
public static final FloatProperty<LauncherRecentsView> TRANSLATION_X_FACTOR =
new FloatProperty<LauncherRecentsView>("translationXFactor") {
@Override
public void setValue(LauncherRecentsView view, float v) {
view.setTranslationXFactor(v);
}
@Override
public Float get(LauncherRecentsView view) {
return view.mTranslationXFactor;
}
};
public static final FloatProperty<LauncherRecentsView> TRANSLATION_Y_FACTOR =
new FloatProperty<LauncherRecentsView>("translationYFactor") {
@Override
public void setValue(LauncherRecentsView view, float v) {
view.setTranslationYFactor(v);
}
@Override
public Float get(LauncherRecentsView view) {
return view.mTranslationYFactor;
}
};
private float mTranslationXFactor;
private float mTranslationYFactor;
private Rect mPagePadding = new Rect();
public LauncherRecentsView(Context context) {
this(context, null);
@@ -59,6 +78,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements Insett
public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setContentAlpha(0);
}
@Override
@@ -71,64 +91,39 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements Insett
setLayoutParams(lp);
setPadding(padding.left, padding.top, padding.right, 0);
if (dp.isVerticalBarLayout()) {
boolean wasScrimOnLeft = mScrimOnLeft;
mScrimOnLeft = dp.isSeascape();
if (mScrim == null || wasScrimOnLeft != mScrimOnLeft) {
Drawable scrim = getContext().getDrawable(mScrimOnLeft
? R.drawable.recents_horizontal_scrim_left
: R.drawable.recents_horizontal_scrim_right);
if (scrim instanceof BitmapDrawable) {
mScrim = ((BitmapDrawable) scrim).getBitmap();
mFadePaint = new Paint();
mFadePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
mFadeShader = new BitmapShader(mScrim, TileMode.CLAMP, TileMode.REPEAT);
mFadeMatrix = new Matrix();
} else {
mScrim = null;
}
}
} else {
mScrim = null;
mFadePaint = null;
mFadeShader = null;
mFadeMatrix = null;
}
}
@Override
public void draw(Canvas canvas) {
if (mScrim == null) {
super.draw(canvas);
return;
}
final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
int length = mScrim.getWidth();
int height = getHeight();
int saveCount = canvas.getSaveCount();
int scrimLeft;
if (mScrimOnLeft) {
scrimLeft = getScrollX();
} else {
scrimLeft = getScrollX() + getWidth() - length;
}
canvas.saveLayer(scrimLeft, 0, scrimLeft + length, height, null, flags);
super.draw(canvas);
mFadeMatrix.setTranslate(scrimLeft, 0);
mFadeShader.setLocalMatrix(mFadeMatrix);
mFadePaint.setShader(mFadeShader);
canvas.drawRect(scrimLeft, 0, scrimLeft + length, height, mFadePaint);
canvas.restoreToCount(saveCount);
mPagePadding.set(padding);
mPagePadding.top += getResources().getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
}
@Override
protected void onAllTasksRemoved() {
mActivity.getStateManager().goToState(NORMAL);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int width = right - left;
setTranslationX(mTranslationXFactor * (mIsRtl ? -width : width));
setTranslationYFactor(mTranslationYFactor);
}
public void setTranslationXFactor(float translationFactor) {
mTranslationXFactor = translationFactor;
setTranslationX(translationFactor * (mIsRtl ? -getWidth() : getWidth()));
}
public float getTranslationXFactor() {
return mTranslationXFactor;
}
public void setTranslationYFactor(float translationFactor) {
mTranslationYFactor = translationFactor;
setTranslationY(mTranslationYFactor * (mPagePadding.bottom - mPagePadding.top));
}
public float getTranslationYFactor() {
return mTranslationYFactor;
}
}
@@ -18,6 +18,7 @@ package com.android.quickstep.views;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.animation.AnimatorSet;
@@ -30,8 +31,11 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Rect;
import android.os.Build;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.SparseBooleanArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -40,6 +44,7 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.config.FeatureFlags;
import com.android.quickstep.PendingAnimation;
import com.android.quickstep.QuickScrubController;
@@ -62,7 +67,23 @@ import java.util.ArrayList;
public abstract class RecentsView<T extends BaseActivity>
extends PagedView implements OnSharedPreferenceChangeListener {
public static final FloatProperty<RecentsView> CONTENT_ALPHA =
new FloatProperty<RecentsView>("contentAlpha") {
@Override
public void setValue(RecentsView recentsView, float v) {
recentsView.setContentAlpha(v);
}
@Override
public Float get(RecentsView recentsView) {
return recentsView.mContentAlpha;
}
};
private static final String PREF_FLIP_RECENTS = "pref_flip_recents";
private static final int DISMISS_TASK_DURATION = 300;
private static final Rect sTempStableInsets = new Rect();
@@ -104,6 +125,11 @@ public abstract class RecentsView<T extends BaseActivity>
private PendingAnimation mPendingAnimation;
private float mContentAlpha = 1;
// Keeps track of task views whose visual state should not be reset
private ArraySet<TaskView> mIgnoreResetTaskViews = new ArraySet<>();
public RecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
@@ -261,7 +287,10 @@ public abstract class RecentsView<T extends BaseActivity>
public void resetTaskVisuals() {
for (int i = getChildCount() - 1; i >= 0; i--) {
((TaskView) getChildAt(i)).resetVisualProperties();
TaskView taskView = (TaskView) getChildAt(i);
if (!mIgnoreResetTaskViews.contains(taskView)) {
taskView.resetVisualProperties();
}
}
updateCurveProperties();
@@ -294,12 +323,10 @@ public abstract class RecentsView<T extends BaseActivity>
float overviewHeight, overviewWidth;
if (profile.isVerticalBarLayout()) {
float scrimLength = context.getResources()
.getDimension(R.dimen.recents_page_fade_length);
float maxPadding = Math.max(padding.left, padding.right);
// Use the same padding on both sides for symmetry.
float availableWidth = taskWidth - 2 * Math.max(maxPadding, scrimLength);
float availableWidth = taskWidth - 2 * maxPadding;
float availableHeight = profile.availableHeightPx - padding.top - padding.bottom
- sTempStableInsets.top;
float scaledRatio = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
@@ -512,7 +539,16 @@ public abstract class RecentsView<T extends BaseActivity>
public float linearInterpolation;
}
public PendingAnimation createTaskDismissAnimation(TaskView taskView, long duration) {
public void addIgnoreResetTask(TaskView taskView) {
mIgnoreResetTaskViews.add(taskView);
}
public void removeIgnoreResetTask(TaskView taskView) {
mIgnoreResetTaskViews.remove(taskView);
}
public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView,
boolean removeTask, long duration) {
if (FeatureFlags.IS_DOGFOOD_BUILD && mPendingAnimation != null) {
throw new IllegalStateException("Another pending animation is still running");
}
@@ -543,9 +579,11 @@ public abstract class RecentsView<T extends BaseActivity>
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child == taskView) {
addAnim(ObjectAnimator.ofFloat(taskView, ALPHA, 0), duration, ACCEL_2, anim);
addAnim(ObjectAnimator.ofFloat(taskView, TRANSLATION_Y, -taskView.getHeight()),
duration, LINEAR, anim);
if (animateTaskView) {
addAnim(ObjectAnimator.ofFloat(taskView, ALPHA, 0), duration, ACCEL_2, anim);
addAnim(ObjectAnimator.ofFloat(taskView, TRANSLATION_Y, -taskView.getHeight()),
duration, LINEAR, anim);
}
} else {
int scrollDiff = newScroll[i] - oldScroll[i] + maxScrollDiff;
if (scrollDiff != 0) {
@@ -563,12 +601,16 @@ public abstract class RecentsView<T extends BaseActivity>
}
// Add a tiny bit of translation Z, so that it draws on top of other views
taskView.setTranslationZ(0.1f);
if (animateTaskView) {
taskView.setTranslationZ(0.1f);
}
mPendingAnimation = pendingAnimation;
mPendingAnimation.addEndListener((isSuccess) -> {
if (isSuccess) {
ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
if (removeTask) {
ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
}
removeView(taskView);
if (getChildCount() == 0) {
onAllTasksRemoved();
@@ -585,4 +627,85 @@ public abstract class RecentsView<T extends BaseActivity>
anim.setDuration(duration).setInterpolator(interpolator);
set.play(anim);
}
private void snapToPageRelative(int delta) {
snapToPage((getNextPage() + getPageCount() + delta) % getPageCount());
}
@Override
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
if (isVisible && !isFocused()) {
// Having focus, even in touch mode, keeps us from losing [Alt+]Tab by preventing
// switching to keyboard mode.
requestFocus();
}
}
public void dismissTask(TaskView taskView, boolean animateTaskView, boolean removeTask) {
PendingAnimation pendingAnim = createTaskDismissAnimation(taskView, animateTaskView,
removeTask, DISMISS_TASK_DURATION);
AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(
pendingAnim.anim, DISMISS_TASK_DURATION);
controller.dispatchOnStart();
controller.setEndAction(() -> pendingAnim.finish(true));
controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
controller.start();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_TAB:
snapToPageRelative(event.isShiftPressed() ? -1 : 1);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
snapToPageRelative(mIsRtl ? -1 : 1);
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
snapToPageRelative(mIsRtl ? 1 : -1);
return true;
case KeyEvent.KEYCODE_DEL:
case KeyEvent.KEYCODE_FORWARD_DEL:
dismissTask((TaskView) getChildAt(getNextPage()), true /*animateTaskView*/,
true /*removeTask*/);
return true;
case KeyEvent.KEYCODE_NUMPAD_DOT:
if (event.isAltPressed()) {
// Numpad DEL pressed while holding Alt.
dismissTask((TaskView) getChildAt(getNextPage()), true /*animateTaskView*/,
true /*removeTask*/);
return true;
}
}
}
return super.dispatchKeyEvent(event);
}
public void snapToTaskAfterNext() {
snapToPageRelative(1);
}
public void launchNextTask() {
final TaskView nextTask = (TaskView) getChildAt(getNextPage());
nextTask.launchTask(true);
}
public void setContentAlpha(float alpha) {
if (mContentAlpha == alpha) {
return;
}
mContentAlpha = alpha;
for (int i = getChildCount() - 1; i >= 0; i--) {
getChildAt(i).setAlpha(alpha);
}
setVisibility(alpha > 0 ? VISIBLE : GONE);
}
@Override
public void onViewAdded(View child) {
super.onViewAdded(child);
child.setAlpha(mContentAlpha);
}
}
@@ -32,14 +32,14 @@ import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.TextView;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.TaskSystemShortcut;
import com.android.quickstep.TaskUtils;
@@ -60,7 +60,7 @@ public class TaskMenuView extends AbstractFloatingView {
private static final long OPEN_CLOSE_DURATION = 220;
private Launcher mLauncher;
private BaseDraggingActivity mActivity;
private TextView mTaskIconAndName;
private AnimatorSet mOpenCloseAnimator;
private TaskView mTaskView;
@@ -72,7 +72,7 @@ public class TaskMenuView extends AbstractFloatingView {
public TaskMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLauncher = Launcher.getLauncher(context);
mActivity = BaseDraggingActivity.fromContext(context);
setClipToOutline(true);
setOutlineProvider(new ViewOutlineProvider() {
@Override
@@ -92,7 +92,7 @@ public class TaskMenuView extends AbstractFloatingView {
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
DragLayer dl = mLauncher.getDragLayer();
BaseDragLayer dl = mActivity.getDragLayer();
if (!dl.isEventOverView(this, ev)) {
// TODO: log this once we have a new container type for it?
close(true);
@@ -122,9 +122,9 @@ public class TaskMenuView extends AbstractFloatingView {
}
public static boolean showForTask(TaskView taskView) {
Launcher launcher = Launcher.getLauncher(taskView.getContext());
final TaskMenuView taskMenuView = (TaskMenuView) launcher.getLayoutInflater().inflate(
R.layout.task_menu, launcher.getDragLayer(), false);
BaseDraggingActivity activity = BaseDraggingActivity.fromContext(taskView.getContext());
final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate(
R.layout.task_menu, activity.getDragLayer(), false);
return taskMenuView.populateAndShowForTask(taskView);
}
@@ -132,7 +132,7 @@ public class TaskMenuView extends AbstractFloatingView {
if (isAttachedToWindow()) {
return false;
}
mLauncher.getDragLayer().addView(this);
mActivity.getDragLayer().addView(this);
mTaskView = taskView;
addMenuOptions(mTaskView);
orientAroundTaskView(mTaskView);
@@ -145,11 +145,11 @@ public class TaskMenuView extends AbstractFloatingView {
int iconSize = getResources().getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
icon.setBounds(0, 0, iconSize, iconSize);
mTaskIconAndName.setCompoundDrawables(null, icon, null, null);
mTaskIconAndName.setText(TaskUtils.getTitle(mLauncher, taskView.getTask()));
mTaskIconAndName.setText(TaskUtils.getTitle(getContext(), taskView.getTask()));
mTaskIconAndName.setOnClickListener(v -> close(true));
for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
OnClickListener onClickListener = menuOption.getOnClickListener(mLauncher, taskView);
OnClickListener onClickListener = menuOption.getOnClickListener(mActivity, taskView);
if (onClickListener != null) {
addMenuOption(menuOption, onClickListener);
}
@@ -157,7 +157,7 @@ public class TaskMenuView extends AbstractFloatingView {
}
private void addMenuOption(TaskSystemShortcut menuOption, OnClickListener onClickListener) {
DeepShortcutView menuOptionView = (DeepShortcutView) mLauncher.getLayoutInflater().inflate(
DeepShortcutView menuOptionView = (DeepShortcutView) mActivity.getLayoutInflater().inflate(
R.layout.system_shortcut, this, false);
menuOptionView.getIconView().setBackgroundResource(menuOption.iconResId);
menuOptionView.getBubbleText().setText(menuOption.labelResId);
@@ -167,8 +167,8 @@ public class TaskMenuView extends AbstractFloatingView {
private void orientAroundTaskView(TaskView taskView) {
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
mLauncher.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
Rect insets = mLauncher.getDragLayer().getInsets();
mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
Rect insets = mActivity.getDragLayer().getInsets();
int x = sTempRect.left + (sTempRect.width() - getMeasuredWidth()) / 2 - insets.left;
setX(Utilities.isRtl(getResources()) ? -x : x);
setY(sTempRect.top - mTaskIconAndName.getPaddingTop() - insets.top);
@@ -211,7 +211,7 @@ public class TaskMenuView extends AbstractFloatingView {
private void closeComplete() {
mIsOpen = false;
mLauncher.getDragLayer().removeView(this);
mActivity.getDragLayer().removeView(this);
}
private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() {
@@ -28,7 +28,7 @@ import android.view.ViewOutlineProvider;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.launcher3.Launcher;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
import com.android.quickstep.views.RecentsView.PageCallbacks;
import com.android.quickstep.views.RecentsView.ScrollState;
@@ -54,6 +54,11 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
*/
private static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
/**
* How much to scale down pages near the edge of the screen.
*/
private static final float EDGE_SCALE_DOWN_FACTOR = 0.03f;
private static final long SCALE_ICON_DURATION = 120;
private Task mTask;
@@ -91,6 +96,7 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
mTask = task;
mSnapshotView.bind();
task.addCallback(this);
setContentDescription(task.titleDescription);
}
public Task getTask() {
@@ -110,7 +116,8 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
if (mTask != null) {
final ActivityOptions opts;
if (animate) {
opts = Launcher.getLauncher(getContext()).getActivityLaunchOptions(this, false);
opts = BaseDraggingActivity.fromContext(getContext())
.getActivityLaunchOptions(this, false);
} else {
opts = ActivityOptions.makeCustomAnimation(getContext(), 0, 0);
}
@@ -164,6 +171,16 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
CURVE_INTERPOLATOR.getInterpolation(scrollState.linearInterpolation);
mSnapshotView.setDimAlpha(1 - curveInterpolation * MAX_PAGE_SCRIM_ALPHA);
float scale = 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
setScaleX(scale);
setScaleY(scale);
}
@Override
public boolean hasOverlappingRendering() {
// TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
return false;
}
private static final class TaskOutlineProvider extends ViewOutlineProvider {
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="2dp"
android:width="16dp"
android:viewportHeight="2.0"
android:viewportWidth="16.0">
<path
android:fillColor="@android:color/white"
android:pathData="M1,0h14c0.55,0,1,0.45,1,1s-0.45,1-1,1H1C0.45,2,0,1.55,0,1S0.45,0,1,0z"/>
</vector>
+3 -3
View File
@@ -21,8 +21,8 @@
android:id="@+id/fast_scroller_popup"
style="@style/FastScrollerPopup"
android:layout_alignParentEnd="true"
android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
android:layout_marginEnd="@dimen/fastscroll_popup_margin"
android:layout_marginTop="@dimen/all_apps_search_bar_field_height_and_margin" />
<com.android.launcher3.views.RecyclerViewFastScroller
android:id="@+id/fast_scroller"
@@ -30,8 +30,8 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_end_margin"
android:layout_marginTop="@dimen/all_apps_search_bar_field_height_and_margin"
launcher:canThumbDetach="true" />
</merge>
+3 -3
View File
@@ -18,10 +18,10 @@
android:id="@+id/all_apps_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/search_container_all_apps"
android:layout_marginTop="@dimen/all_apps_search_bar_field_height_and_margin"
android:clipToPadding="false"
android:paddingTop="@dimen/all_apps_header_top_padding"
android:orientation="vertical" >
android:orientation="vertical"
android:paddingTop="@dimen/all_apps_header_top_padding" >
<com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
android:id="@+id/tabs"
+1 -1
View File
@@ -19,7 +19,7 @@
android:id="@+id/apps_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/search_container_all_apps"
android:layout_marginTop="@dimen/all_apps_search_bar_field_height_and_margin"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:focusable="true" />
+1 -2
View File
@@ -20,9 +20,8 @@
android:id="@+id/all_apps_tabs_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/search_container_all_apps"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="@dimen/all_apps_header_tab_height"
android:layout_marginTop="@dimen/all_apps_tabs_top_margin"
android:clipChildren="true"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
+10
View File
@@ -17,6 +17,16 @@
android:theme="@style/HomeScreenElementTheme"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/drag_indicator"
android:layout_width="@dimen/hotseat_drag_indicator_height"
android:layout_height="@dimen/hotseat_drag_indicator_height"
android:src="@drawable/ic_drag_indicator"
android:tint="?attr/workspaceTextColor"
android:scaleType="centerInside"
android:layout_gravity="top|center_horizontal"/>
<com.android.launcher3.CellLayout
android:id="@+id/layout"
android:layout_width="wrap_content"
+7 -7
View File
@@ -44,13 +44,6 @@
layout="@layout/overview_panel"
android:visibility="gone" />
<!-- DO NOT CHANGE THE ID -->
<include
android:id="@+id/hotseat"
layout="@layout/hotseat"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
<com.android.launcher3.pageindicators.WorkspacePageIndicator
@@ -69,6 +62,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
<!-- DO NOT CHANGE THE ID -->
<include
android:id="@+id/hotseat"
layout="@layout/hotseat"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.android.launcher3.dragndrop.DragLayer>
</com.android.launcher3.LauncherRootView>
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<com.android.launcher3.views.HighlightableListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@android:color/transparent"
android:clipToPadding="false"
android:drawSelectorOnTop="false"
android:orientation="vertical"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="outsideOverlay" />
-1
View File
@@ -31,7 +31,6 @@
android:layout_height="@dimen/widget_section_height"
android:background="?android:attr/colorPrimary"
android:drawablePadding="@dimen/widget_section_horizontal_padding"
android:ellipsize="end"
android:focusable="true"
android:gravity="start|center_vertical"
android:paddingBottom="@dimen/widget_section_vertical_padding"
@@ -20,6 +20,7 @@
android:layout_gravity="bottom"
android:background="?android:attr/colorAccent"
android:elevation="2dp"
android:focusable="true"
android:orientation="horizontal">
<ImageView
@@ -42,6 +43,7 @@
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:layout_gravity="right"
android:contentDescription="@string/bottom_work_tab_user_education_close_button"
android:src="@drawable/ic_close"/>
<TextView
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Soek meer programme"</string>
<string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Niks meer spasie op die tuisskerm nie."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Geen plek meer in die Gunstelinge-laai nie"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Programmelys"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lys persoonlike programme"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lys werkprogramme"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Tuis"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Verwyder"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deïnstalleer"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Muurpapiere"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home-instellings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gedeaktiveer deur jou administrateur"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Oorsig"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Laat toe dat tuisskerm gedraai word"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer foon gedraai word"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Huidige vertooninstelling laat nie rotasie toe nie"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Kennisgewingkolle"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Aan"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Af"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Kennisgewingtoegang word benodig"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Skakel programkennisgewings vir <xliff:g id="NAME">%1$s</xliff:g> aan om kennisgewingkolle te sien"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Verander instellings"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Wys kennisgewingkolle"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Voeg ikoon by tuisskerm"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Vir nuwe programme"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Verander ikoon se vorm"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"op tuisskerm"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Gebruik stelselverstek"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Vierkant"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Sirkelvierkant"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Skep vouer met: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Vouer geskep"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Skuif na tuisskerm"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Skuif skerm na links"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Skuif skerm na regs"</string>
<string name="screen_moved" msgid="266230079505650577">"Skerm is geskuif"</string>
<string name="action_resize" msgid="1802976324781771067">"Verander grootte"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Vermeerder breedte"</string>
<string name="action_increase_height" msgid="459390020612501122">"Vermeerder hoogte"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Werk"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Werkprofiel"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Kry werkprogramme hier"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Elke werkprogram het \'n kenteken en word deur jou organisasie veilig gehou. Skuif programme na jou tuisskerm toe vir makliker toegang."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Bestuur deur jou organisasie"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Kennisgewings en programme is af"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Maak toe"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Toe"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> sorğusuna uyğun tətbiq tapılmadı"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
<string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Bu Əsas ekranda boş yer yoxdur."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritlər-də yer yoxdur"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Tətbiq siyahısı"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Şəxsi tətbiqlərin siyahısı"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"İş tətbiqlərinin siyahısı"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Əsas səhifə"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Silin"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Sistemdən sil"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Divar kağızları"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home ayarları"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"İcmal"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekranın firlanmağına icazə verin"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon çevrilən zaman"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cari Ekran ayarı fırlatmağa icazə vermir"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Bildiriş nişanı"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktiv"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Deaktiv"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Bildiriş girişi tələb edilir"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Bildiriş Nöqtələrini göstərmək üçün <xliff:g id="NAME">%1$s</xliff:g> bildirişlərini aktiv edin"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Ayarları dəyişin"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Bildiriş nöqtələrini göstərin"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Əsas ekrana ikona əlavə edin"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni tətbiqlər üçün"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"İkona formasını dəyişin"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"Əsas səhifə ekranında"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Sistem defoltu istifadə edin"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Kənarları dairəvi kvadrat"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Qovluq yaradın: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Qovluq yaradıldı"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Əsas ekrana köçürün"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Ekranı sola köçürün"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Ekranı sağa köçürün"</string>
<string name="screen_moved" msgid="266230079505650577">"Ekran köçürülüb"</string>
<string name="action_resize" msgid="1802976324781771067">"Ölçüsünü dəyişin"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Eni artırın"</string>
<string name="action_increase_height" msgid="459390020612501122">"Hündürlüyü artırın"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"İş"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"İş profili"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Burada iş tətbiqləri axtarın"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Hər bir iş tətbiqində təşkilat tərəfindən qorunduğunu göstərən narıncı nişan var. Tətbiqləri daha asan giriş üçün Əsas Səhifə Ekranına köçürün."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Təşkilatınız tərəfindən idarə olunur"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Bildiriş və tətbiqlər deaktivdir"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Bağlayın"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Bağlıdır"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"Известия"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Премахване"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Деинсталиране"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Настройки за Google Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Деактивирано от администратора ви"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Общ преглед"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешаване на завъртането на началния екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"При завъртане на телефона"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Текущата настройка на екрана не разрешава завъртане"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Точки за известия"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Включено"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Изключено"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Показване на точките за известия"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавяне на икона към началния екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови приложения"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Промяна на формата на иконите"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"на началния екран"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Използване на стандартната системна настройка"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Комбинация от кръг и квадрат"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Създаване на папка с елемента „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
<string name="folder_created" msgid="6409794597405184510">"Папката е създадена"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Преместване към началния екран"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Преместване на екрана наляво"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Преместване на екрана надясно"</string>
<string name="screen_moved" msgid="266230079505650577">"Екранът е преместен"</string>
<string name="action_resize" msgid="1802976324781771067">"Преоразмеряване"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Увеличаване на ширината"</string>
<string name="action_increase_height" msgid="459390020612501122">"Увеличаване на височината"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Служебни"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Служебен потребителски профил"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Тук можете да намерите служебните приложения"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Всяко служебно приложение има значка и организацията ви се грижи за сигурността му. За по-лесен достъп преместете приложенията на началния си екран."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Управлява се от организацията ви"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Известията и приложенията са изключени"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Затваряне"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Затворено"</string>
</resources>
+13 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"বিজ্ঞপ্তি"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"সরান"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"আনইনস্টল করুন"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"ওয়ালপেপারগুলি"</string>
<string name="settings_button_text" msgid="8873672322605444408">"হোম এর সেটিংস"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"এক নজরে"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"হোমস্ক্রীন ঘোরানোর অনুমতি দিন"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"যখন ফোনটি ঘোরানো হয়"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"বর্তমান প্রদর্শনের সেটিংস ঘোরানোর মঞ্জুরি দেয় না"</string>
<string name="icon_badging_title" msgid="874121399231955394">"বিজ্ঞপ্তি ডট"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"চালু হয়েছে"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"বন্ধ আছে"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"বিজ্ঞপ্তির ডট দেখুন"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"হোম স্ক্রিনে আইকন যোগ করুন"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপ্লিকেশানগুলির জন্যে"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"আইকনের আকৃতি পরিবর্তন করুন"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"হোম স্ক্রিনে"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"সিস্টেমের ডিফল্ট মান ব্যবহার করুন"</string>
<string name="icon_shape_square" msgid="633575066111622774">"চৌকো"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"চৌকো-গোলাকার"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"এর সাথে ফোল্ডার তৈরি করুন: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"ফোল্ডার তৈরি করা হয়েছে"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"হোম স্ক্রীনে সরান"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"স্ক্রীন বাঁ দিকে সরান"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"স্ক্রীন ডান দিকে সরান"</string>
<string name="screen_moved" msgid="266230079505650577">"স্ক্রীন সরানো হয়েছে"</string>
<string name="action_resize" msgid="1802976324781771067">"আবার আকার দিন"</string>
<string name="action_increase_width" msgid="8773715375078513326">"প্রস্থ বাড়ান"</string>
<string name="action_increase_height" msgid="459390020612501122">"উচ্চতা বাড়ান"</string>
@@ -137,8 +138,11 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"অফিস"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"অফিসের প্রোফাইল"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"এখানে কাজের অ্যাপ্সগুলি খুঁজুন"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"প্রতিটি কাজের অ্যাপে একটি করে ব্যাজ রয়েছে এবং অ্যাপগুলি আপনার প্রতিষ্ঠানের দ্বারা সুরক্ষিত। সহজে অ্যাক্সেস করার জন্য অ্যাপগুলি হোম স্ক্রিনে রাখুন।"</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"আপনার প্রতিষ্ঠানের দ্বারা পরিচালিত"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"বিজ্ঞপ্তি এবং অ্যাপ বন্ধ আছে"</string>
<!-- no translation found for bottom_work_tab_user_education_close_button (4224492243977802135) -->
<skip />
<!-- no translation found for bottom_work_tab_user_education_closed (1098340939861869465) -->
<skip />
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No s\'ha trobat cap aplicació que coincideixi amb \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca més aplicacions"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificacions"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Ja no queda espai en aquesta pantalla d\'inici."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No hi ha més espai a la safata Preferits."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Llista d\'aplicacions"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Llista d\'aplicacions personals"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Llista d\'aplicacions per a la feina"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Inici"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Suprimeix"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstal·la"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fons de pantalla"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Configuració de la pantalla d\'inici"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Visió general"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permet la rotació de la pantalla d\'inici"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"En girar el telèfon"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuració actual de la pantalla no permet la rotació"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Punts de notificació"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Activat"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivat"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Cal que tingui accés a les notificacions"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Per veure els punts de notificació, activa les notificacions de l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Canvia la configuració"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Mostra els punts de notificació"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Afegeix la icona a la pantalla d\'inici"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per a les aplicacions noves"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Canvia la forma de les icones"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"a la pantalla d\'inici"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Utilitza l\'opció predeterminada del sistema"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Quadrat"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Quadrat arrodonit"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Crea una carpeta amb: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Carpeta creada"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Desplaça a la pantalla d\'inici"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Desplaça pantalla a l\'esquerra"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Desplaça pantalla a la dreta"</string>
<string name="screen_moved" msgid="266230079505650577">"S\'ha desplaçat la pantalla"</string>
<string name="action_resize" msgid="1802976324781771067">"Canvia la mida"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Augmenta l\'amplada"</string>
<string name="action_increase_height" msgid="459390020612501122">"Augmenta l\'alçada"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Feina"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil professional"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Cerca aplicacions per a la feina aquí"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Totes les aplicacions per a la feina tenen una insígnia que indica que estan protegides per la teva organització. Mou les aplicacions a la pantalla d\'inici per poder-hi accedir més fàcilment."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Gestionat per la teva organització"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Les notificacions i les aplicacions estan desactivades"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Tanca"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Tancada"</string>
</resources>
+8 -9
View File
@@ -43,6 +43,10 @@
<string name="out_of_space" msgid="4691004494942118364">"Der er ikke mere plads på denne startskærm."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Der er ikke mere plads i bakken Foretrukne"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Liste med apps"</string>
<!-- no translation found for all_apps_button_personal_label (1315764287305224468) -->
<skip />
<!-- no translation found for all_apps_button_work_label (7270707118948892488) -->
<skip />
<string name="all_apps_home_button_label" msgid="252062713717058851">"Startskærm"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Fjern"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Afinstaller"</string>
@@ -77,19 +81,18 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Baggrunde"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Indstillinger for startskærmen"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Deaktiveret af din administrator"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Oversigt"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillad rotation af startskærmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Den aktuelle indstilling for visning tillader ikke rotation"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Underretningscirkler"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Til"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Fra"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Kræver adgang til underretninger"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Hvis du vil se underretningscirkler, skal du aktivere appunderretninger for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Skift indstillinger"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Vis underretningscirkler"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Føj ikon til startskærmen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apps"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Skift ikonform"</string>
<!-- no translation found for icon_shape_override_label_location (3841607380657692863) -->
<skip />
<string name="icon_shape_system_default" msgid="1709762974822753030">"Brug systemstandarden"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Kvadrat med runde hjørner"</string>
@@ -119,9 +122,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Opret mappe med: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Mappen blev oprettet"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Flyt til startskærmen"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Flyt skærmen til venstre"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Flyt skærmen til højre"</string>
<string name="screen_moved" msgid="266230079505650577">"Skærmen er flyttet"</string>
<string name="action_resize" msgid="1802976324781771067">"Tilpas størrelse"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Øg bredden"</string>
<string name="action_increase_height" msgid="459390020612501122">"Øg højden"</string>
@@ -137,8 +137,7 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Arbejde"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Arbejdsprofil"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find arbejdsapps her"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Alle arbejdsapps har et badge og beskyttes af din organisation. Flyt apps til din startskærm, så du nemmere kan få adgang til dem."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Administreret af din organisation"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Underretninger og apps er slået fra"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"Ειδοποιήσεις"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Κατάργηση"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Απεγκατάσταση"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ταπετσαρίες"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ρυθμίσεις Αρχικής σελίδας"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Απενεργοποιήθηκε από τον διαχειριστή σας"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Επισκόπηση"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Όταν το τηλέφωνο περιστρέφεται"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Η τρέχουσα ρύθμιση οθόνης δεν επιτρέπει την περιστροφή"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Κουκκίδες ειδοποίησης"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Ενεργή"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Ανενεργή"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Εμφάνιση κουκκίδων ειδοποίησης"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Προσθήκη εικονιδίου στην Αρχική οθόνη"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Για νέες εφαρμογές"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Αλλαγή σχήματος εικονιδίου"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"στην Αρχική οθόνη"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Χρήση προεπιλογής συστήματος"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Τετράγωνο"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Στρογγυλεμένο τετράγωνο"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Δημιουργία φακέλου με: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Δημιουργήθηκε φάκελος"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Μετακίνηση Αρχικής οθόνης"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Μετακίνηση οθόνης αριστερά"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Μετακίνηση οθόνης δεξιά"</string>
<string name="screen_moved" msgid="266230079505650577">"Η οθόνη μετακινήθηκε"</string>
<string name="action_resize" msgid="1802976324781771067">"Προσαρμογή μεγέθους"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Αύξηση του πλάτους"</string>
<string name="action_increase_height" msgid="459390020612501122">"Αύξηση του ύψους"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Εργασίας"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Προφίλ εργασίας"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Βρείτε όλες τις εφαρμογές εργασίας εδώ"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Κάθε εφαρμογή εργασίας φέρει ένα σήμα και διατηρείται ασφαλής από τον οργανισμό σας. Μετακινήστε τις εφαρμογές εργασίας στην Αρχική οθόνη, για να έχετε πιο εύκολη πρόσβαση."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Διαχειριζόμενο από τον οργανισμό σας"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Οι ειδοποιήσεις και οι εφαρμογές είναι απενεργοποιημένες"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Κλείσιμο"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Κλειστή"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personal apps list"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Work apps list"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Home"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remove"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstall"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Overview"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Notification access needed"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Show notification dots"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Change icon shape"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"on Home screen"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Square"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Create folder with: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Folder created"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Move to Home screen"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Move screen to left"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Move screen to right"</string>
<string name="screen_moved" msgid="266230079505650577">"Screen moved"</string>
<string name="action_resize" msgid="1802976324781771067">"Re-size"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Increase width"</string>
<string name="action_increase_height" msgid="459390020612501122">"Increase height"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Work"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Work profile"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find work apps here"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Managed by your organisation"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Notifications and apps are off"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Close"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Closed"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personal apps list"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Work apps list"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Home"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remove"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstall"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Overview"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Notification access needed"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Show notification dots"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Change icon shape"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"on Home screen"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Square"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Create folder with: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Folder created"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Move to Home screen"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Move screen to left"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Move screen to right"</string>
<string name="screen_moved" msgid="266230079505650577">"Screen moved"</string>
<string name="action_resize" msgid="1802976324781771067">"Re-size"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Increase width"</string>
<string name="action_increase_height" msgid="459390020612501122">"Increase height"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Work"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Work profile"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find work apps here"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Managed by your organisation"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Notifications and apps are off"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Close"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Closed"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personal apps list"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Work apps list"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Home"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remove"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstall"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Overview"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Notification access needed"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Show notification dots"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Change icon shape"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"on Home screen"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Square"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Create folder with: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Folder created"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Move to Home screen"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Move screen to left"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Move screen to right"</string>
<string name="screen_moved" msgid="266230079505650577">"Screen moved"</string>
<string name="action_resize" msgid="1802976324781771067">"Re-size"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Increase width"</string>
<string name="action_increase_height" msgid="459390020612501122">"Increase height"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Work"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Work profile"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find work apps here"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Managed by your organisation"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Notifications and apps are off"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Close"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Closed"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más aplicaciones"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"No queda espacio en la pantalla de inicio."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"La bandeja de favoritos está completa"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicaciones"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de aplicaciones personales"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de aplicaciones del trabajo"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Inicio"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Quitar"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ajustes de Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inhabilitada por el administrador"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Visión general"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotación de la pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuración de pantalla actual no permite girar la pantalla"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Puntos de notificación"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Activada"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivada"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Se necesita acceso a las notificaciones"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar burbujas de notificación, activa las notificaciones de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Cambiar ajustes"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Mostrar burbujas de notificación"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Añadir icono a la pantalla de inicio"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para aplicaciones nuevas"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Cambiar forma de los iconos"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"en la pantalla de inicio"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Usar opción predeterminada del sistema"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Cuadrado"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Cuadrado con esquinas redondeadas"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Crear carpeta con: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Carpeta creada"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Mover a la pantalla de inicio"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Mover pantalla a la izquierda"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Mover pantalla a la derecha"</string>
<string name="screen_moved" msgid="266230079505650577">"Pantalla movida"</string>
<string name="action_resize" msgid="1802976324781771067">"Modificar tamaño"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Aumentar ancho"</string>
<string name="action_increase_height" msgid="459390020612501122">"Aumentar altura"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Trabajo"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de trabajo"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Aplicaciones de trabajo"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Cada aplicación de trabajo tiene una insignia y está protegida por tu organización. Mueve las aplicaciones a la pantalla de inicio para acceder a ellas más fácilmente."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Administrada por tu organización"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Las notificaciones y las aplicaciones están desactivadas"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Cerrar"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Cerrada"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Otsi rohkem rakendusi"</string>
<string name="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Sellel avaekraanil pole enam ruumi."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Salves Lemmikud pole rohkem ruumi"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Rakenduste loend"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Isiklike rakenduste loend"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Töörakenduste loend"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Avaekraan"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Eemalda"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalli"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Avalehe seaded"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Ülevaade"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Luba avaekraani pööramine"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kui telefoni pööratakse"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Praegune kuvaseade ei luba pööramist"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Märguandetäpid"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Sees"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Väljas"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Vaja on juurdepääsu märguannetele"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Märguandetäppide kuvamiseks lülitage sisse rakenduse <xliff:g id="NAME">%1$s</xliff:g> märguanded"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Seadete muutmine"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Kuva märguandetäpid"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisa ikoon avaekraanile"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uute rakenduste puhul"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Ikooni kuju muutmine"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"avaekraanil"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Kasuta süsteemi vaikeseadet"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Ruut"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Ümarate nurkadega ruut"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Kausta loomine nimega <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Kaust on loodud"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Teisalda avaekraanile"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Teisalda ekraan vasakule"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Teisalda ekraan paremale"</string>
<string name="screen_moved" msgid="266230079505650577">"Ekraan teisaldati"</string>
<string name="action_resize" msgid="1802976324781771067">"Muuda suurust"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Suurenda laiust"</string>
<string name="action_increase_height" msgid="459390020612501122">"Suurenda kõrgust"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Töö"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Tööprofiil"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Töörakendused leiate siit"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Igal töörakendusel on märk ja teie organisatsioon tagab selle turvalisuse. Teisaldage rakendused avaekraanile, et neile oleks lihtsam juurde pääseda."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Haldab teie organisatsioon"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Märguanded ja rakendused on välja lülitatud"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sule"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Suletud"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketaren emaitzarik"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
<string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Hasierako pantaila honetan ez dago toki gehiago."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Ez dago toki gehiago Gogokoak erretiluan"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Aplikazioen zerrenda"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Aplikazio pertsonalen zerrenda"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Laneko aplikazioen zerrenda"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Hasiera"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Kendu"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalatu"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Horma-paperak"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Hasierako pantailaren ezarpenak"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Ikuspegi orokorra"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Baimendu hasierako pantaila biratzea"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzen denean"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Uneko pantaila-ezarpenak ez du onartzen ikuspegia biratzea"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Jakinarazteko biribiltxoak"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktibatuta"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Desaktibatuta"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Jakinarazpenetarako sarbidea behar da"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Jakinarazteko biribiltxoak ikusteko, aktibatu <xliff:g id="NAME">%1$s</xliff:g> aplikazioaren jakinarazpenak"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Aldatu ezarpenak"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Erakutsi jakinarazteko biribiltxoak"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Gehitu ikonoa hasierako pantailan"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Aplikazio berrietan"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Aldatu ikonoaren forma"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"Hasierako pantailan"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Erabili sistemaren balio lehenetsiak"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Karratua"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Ertz biribilduko karratua"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Sortu karpeta <xliff:g id="NAME">%1$s</xliff:g> elementuarekin"</string>
<string name="folder_created" msgid="6409794597405184510">"Karpeta sortu da"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Eraman hasierako pantailara"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Eraman pantaila ezkerrera"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Eraman pantaila eskuinera"</string>
<string name="screen_moved" msgid="266230079505650577">"Mugitu da pantaila"</string>
<string name="action_resize" msgid="1802976324781771067">"Aldatu tamaina"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Handitu zabalera"</string>
<string name="action_increase_height" msgid="459390020612501122">"Handitu altuera"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Lanekoak"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Laneko profila"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Hemen dituzu laneko aplikazioak"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Laneko aplikazio bakoitzak bereizgarri bat dauka eta erakundeak babesten du. Aplikazioak errazago atzitzeko, eraman itzazu hasierako pantailara."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Erakundeak kudeatzen du"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Jakinarazpenak eta aplikazioak desaktibatuta daude"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Itxi"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Itxita"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> ei palauttanut sovelluksia."</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Hae lisää sovelluksia"</string>
<string name="notifications_header" msgid="1404149926117359025">"Ilmoitukset"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Tässä aloitusruudussa ei ole enää tilaa."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Suosikit-valikossa ei ole enää tilaa"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Sovellusluettelo"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Omat sovellukset luettelo"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Työsovellusluettelo"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Aloitusruutu"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Poista"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Poista asennus"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustakuvat"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Kotiasetukset"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Järjestelmänvalvoja on poistanut toiminnon käytöstä."</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Yleiskatsaus"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Salli aloitusnäytön kiertäminen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kun puhelinta kierretään"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Nykyiset näyttöasetukset eivät salli näytön kiertämistä."</string>
<string name="icon_badging_title" msgid="874121399231955394">"Pistemerkit"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Käytössä"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Pois käytöstä"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Ilmoituksien käyttöoikeus tarvitaan"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"<xliff:g id="NAME">%1$s</xliff:g> tarvitsee ilmoitusten käyttöoikeuden, jotta pistemerkkejä voidaan näyttää."</string>
<string name="title_change_settings" msgid="1376365968844349552">"Muuta asetuksia"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Näytä ilmoituksista kertovat pistemerkit"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisää kuvake aloitusruutuun"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uusille sovelluksille"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Muuta kuvakkeen muotoa"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"aloitusnäytöllä"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Käytä järjestelmän oletusarvoa"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Neliö"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Ympyräneliö"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Luo kansio, jossa on <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="folder_created" msgid="6409794597405184510">"Kansio on luotu."</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Siirrä aloitusnäytölle"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Siirrä näyttöä vasemmalle"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Siirrä näyttöä oikealle"</string>
<string name="screen_moved" msgid="266230079505650577">"Näyttö siirrettiin."</string>
<string name="action_resize" msgid="1802976324781771067">"Muuta kokoa"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Lisää leveyttä"</string>
<string name="action_increase_height" msgid="459390020612501122">"Lisää korkeutta"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Työsovellukset"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Työprofiili"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Etsi työsovelluksia tästä"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Kaikki työsovellukset on merkitty, ja organisaatiosi vastaa niiden suojaamisesta. Voit siirtää työsovelluksia aloitusnäytölle käytön helpottamiseksi."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Organisaatiosi hallinnoima"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Ilmoitukset ja sovellukset ovat poissa käytöstä"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sulje"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Suljettu"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar máis aplicacións"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Non hai máis espazo nesta pantalla de inicio."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Non hai máis espazo na bandexa de favoritos"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicacións"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de aplicacións persoais"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de aplicacións de traballo"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Inicio"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Eliminar"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Configuración de inicio"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Visión xeral"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir xirar a pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ao xirar o teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A configuración de visualización actual non permite xirar a pantalla"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Puntos de notificacións"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Activado"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivado"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Necesítase acceso ás notificacións"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para que se mostren os puntos de notificacións, activa as notificacións da aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Cambiar configuración"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Mostrar puntos de notificación"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engadir icona á pantalla de inicio"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicacións"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Cambiar forma das iconas"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"na pantalla de inicio"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Usar valores predeterminados do sistema"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Cadrado"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Cadrado de bordos redondeados"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Crear cartafol con: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Creouse o cartafol"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Mover á pantalla de inicio"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Mover pantalla á esquerda"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Mover pantalla á dereita"</string>
<string name="screen_moved" msgid="266230079505650577">"Moveuse a pantalla"</string>
<string name="action_resize" msgid="1802976324781771067">"Cambiar tamaño"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Aumentar ancho"</string>
<string name="action_increase_height" msgid="459390020612501122">"Aumentar altura"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Traballo"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de traballo"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Buscar aplicacións do traballo aquí"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"As aplicacións do traballo teñen unha insignia e están protexidas pola túa organización. Traslada as aplicacións á pantalla de inicio para acceder a elas de forma máis fácil."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Perfil xestionado pola túa organización"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"As notificacións e as aplicacións están desactivadas"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Pechar"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Pechado"</string>
</resources>
+13 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"નોટિફિકેશનો"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"દૂર કરો"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"અનઇન્સ્ટોલ કરો"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર્સ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ્સ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"ઝલક"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"વર્તમાન પ્રદર્શન સેટિંગ ફેરવવાની પરવાનગી આપતી નથી"</string>
<string name="icon_badging_title" msgid="874121399231955394">"સૂચના બિંદુઓ"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"ચાલુ"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"બંધ"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"નોટિફિકેશન માટેનું ચિહ્ન બતાવો"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"હોમ સ્ક્રીન પર આઇકન ઉમેરો"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ્લિકેશનો માટે"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"આઇકનનો આકાર બદલો"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"હોમ સ્ક્રીન પર"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"સિસ્ટમ ડિફૉલ્ટનો ઉપયોગ કરો"</string>
<string name="icon_shape_square" msgid="633575066111622774">"ચોરસ"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"ચોરસ જેવું ગોળ"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"આની સાથે ફોલ્ડર બનાવો: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"ફોલ્ડર બનાવ્યું"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"હોમ સ્ક્રીન પર ખસેડો"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"સ્ક્રીનને ડાબી બાજુ ખસેડો"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"સ્ક્રીનને જમણી બાજુ ખસેડો"</string>
<string name="screen_moved" msgid="266230079505650577">"સ્ક્રીન ખસેડી"</string>
<string name="action_resize" msgid="1802976324781771067">"આકાર બદલો"</string>
<string name="action_increase_width" msgid="8773715375078513326">"પહોળાઈ વધારો"</string>
<string name="action_increase_height" msgid="459390020612501122">"ઊંચાઈ વધારો"</string>
@@ -137,8 +138,11 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"કાર્યાલયની ઍપ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"કાર્યાલયની પ્રોફાઇલ"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"કાર્ય ઍપને અહીંથી મેળવો"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"દરેક કાર્ય ઍપ પાસે એક બૅજ હોય છે અને તમારી સંસ્થા દ્વારા તેને સુરક્ષિત રાખવામાં આવે છે. વધુ સરળ ઍક્સેસ માટે ઍપને તમારી હોમ સ્ક્રીન પર ખસેડો."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"તમારી સંસ્થા દ્વારા મેનેજ કરેલ"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"નોટિફિકેશન અને ઍપ બંધ છે"</string>
<!-- no translation found for bottom_work_tab_user_education_close_button (4224492243977802135) -->
<skip />
<!-- no translation found for bottom_work_tab_user_education_closed (1098340939861869465) -->
<skip />
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nem található alkalmazás a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"További alkalmazások keresése"</string>
<string name="notifications_header" msgid="1404149926117359025">"Értesítések"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Nincs több hely ezen a kezdőképernyőn."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Nincs több hely a Kedvencek tálcán"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Alkalmazások listája"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Személyes alkalmazások listája"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Munkahelyi alkalmazások listája"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Főoldal"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Törlés"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Eltávolítás"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Háttérképek"</string>
<string name="settings_button_text" msgid="8873672322605444408">"A Home beállításai"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"A rendszergazda letiltotta"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Áttekintés"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"A kezdőképernyő elforgatásának engedélyezése"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"A telefon elforgatásakor"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A jelenlegi kijelzőbeállítások nem teszik lehetővé az elforgatást"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Értesítési pöttyök"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Bekapcsolva"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Kikapcsolva"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Értesítésekhez való hozzáférésre van szükség"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Az értesítési pöttyök megjelenítéséhez kapcsolja be a(z) <xliff:g id="NAME">%1$s</xliff:g> alkalmazás értesítéseit"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Beállítások módosítása"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Értesítési pöttyök megjelenítése"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ikon hozzáadása a kezdőképernyőhöz"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Új alkalmazásoknál"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Ikon formájának módosítása"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"a kezdőképernyőn"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Alapértelmezett érték használata"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Négyzet"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Mappa létrehozása a következővel: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Mappa létrehozva"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Áthelyezés a kezdőképernyőre"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Képernyő mozgatása balra"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Képernyő mozgatása jobbra"</string>
<string name="screen_moved" msgid="266230079505650577">"Képernyő áthelyezve"</string>
<string name="action_resize" msgid="1802976324781771067">"Átméretezés"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Szélesség növelése"</string>
<string name="action_increase_height" msgid="459390020612501122">"Magasság növelése"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Munkahelyi"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Munkaprofil"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Itt kereshet munkahelyi alkalmazásokat"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"A munkahelyi alkalmazásoknál jelvény található, és biztonságukról az Ön szervezete gondoskodik. A könnyebb hozzáférés érdekében helyezze át az alkalmazásokat a kezdőképernyőre."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Az Ön szervezete kezeli"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Az értesítések és az alkalmazások ki vannak kapcsolva"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Bezárás"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Bezárva"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Tidak ditemukan aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Tidak ada ruang lagi pada layar Utama ini."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Tidak ada ruang tersisa di baki Favorit"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Daftar aplikasi"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Daftar aplikasi pribadi"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Daftar aplikasi kantor"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Layar Utama"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Hapus"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstal"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpaper"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Setelan layar Utama"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dinonaktifkan oleh admin"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Ringkasan"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan layar Utama diputar"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Saat ponsel diputar"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Setelan Tampilan Saat Ini tidak memungkinkan putaran"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Titik notifikasi"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktif"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Nonaktif"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Perlu akses notifikasi"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Guna menampilkan Titik Notifikasi, aktifkan notifikasi aplikasi untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Ubah setelan"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Tampilkan titik notifikasi"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon ke Layar utama"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk aplikasi baru"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Ubah bentuk ikon"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"di layar Utama"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Gunakan default sistem"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Persegi"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Persegi bundar"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Buat folder dengan: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Folder dibuat"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Pindahkan ke layar Utama"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Pindahkan layar ke kiri"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Pindahkan layar ke kanan"</string>
<string name="screen_moved" msgid="266230079505650577">"Layar dipindahkan"</string>
<string name="action_resize" msgid="1802976324781771067">"Ubah ukuran"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Tambahi lebar"</string>
<string name="action_increase_height" msgid="459390020612501122">"Tambahi tinggi"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Kantor"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil kerja"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Temukan aplikasi kerja di sini"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Setiap aplikasi kerja memiliki badge dan dibuat tetap aman oleh organisasi. Pindahkan aplikasi ke Layar utama untuk memudahkan akses."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Dikelola oleh organisasi"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Notifikasi dan aplikasi nonaktif"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Tutup"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Ditutup"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca altre app"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifiche"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<string name="out_of_space" msgid="4691004494942118364">"Spazio nella schermata Home esaurito."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Spazio esaurito nella barra dei Preferiti"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Elenco di app"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Elenco di app personali"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Elenco di app di lavoro"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Home page"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Rimuovi"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Disinstalla"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Sfondi"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Impostazioni Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disattivata dall\'amministratore"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Panoramica"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Consenti rotazione della schermata Home"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Con il telefono ruotato"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"L\'impostazione corrente del display non consente la rotazione"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Indicatori notifica"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Attiva"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Non attiva"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Accesso alle notifiche necessario"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Per mostrare gli indicatori di notifica, attiva le notifiche per l\'app <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Modifica impostazioni"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Mostra indicatori di notifica"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Aggiungi icone alla schermata Home"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per le nuove app"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Cambia la forma delle icone"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"nella schermata Home"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Usa impostazione predefinita di sistema"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Quadrato"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Supercerchio"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Crea cartella con: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Cartella creata"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Sposta nella schermata Home"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Sposta schermata a sinistra"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Sposta schermata a destra"</string>
<string name="screen_moved" msgid="266230079505650577">"Schermata spostata"</string>
<string name="action_resize" msgid="1802976324781771067">"Ridimensiona"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Aumenta larghezza"</string>
<string name="action_increase_height" msgid="459390020612501122">"Aumenta altezza"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Lavoro"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profilo di lavoro"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Qui puoi trovare le tue app di lavoro"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Ogni app di lavoro è contrassegnata da un badge e viene tenuta al sicuro dalla tua organizzazione. Sposta le app nella schermata Home per accedervi più facilmente."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Gestito dalla tua organizzazione"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Le notifiche e le app non sono attive"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Chiudi"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Chiusa"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"通知"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"削除"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"アンインストール"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"壁紙"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ホームの設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"管理者により無効にされています"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"概要"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ホーム画面の回転を許可"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"スマートフォンが回転したとき"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"現在の [ディスプレイ] 設定では回転を使用できません"</string>
<string name="icon_badging_title" msgid="874121399231955394">"通知ドット"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"ON"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"OFF"</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>」のアプリ通知を ON にしてください"</string>
<string name="title_change_settings" msgid="1376365968844349552">"設定を変更"</string>
<string name="icon_badging_service_title" msgid="2309733118428242174">"通知ドットの表示"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ホーム画面にアイコンを追加"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新しいアプリをダウンロードしたとき"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"アイコンの形の変更"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"ホーム画面上"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"システムのデフォルトを使用"</string>
<string name="icon_shape_square" msgid="633575066111622774">"スクエア"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"スクワークル"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"「<xliff:g id="NAME">%1$s</xliff:g>」フォルダを作成"</string>
<string name="folder_created" msgid="6409794597405184510">"フォルダを作成しました"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"ホーム画面に移動"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"画面を左に移動"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"画面を右に移動"</string>
<string name="screen_moved" msgid="266230079505650577">"画面を移動しました"</string>
<string name="action_resize" msgid="1802976324781771067">"サイズを変更"</string>
<string name="action_increase_width" msgid="8773715375078513326">"幅を広くする"</string>
<string name="action_increase_height" msgid="459390020612501122">"高さを高くする"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"仕事用"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"仕事用プロファイル"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ここには仕事用アプリが表示されます"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"仕事用アプリにはバッジが表示され、組織によって安全に保護されています。仕事用アプリをホーム画面に移動すると、簡単にアクセスできます。"</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"組織によって管理されています"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"通知とアプリは OFF です"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"閉じる"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"終了"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"შეტყობინებები"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ამოშლა"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"დეინსტალაცია"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
<string name="settings_button_text" msgid="8873672322605444408">"მთავარი გვერდის პარამეტრები"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"მიმოხილვა"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ტელეფონის შეტრიალებისას"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ბრუნვა დაუშვებელია ჩვენების მიმდინარე პარამეტრებით"</string>
<string name="icon_badging_title" msgid="874121399231955394">"შეტყობინების ნიშნულები"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"ჩართული"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"გამორთული"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"შეტყობინების ნიშნულების ჩვენება"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ხატულას მთავარ ეკრანზე დამატება"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ახალი აპებისთვის"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"ხატულას ფორმის შეცვლა"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"მთავარ ეკრანზე"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"ნაგულისხმევი სისტემური პარამეტრების გამოყენება"</string>
<string name="icon_shape_square" msgid="633575066111622774">"კვადრატი"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"წრეკუთხედი"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"საქაღალდის შექმნა ერთეულით: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"საქაღალდე შექმნილია"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"მთავარ ეკრანზე გადატანა"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"ეკრანის გადატანა მარცხნივ"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"ეკრანის გადატანა მარჯვნით"</string>
<string name="screen_moved" msgid="266230079505650577">"ეკრანი გადაადგილდა"</string>
<string name="action_resize" msgid="1802976324781771067">"ზომის შეცვლა"</string>
<string name="action_increase_width" msgid="8773715375078513326">"სიგანის გაზრდა"</string>
<string name="action_increase_height" msgid="459390020612501122">"სიმაღლის გაზრდა"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"სამსახური"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"სამსახურის პროფილი"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"აქ თავმოყრილია სამსახურის აპები"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"სამსახურის თითოეულ აპს აქვს ბეჯი, რაც ნიშნავს, რომ მათ უსაფრთხოებას თქვენი ორგანიზაცია უზრუნველყოფს. მარტივი წვდომისთვის, შეგიძლიათ სამსახურის აპები მთავარი ეკრანზე გადაიტანოთ."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"იმართება თქვენი ორგანიზაციის მიერ"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"შეტყობინებები და აპები გამორთულია"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"დახურვა"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"დახურული"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"Хабарландырулар"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Жою"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Жою"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тұсқағаздар"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Негізгі экран параметрлері"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Шолу"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бұрылғанда"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранның ағымдағы параметрі айналуға рұқсат бермейді"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Хабарландыру белгілері"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Қосулы"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Өшірулі"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Хабарландыру белгілерін көрсету"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Негізгі экранға белгіше енгізу"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңа қолданбаларға арналған"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Белгіше пішінін өзгерту"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"Негізгі экранда"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Жүйенің әдепкі параметрін пайдалану"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Шаршы"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Жұмыр төртбұрыш"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Мына бар қалтаны жасау: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Қалта жасалды"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Негізгі экранға жылжыту"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Экранды солға жылжыту"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Экранды оңға жылжыту"</string>
<string name="screen_moved" msgid="266230079505650577">"Экран жылжытылды"</string>
<string name="action_resize" msgid="1802976324781771067">"Өлшемін өзгерту"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Енін арттыру"</string>
<string name="action_increase_height" msgid="459390020612501122">"Биіктігін арттыру"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Жұмыс"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Жұмыс профилі"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Жұмыс қолданбалары осы жерде берілген"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Әрбір жұмыс қолданбасында танымбелгі бар. Ол оның қауіпсіздігі ұйым арқылы қамтамасыз етілетінін білдіреді. Жұмыс қолданбаларына оңай кіру үшін, оларды Негізгі экранға жылжытуға болады."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Ұйым арқылы басқарылады"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Хабарландырулар мен қолданбалар өшірулі"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Жабу"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Жабық"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"ការ​ជូនដំណឹង"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"យកចេញ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"លុបការដំឡើង"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំង​រូបភាព"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ការកំណត់​ទំព័រដើម"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"សង្ខេប"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ការកំណត់អេក្រង់បច្ចុប្បន្នមិនអនុញ្ញាតការបង្វិលទេ"</string>
<string name="icon_badging_title" msgid="874121399231955394">"ស្លាកជូនដំណឹង"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"បើក"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"បិទ"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"បង្ហាញ​ស្លាក​ជូនដំណឹង"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"បញ្ចូល​រូបតំណាង​ទៅ​អេក្រង់​ដើម"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"សម្រាប់កម្មវិធីថ្មី"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"ប្តូររូបរាងរូបតំណាង"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"នៅ​លើ​អេក្រង់​ដើម"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"ប្រើលំនាំដើមរបស់ប្រព័ន្ធ"</string>
<string name="icon_shape_square" msgid="633575066111622774">"ការ៉េ"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"ការ៉េជ្រុងកោង"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"បង្កើតថតឯកសារជាមួយ៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"បានបង្កើតថតឯកសារ"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"ផ្លាស់ទៅអេក្រង់ដើម"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"រំកិលអេក្រង់ទៅខាងឆ្វេង"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"រំកិលអេក្រង់ទៅខាងស្តាំ"</string>
<string name="screen_moved" msgid="266230079505650577">"អេក្រង់ដែលបានផ្លាស់ទី"</string>
<string name="action_resize" msgid="1802976324781771067">"ប្ដូរទំហំ"</string>
<string name="action_increase_width" msgid="8773715375078513326">"បង្កើនទទឹង"</string>
<string name="action_increase_height" msgid="459390020612501122">"បង្កើនកម្ពស់"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"ការងារ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"កម្រងព័ត៌មានការងារ"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ស្វែង​រក​កម្មវិធី​ការងារ​នៅទីនេះ"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"កម្មវិធី​ការងារ​នីមួយៗ​មាន​ស្លាកមួយ និងត្រូវ​បានរក្សាទុក​យ៉ាងមានសុវត្ថិភាព​ដោយស្ថាប័ន​របស់អ្នក។ សូម​ផ្លាស់ទី​កម្មវិធី​ទៅកាន់​អេក្រង់​ដើម​របស់អ្នក​ ដើម្បី​ងាយស្រួល​ចូលប្រើជាងមុន។"</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"គ្រប់គ្រងដោយ​ស្ថាប័ន​របស់អ្នក"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"ការជូនដំណឹង​ និងកម្មវិធី​ត្រូវបានបិទ"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"បិទ"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"បានបិទ"</string>
</resources>
+13 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ತೆಗೆದುಹಾಕಿ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"ವಾಲ್‌ಪೇಪರ್‌ಗಳು"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"ಅವಲೋಕನ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ಫೋನ್‌ ತಿರುಗಿಸಿದಾಗ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ಪ್ರಸ್ತುತ ಪ್ರದರ್ಶನ ಸೆಟ್ಟಿಂಗ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
<string name="icon_badging_title" msgid="874121399231955394">"ಅಧಿಸೂಚನೆ ಡಾಟ್‌ಗಳು"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"ಆನ್"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"ಆಫ್"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"ಅಧಿಸೂಚನೆ ಡಾಟ್‌ಗಳನ್ನು ತೋರಿಸಿ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ಮುಖಪುಟದ ಪರದೆಗೆ ಐಕಾನ್ ಸೇರಿಸಿ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"ಮುಖಪುಟ ಪರದೆಯಲ್ಲಿ"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್ ಬಳಸಿ"</string>
<string name="icon_shape_square" msgid="633575066111622774">"ಚೌಕ"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"ಚೌಕವೃತ್ತ"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"ಇದನ್ನು ಬಳಸಿಕೊಂಡು ಫೋಲ್ಡರ್ ರಚಿಸಿ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"ಫೋಲ್ಡರ್ ರಚಿಸಲಾಗಿದೆ"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"ಮುಖಪುಟಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"ಪರದೆಯನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"ಪರದೆಯನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="screen_moved" msgid="266230079505650577">"ಪರದೆ ಸರಿಸಲಾಗಿದೆ"</string>
<string name="action_resize" msgid="1802976324781771067">"ಮರುಗಾತ್ರ"</string>
<string name="action_increase_width" msgid="8773715375078513326">"ಅಗಲವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"</string>
<string name="action_increase_height" msgid="459390020612501122">"ಎತ್ತರವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"</string>
@@ -137,8 +138,11 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"ಕೆಲಸ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಇಲ್ಲಿ ಹುಡುಕಿ"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ಕೆಲಸದ ಪ್ರತಿ ಅಪ್ಲಿಕೇಶನ್ ಬ್ಯಾಡ್ಜ್ ಹೊಂದಿದೆ ಮತ್ತು ನಿಮ್ಮ ಸಂಸ್ಥೆಯಿಂದ ಸುರಕ್ಷಿತವಾಗಿ ಇರಿಸಲಾಗುತ್ತದೆ. ಸುಲಭ ಪ್ರವೇಶಕ್ಕಾಗಿ ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸರಿಸಿ."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"ಅಧಿಸೂಚನೆಗಳು ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಆಫ್ ಆಗಿವೆ"</string>
<!-- no translation found for bottom_work_tab_user_education_close_button (4224492243977802135) -->
<skip />
<!-- no translation found for bottom_work_tab_user_education_closed (1098340939861869465) -->
<skip />
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"알림"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"삭제"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"제거"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"배경화면"</string>
<string name="settings_button_text" msgid="8873672322605444408">"홈 설정"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"관리자가 사용 중지함"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"개요"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"홈 화면 회전 허용"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"휴대전화 회전 시"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"현재 표시 설정에는 회전 기능이 허용되지 않습니다."</string>
<string name="icon_badging_title" msgid="874121399231955394">"알림 표시 점"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"사용"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"사용 안함"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"알림 표시 점 보기"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"홈 화면에 아이콘 추가"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"새로 설치한 앱에 적용"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"아이콘 모양 변경"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"홈 화면에 표시"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"시스템 기본값 사용"</string>
<string name="icon_shape_square" msgid="633575066111622774">"정사각형"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"모서리가 둥근 정사각형"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"다음이 포함된 폴더 만들기: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"폴더를 만들었습니다."</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"홈 화면으로 이동"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"화면을 왼쪽으로 이동"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"화면을 오른쪽으로 이동"</string>
<string name="screen_moved" msgid="266230079505650577">"화면 이동됨"</string>
<string name="action_resize" msgid="1802976324781771067">"크기 조정"</string>
<string name="action_increase_width" msgid="8773715375078513326">"폭 늘리기"</string>
<string name="action_increase_height" msgid="459390020612501122">"높이 늘리기"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"직장"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"직장 프로필"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"여기에서 업무용 앱 찾기"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"각 업무용 앱에는 배지가 있으며 업무용 앱은 조직에서 안전하게 보호됩니다. 앱을 홈 화면으로 이동하여 더 간편하게 사용하세요."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"조직에서 관리"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"알림 및 앱 사용 중지됨"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"닫기"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"종료됨"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"Эскертмелер"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Алып салуу"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Чыгарып салуу"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Башкы беттин жөндөөлөрү"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"Көз жүгүртүү"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды айлантууга уруксат берүү"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон айланганда"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранды айлантуу параметри өчүрүлгөн"</string>
<string name="icon_badging_title" msgid="874121399231955394">"Эскертме белгилери"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"Күйүк"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"Өчүк"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"Эскертме белгилерин көрсөтүү"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Башкы экранга сүрөтчө кошуу"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңы колдонмолор үчүн"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"Сүрөтчөнүн формасын өзгөртүү"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"Башкы экранда"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"Тутум сушунтаган демейкисин колдонуу"</string>
<string name="icon_shape_square" msgid="633575066111622774">"Чарчы"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"Бурчтары жумуру төрт бурчтук"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"Төмөнкү менен куржун түзүү: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"Куржун түзүлдү"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Башкы экранга жылдыруу"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"Экранды солго жылдыруу"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"Экранды оңго жылдыруу"</string>
<string name="screen_moved" msgid="266230079505650577">"Экран жылдырылды"</string>
<string name="action_resize" msgid="1802976324781771067">"Өлчөмүн өзгөртүү"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Кеңейтүү"</string>
<string name="action_increase_height" msgid="459390020612501122">"Бийиктетүү"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"Жумуш колдонмолору"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Жумуш профили"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Жумуш колдонмолорун бул жерден таап алыңыз"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Ар бир жумуш колдонмосунун бейджиги бар жана ал уюмуңуз тарабынан коопсуз сакталат. Колдонмолорго тез өтүү үчүн аларды Башкы экранга кошуп алыңыз."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"Уюмуңуз тарабынан башкарылат"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"Билдирүүлөр жана колдонмолор өчүрүлгөн"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Жабуу"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Жабык"</string>
</resources>
+11 -9
View File
@@ -40,9 +40,15 @@
<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="notifications_header" msgid="1404149926117359025">"ການແຈ້ງເຕືອນ"</string>
<!-- no translation found for long_press_shortcut_to_add (4524750017792716791) -->
<skip />
<!-- no translation found for long_accessible_way_to_add_shortcut (3327314059613154633) -->
<skip />
<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_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>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ເອົາ​ອອກ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ຖອນ​ການ​ຕິດ​ຕັ້ງ"</string>
@@ -77,19 +83,17 @@
<string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ການຕັ້ງຄ່າ Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
<string name="accessibility_action_overview" msgid="6257665857640347026">"ພາບຮວມ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ເມື່ອໝຸນໂທລະສັບ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ການຕັ້ງຄ່າສະແດງຜົນປັດຈຸບັນບໍ່ອະນຸຍາດໃຫ້ໝຸນໄດ້"</string>
<string name="icon_badging_title" msgid="874121399231955394">"ຈຸດການແຈ້ງເຕືອນ"</string>
<string name="icon_badging_desc_on" msgid="2627952638544674079">"ເປີດ"</string>
<string name="icon_badging_desc_off" msgid="5503319969924580241">"ປິດ"</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>
<string name="icon_badging_service_title" msgid="2309733118428242174">"ສະແດງຈຸດການແຈ້ງເຕືອນ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ສຳລັບແອັບໃໝ່"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"ປ່ຽນຮູບຮ່າງໄອຄອນ"</string>
<string name="icon_shape_override_label_location" msgid="3841607380657692863">"ຢູ່ໜ້າຈໍຫຼັກ"</string>
<string name="icon_shape_system_default" msgid="1709762974822753030">"ໃຊ້ຄ່າເລີ່ມຕົ້ນລະບົບ"</string>
<string name="icon_shape_square" msgid="633575066111622774">"ສີ່ຫຼ່ຽມຈັດຕຸລັດ"</string>
<string name="icon_shape_squircle" msgid="5658049910802669495">"ສີ່ຫຼ່ຽມຂອບມົນ"</string>
@@ -119,9 +123,6 @@
<string name="create_folder_with" msgid="4050141361160214248">"ສ້າງ​ໂຟ​ລ​ເດີ​ກັບ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"ສ້າງ​ໂຟ​ລ​ເດີ​ແລ້ວ"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"ຍ້າຍ​ໄປ​ໃສ່​ໜ້າ​ຈໍ​ຫຼັກ"</string>
<string name="action_move_screen_left" msgid="8854216831569401665">"ຍ້າຍ​ໜ້າ​ຈໍ​ໄປ​ທາງ​ຊ້າຍ"</string>
<string name="action_move_screen_right" msgid="329334910274311123">"ຍ້າຍ​ໜ້າ​ຈໍ​ໄປ​ທາງ​ຂວາ"</string>
<string name="screen_moved" msgid="266230079505650577">"ຍ້າຍ​ໜ້າ​ຈໍ​ແລ້ວ"</string>
<string name="action_resize" msgid="1802976324781771067">"ປັບຂະໜາດ"</string>
<string name="action_increase_width" msgid="8773715375078513326">"ເພີ່ມ​ລວງ​ກ້​ວາງ​ຂຶ້ນ"</string>
<string name="action_increase_height" msgid="459390020612501122">"ເພີ່ມ​ລວງ​ສູງ​ຂຶ້ນ"</string>
@@ -137,8 +138,9 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"ວຽກ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
<string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ຊອກຫາແອັບວຽກຢູ່ບ່ອນນີ້"</string>
<!-- no translation found for bottom_work_tab_user_education_body (2818107472360579152) -->
<skip />
<string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ແຕ່ລະແອັບວຽກຈະມີປ້າຍ ແລະ ຖືກຈັດເກັບໄວ້ຢ່າງປອດໄພໂດຍອົງກອນຂອງທ່ານ. ທ່ານສາມາດຍ້າຍແອັບໄປໃສ່ໜ້າຈໍຫຼັກເພື່ອໃຫ້ເຂົ້າໃຊ້ງ່າຍຂຶ້ນໄດ້."</string>
<string name="work_mode_on_label" msgid="4781128097185272916">"ຈັດການໂດຍອົງກອນຂອງທ່ານ"</string>
<string name="work_mode_off_label" msgid="3194894777601421047">"ການແຈ້ງເຕືອນ ແລະ ແອັບຖືກປິດໄວ້"</string>
<string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ປິດ"</string>
<string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ປິດແລ້ວ"</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More