Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8492330 authored by Vadim Tryshev's avatar Vadim Tryshev
Browse files

Prototype for the DWB toast in Overview

No UX spec is ready, so using some placeholder layout.
No attention to string localization since I feel that strings may
change, compared to current mocks.
Not using remaining-time API, as it is not ready.

Bug:118319143
Test: Manual
Change-Id: I50cff9099677db543e95963f058d3e89eab07d8f
parent 33fd26f0
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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
+97 −0
Original line number Diff line number Diff line
/*
 * 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);
        }
    }
}
+24 −33
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.animation.AnimatorListenerAdapter;
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.FrameLayout;
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;
@@ -140,6 +137,7 @@ public class TaskView extends FrameLayout implements PageCallbacks {
    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 @@ public class TaskView extends FrameLayout implements PageCallbacks {
        super.onFinishInflate();
        mSnapshotView = findViewById(R.id.snapshot);
        mIconView = findViewById(R.id.icon);
        mDigitalWellBeingToast = findViewById(R.id.digital_well_being_toast);
    }

    /**
@@ -266,8 +265,18 @@ public class TaskView extends FrameLayout implements PageCallbacks {
                    (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) {
@@ -464,7 +473,7 @@ public class TaskView extends FrameLayout implements PageCallbacks {
        }

        if (action == R.string.accessibility_app_usage_settings) {
            openAppUsageSettings(this);
            mDigitalWellBeingToast.openAppUsageSettings();
            return true;
        }

@@ -486,24 +495,6 @@ public class TaskView extends FrameLayout implements PageCallbacks {
        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();
    }