Merge "Prototype for the DWB toast in Overview" into ub-launcher3-master
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 36d327d..fcc0c53 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -34,4 +34,21 @@
android:layout_gravity="top|center_horizontal"
android:focusable="false"
android:importantForAccessibility="no" />
+
+ <com.android.quickstep.views.DigitalWellBeingToast
+ android:id="@+id/digital_well_being_toast"
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ android:importantForAccessibility="noHideDescendants"
+ android:background="#800000FF"
+ android:layout_gravity="bottom"
+ >
+ <TextView
+ android:id="@+id/remaining_time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:textColor="@android:color/white"
+ />
+ </com.android.quickstep.views.DigitalWellBeingToast>
</com.android.quickstep.views.TaskView>
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
new file mode 100644
index 0000000..4e89353
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -0,0 +1,97 @@
+/*
+ * 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.views;
+
+import android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.systemui.shared.recents.model.Task;
+
+public final class DigitalWellBeingToast extends LinearLayout {
+ public interface InitializeCallback {
+ void call(long t, boolean b);
+ }
+
+ private static final String TAG = DigitalWellBeingToast.class.getSimpleName();
+
+ private Task mTask;
+
+ public DigitalWellBeingToast(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setLayoutDirection(Utilities.isRtl(getResources()) ?
+ View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
+ setOnClickListener((view) -> openAppUsageSettings());
+
+ }
+
+ private void setRemainingTime(long remainingTime, boolean isGroupLimit) {
+ final TextView remainingTimeText = findViewById(R.id.remaining_time);
+ if (remainingTime <= 0) {
+ setVisibility(GONE);
+ } else {
+ setVisibility(VISIBLE);
+ remainingTimeText.setText(getText(remainingTime, isGroupLimit));
+ }
+ }
+
+ public void initialize(Task task, InitializeCallback callback) {
+ mTask = task;
+ Utilities.THREAD_POOL_EXECUTOR.execute(() -> {
+ final long appRemainingTimeMs = -1;
+ final boolean isGroupLimit = true;
+ post(() -> {
+ setRemainingTime(appRemainingTimeMs, isGroupLimit);
+ callback.call(appRemainingTimeMs, isGroupLimit);
+ });
+ });
+ }
+
+ public static String getText(long remainingTime, boolean isGroupLimit) {
+ return "Remaining time:" + (remainingTime + 119999) / 120000
+ + " min " + (isGroupLimit ? "for group" : "for the app");
+ }
+
+ public void openAppUsageSettings() {
+ final Intent intent = new Intent(TaskView.SEE_TIME_IN_APP_TEMPLATE)
+ .putExtra(Intent.EXTRA_PACKAGE_NAME,
+ mTask.getTopComponent().getPackageName()).addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ try {
+ final Launcher launcher = Launcher.getLauncher(getContext());
+ final ActivityOptions options = ActivityOptions.makeScaleUpAnimation(
+ this, 0, 0,
+ getWidth(), getHeight());
+ launcher.startActivity(intent, options.toBundle());
+ launcher.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP,
+ LauncherLogProto.ControlType.APP_USAGE_SETTINGS, this);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Failed to open app usage settings for task "
+ + mTask.getTopComponent().getPackageName(), e);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 9aaaf9c..a6a3b85 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -27,7 +27,6 @@
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.app.ActivityOptions;
-import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -46,10 +45,8 @@
import android.widget.Toast;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-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.quickstep.RecentsModel;
@@ -107,16 +104,16 @@
private static final FloatProperty<TaskView> FOCUS_TRANSITION =
new FloatProperty<TaskView>("focusTransition") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setIconAndDimTransitionProgress(v);
- }
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.setIconAndDimTransitionProgress(v);
+ }
- @Override
- public Float get(TaskView taskView) {
- return taskView.mFocusTransitionProgress;
- }
- };
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mFocusTransitionProgress;
+ }
+ };
static final Intent SEE_TIME_IN_APP_TEMPLATE =
new Intent("com.android.settings.action.TIME_SPENT_IN_APP");
@@ -140,6 +137,7 @@
private TaskThumbnailView mSnapshotView;
private TaskMenuView mMenuView;
private IconView mIconView;
+ private DigitalWellBeingToast mDigitalWellBeingToast;
private float mCurveScale;
private float mZoomScale;
private boolean mIsFullscreen;
@@ -183,6 +181,7 @@
super.onFinishInflate();
mSnapshotView = findViewById(R.id.snapshot);
mIconView = findViewById(R.id.icon);
+ mDigitalWellBeingToast = findViewById(R.id.digital_well_being_toast);
}
/**
@@ -266,8 +265,18 @@
(task) -> mSnapshotView.setThumbnail(task, task.thumbnail));
mIconLoadRequest = iconCache.updateIconInBackground(mTask,
(task) -> {
- setContentDescription(task.titleDescription);
setIcon(task.icon);
+ mDigitalWellBeingToast.initialize(
+ mTask,
+ (appRemainingTimeMs, isGroupLimit) -> {
+ mAppRemainingTimeMs = appRemainingTimeMs;
+ setContentDescription(
+ hasRemainingTime() ?
+ task.titleDescription + ". "
+ + DigitalWellBeingToast.getText(
+ appRemainingTimeMs, isGroupLimit) :
+ task.titleDescription);
+ });
});
} else {
if (mThumbnailLoadRequest != null) {
@@ -309,7 +318,7 @@
mFocusTransitionProgress = progress;
mSnapshotView.setDimAlphaMultipler(progress);
float scale = FAST_OUT_SLOW_IN.getInterpolation(Utilities.boundToRange(
- progress * DIM_ANIM_DURATION / SCALE_ICON_DURATION, 0, 1));
+ progress * DIM_ANIM_DURATION / SCALE_ICON_DURATION, 0, 1));
mIconView.setScaleX(scale);
mIconView.setScaleY(scale);
}
@@ -464,7 +473,7 @@
}
if (action == R.string.accessibility_app_usage_settings) {
- openAppUsageSettings(this);
+ mDigitalWellBeingToast.openAppUsageSettings();
return true;
}
@@ -486,24 +495,6 @@
return super.performAccessibilityAction(action, arguments);
}
- private void openAppUsageSettings(View view) {
- final Intent intent = new Intent(SEE_TIME_IN_APP_TEMPLATE)
- .putExtra(Intent.EXTRA_PACKAGE_NAME,
- mTask.getTopComponent().getPackageName()).addFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- try {
- final Launcher launcher = Launcher.getLauncher(getContext());
- final ActivityOptions options = ActivityOptions.makeScaleUpAnimation(view, 0, 0,
- view.getWidth(), view.getHeight());
- launcher.startActivity(intent, options.toBundle());
- launcher.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP,
- LauncherLogProto.ControlType.APP_USAGE_SETTINGS, this);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "Failed to open app usage settings for task "
- + mTask.getTopComponent().getPackageName(), e);
- }
- }
-
private RecentsView getRecentsView() {
return (RecentsView) getParent();
}