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

Commit a8f569c1 authored by Jason Monk's avatar Jason Monk
Browse files

Add toast when user tries to leave lock-to-app

The toast will describe how to exit when entered normally, but when
entered by a DPM whitelisted app it will just notify them they are in
the mode.

Bug: 15780115
Change-Id: I75ac8540c31a75ac68e34b3b5c8260e191894b39
parent 851d2d5d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4773,6 +4773,10 @@
    <!-- DO NOT TRANSLATE -->
    <string name="day_of_week_label_typeface">sans-serif</string>

    <!-- Lock-to-app notification toast. The $ is not actually shown or translated, it is a marker of where the recents icon shows up. -->
    <string name="lock_to_app_toast">You are in Lock-to-App mode. Press and hold the recent apps button to exit $</string>
    <!-- Notify user that they are locked in lock-to-app mode -->
    <string name="lock_to_app_toast_locked">You are in Lock-to-App mode.</string>
    <!-- Lock-to-app dialog title. -->
    <string name="lock_to_app_title">Use lock-to-app?</string>
    <!-- Lock-to-app dialog description. The $ is not actually shown or translated, it is a marker of where the recents icon shows up. -->
+2 −0
Original line number Diff line number Diff line
@@ -602,6 +602,8 @@
  <java-symbol type="string" name="kilobyteShort" />
  <java-symbol type="string" name="last_month" />
  <java-symbol type="string" name="launchBrowserDefault" />
  <java-symbol type="string" name="lock_to_app_toast" />
  <java-symbol type="string" name="lock_to_app_toast_locked" />
  <java-symbol type="string" name="lock_to_app_title" />
  <java-symbol type="string" name="lock_to_app_description" />
  <java-symbol type="string" name="lock_to_app_negative" />
+4 −2
Original line number Diff line number Diff line
@@ -3721,6 +3721,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            // Do not allow task to finish in Lock Task mode.
            if (tr == mStackSupervisor.mLockTaskModeTask) {
                if (rootR == r) {
                    mStackSupervisor.showLockTaskToast();
                    return false;
                }
            }
@@ -3875,7 +3876,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                // Do not allow task to finish in Lock Task mode.
                if (r.task == mStackSupervisor.mLockTaskModeTask) {
                    if (rootR == r) {
                        Binder.restoreCallingIdentity(origId);
                        mStackSupervisor.showLockTaskToast();
                        return false;
                    }
                }
@@ -7495,6 +7496,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                    return;
                }
                if (mStackSupervisor.isLockTaskModeViolation(task)) {
                    mStackSupervisor.showLockTaskToast();
                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
                    return;
                }
@@ -7749,7 +7751,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
                        throw new IllegalArgumentException("Invalid task, not in foreground");
                    }
                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
                }
            }
        } finally {
+10 −2
Original line number Diff line number Diff line
@@ -262,6 +262,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
    /** If non-null then the task specified remains in front and no other tasks may be started
     * until the task exits or #stopLockTaskMode() is called. */
    TaskRecord mLockTaskModeTask;
    /** Whether lock task has been entered by an authorized app and cannot
     * be exited. */
    private boolean mLockTaskIsLocked;
    /**
     * Notifies the user when entering/exiting lock-task.
     */
@@ -1670,6 +1673,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
                        : findActivityLocked(intent, r.info);
                if (intentActivity != null) {
                    if (isLockTaskModeViolation(intentActivity.task)) {
                        showLockTaskToast();
                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
                    }
@@ -3028,7 +3032,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return list;
    }

    void setLockTaskModeLocked(TaskRecord task, boolean showHomeRecents) {
    void showLockTaskToast() {
        mLockTaskNotify.showToast(mLockTaskIsLocked);
    }

    void setLockTaskModeLocked(TaskRecord task, boolean isLocked) {
        if (task == null) {
            // Take out of lock task mode if necessary
            if (mLockTaskModeTask != null) {
@@ -3052,7 +3060,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
        lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
        lockTaskMsg.arg1 = mLockTaskModeTask.userId;
        lockTaskMsg.what = LOCK_TASK_START_MSG;
        lockTaskMsg.arg2 = showHomeRecents ? 1 : 0;
        lockTaskMsg.arg2 = !isLocked ? 1 : 0;
        mHandler.sendMessage(lockTaskMsg);
    }

+51 −0
Original line number Diff line number Diff line
@@ -20,9 +20,15 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.util.DisplayMetrics;
import android.util.Slog;
import android.view.Gravity;
@@ -31,6 +37,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.R;

@@ -57,6 +65,45 @@ public class LockTaskNotify {
                mContext.getSystemService(Context.WINDOW_SERVICE);
    }

    public void showToast(boolean isLocked) {
        mHandler.obtainMessage(H.SHOW_TOAST, isLocked ? 1 : 0, 0 /* Not used */).sendToTarget();
    }

    public void handleShowToast(boolean isLocked) {
        final Resources r = Resources.getSystem();
        String text = mContext.getString(isLocked
                ? R.string.lock_to_app_toast_locked : R.string.lock_to_app_toast);
        Toast toast = Toast.makeText(mContext, text, Toast.LENGTH_LONG);
        TextView tv = (TextView) toast.getView().findViewById(R.id.message);

        if (isLocked) {
            tv.setText(text);
        } else {
            final SpannableString formattedText =
                    new SpannableString(text.replace('$', ' '));
            final ImageSpan imageSpan = new ImageSpan(mContext,
                    BitmapFactory.decodeResource(r, R.drawable.ic_recent),
                    DynamicDrawableSpan.ALIGN_BOTTOM);
            final int index = text.indexOf('$');
            if (index >= 0) {
                formattedText.setSpan(imageSpan, index, index + 1,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }

            // Make icon fit.
            final float width = imageSpan.getDrawable().getIntrinsicWidth();
            final float height = imageSpan.getDrawable().getIntrinsicHeight();
            final int lineHeight = tv.getLineHeight();
            imageSpan.getDrawable().setBounds(0, 0, (int) (lineHeight * width / height),
                    lineHeight);

            tv.setText(formattedText);
        }


        toast.show();
    }

    public void show(boolean starting) {
        mIsStarting = starting;
        mHandler.obtainMessage(H.SHOW).sendToTarget();
@@ -169,6 +216,7 @@ public class LockTaskNotify {
    private final class H extends Handler {
        private static final int SHOW = 1;
        private static final int HIDE = 2;
        private static final int SHOW_TOAST = 3;

        @Override
        public void handleMessage(Message msg) {
@@ -179,6 +227,9 @@ public class LockTaskNotify {
                case HIDE:
                    handleHide();
                    break;
                case SHOW_TOAST:
                    handleShowToast(msg.arg1 != 0);
                    break;
            }
        }
    }