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

Commit a0030632 authored by Svet Ganov's avatar Svet Ganov Committed by android-build-merger
Browse files

Prevent apps to overlay other apps via toast windows am: dc24f937

am: fd8ffb62

Change-Id: I94077046a2f38a7cffce5cc73f805f671c35db23
parents 0d287f18 fd8ffb62
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -19,7 +19,7 @@ package android.app;


/** @hide */
/** @hide */
oneway interface ITransientNotification {
oneway interface ITransientNotification {
    void show();
    void show(IBinder windowToken);
    void hide();
    void hide();
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -233,6 +233,7 @@ public class SurfaceView extends View {
        mSession = getWindowSession();
        mSession = getWindowSession();
        mLayout.token = getWindowToken();
        mLayout.token = getWindowToken();
        mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle());
        mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle());
        mLayout.packageName = mContext.getOpPackageName();
        mViewVisibility = getVisibility() == VISIBLE;
        mViewVisibility = getVisibility() == VISIBLE;


        if (!mGlobalListenersAdded) {
        if (!mGlobalListenersAdded) {
+10 −6
Original line number Original line Diff line number Diff line
@@ -1734,14 +1734,18 @@ public interface WindowManager extends ViewManager {
        public CharSequence accessibilityTitle;
        public CharSequence accessibilityTitle;


        /**
        /**
         * Sets a timeout in milliseconds before which the window will be removed
         * Sets a timeout in milliseconds before which the window will be hidden
         * by the window manager. Useful for transient notifications like toasts
         * by the window manager. Useful for transient notifications like toasts
         * so we don't have to rely on client cooperation to ensure the window
         * so we don't have to rely on client cooperation to ensure the window
         * is removed. Must be specified at window creation time.
         * is hidden. Must be specified at window creation time. Note that apps
         * are not prepared to handle their windows being removed without their
         * explicit request and may try to interact with the removed window
         * resulting in undefined behavior and crashes. Therefore, we do hide
         * such windows to prevent them from overlaying other apps.
         *
         *
         * @hide
         * @hide
         */
         */
        public long removeTimeoutMilliseconds = -1;
        public long hideTimeoutMilliseconds = -1;


        public LayoutParams() {
        public LayoutParams() {
            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
@@ -1877,7 +1881,7 @@ public interface WindowManager extends ViewManager {
            out.writeInt(needsMenuKey);
            out.writeInt(needsMenuKey);
            out.writeInt(accessibilityIdOfAnchor);
            out.writeInt(accessibilityIdOfAnchor);
            TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
            TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
            out.writeLong(removeTimeoutMilliseconds);
            out.writeLong(hideTimeoutMilliseconds);
        }
        }


        public static final Parcelable.Creator<LayoutParams> CREATOR
        public static final Parcelable.Creator<LayoutParams> CREATOR
@@ -1931,7 +1935,7 @@ public interface WindowManager extends ViewManager {
            needsMenuKey = in.readInt();
            needsMenuKey = in.readInt();
            accessibilityIdOfAnchor = in.readInt();
            accessibilityIdOfAnchor = in.readInt();
            accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            removeTimeoutMilliseconds = in.readLong();
            hideTimeoutMilliseconds = in.readLong();
        }
        }


        @SuppressWarnings({"PointlessBitwiseExpression"})
        @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -2153,7 +2157,7 @@ public interface WindowManager extends ViewManager {
            }
            }


            // This can't change, it's only set at window creation time.
            // This can't change, it's only set at window creation time.
            removeTimeoutMilliseconds = o.removeTimeoutMilliseconds;
            hideTimeoutMilliseconds = o.hideTimeoutMilliseconds;


            return changes;
            return changes;
        }
        }
+14 −12
Original line number Original line Diff line number Diff line
@@ -25,6 +25,8 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.util.Log;
import android.util.Log;
@@ -326,13 +328,6 @@ public class Toast {
    }
    }


    private static class TN extends ITransientNotification.Stub {
    private static class TN extends ITransientNotification.Stub {
        final Runnable mShow = new Runnable() {
            @Override
            public void run() {
                handleShow();
            }
        };

        final Runnable mHide = new Runnable() {
        final Runnable mHide = new Runnable() {
            @Override
            @Override
            public void run() {
            public void run() {
@@ -343,7 +338,13 @@ public class Toast {
        };
        };


        private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
        private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
        final Handler mHandler = new Handler();
        final Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                IBinder token = (IBinder) msg.obj;
                handleShow(token);
            }
        };


        int mGravity;
        int mGravity;
        int mX, mY;
        int mX, mY;
@@ -379,9 +380,9 @@ public class Toast {
         * schedule handleShow into the right thread
         * schedule handleShow into the right thread
         */
         */
        @Override
        @Override
        public void show() {
        public void show(IBinder windowToken) {
            if (localLOGV) Log.v(TAG, "SHOW: " + this);
            if (localLOGV) Log.v(TAG, "SHOW: " + this);
            mHandler.post(mShow);
            mHandler.obtainMessage(0, windowToken).sendToTarget();
        }
        }


        /**
        /**
@@ -393,7 +394,7 @@ public class Toast {
            mHandler.post(mHide);
            mHandler.post(mHide);
        }
        }


        public void handleShow() {
        public void handleShow(IBinder windowToken) {
            if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
            if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
                    + " mNextView=" + mNextView);
                    + " mNextView=" + mNextView);
            if (mView != mNextView) {
            if (mView != mNextView) {
@@ -422,8 +423,9 @@ public class Toast {
                mParams.verticalMargin = mVerticalMargin;
                mParams.verticalMargin = mVerticalMargin;
                mParams.horizontalMargin = mHorizontalMargin;
                mParams.horizontalMargin = mHorizontalMargin;
                mParams.packageName = packageName;
                mParams.packageName = packageName;
                mParams.removeTimeoutMilliseconds = mDuration ==
                mParams.hideTimeoutMilliseconds = mDuration ==
                    Toast.LENGTH_LONG ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT;
                    Toast.LENGTH_LONG ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT;
                mParams.token = windowToken;
                if (mView.getParent() != null) {
                if (mView.getParent() != null) {
                    if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
                    if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
                    mWM.removeView(mView);
                    mWM.removeView(mView);
+23 −12
Original line number Original line Diff line number Diff line
@@ -58,7 +58,6 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
import android.app.NotificationManager.Policy;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.app.StatusBarManager;
import android.app.StatusBarManager;
import android.app.backup.BackupManager;
import android.app.backup.BackupManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEvents;
@@ -93,7 +92,6 @@ import android.os.IBinder;
import android.os.IInterface;
import android.os.IInterface;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.Parcelable;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemClock;
@@ -122,6 +120,8 @@ import android.util.Log;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArray;
import android.util.Xml;
import android.util.Xml;
import android.view.WindowManager;
import android.view.WindowManagerInternal;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
import android.widget.Toast;
@@ -138,6 +138,7 @@ import com.android.server.SystemService;
import com.android.server.lights.Light;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LightsManager;
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.policy.PhoneWindowManager;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.vr.VrManagerInternal;
import com.android.server.vr.VrManagerInternal;
import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.server.notification.ManagedServices.UserProfiles;
@@ -193,7 +194,7 @@ public class NotificationManagerService extends SystemService {
    private static final int MESSAGE_RECONSIDER_RANKING = 1000;
    private static final int MESSAGE_RECONSIDER_RANKING = 1000;
    private static final int MESSAGE_RANKING_SORT = 1001;
    private static final int MESSAGE_RANKING_SORT = 1001;


    static final int LONG_DELAY = 3500; // 3.5 seconds
    static final int LONG_DELAY = PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
    static final int SHORT_DELAY = 2000; // 2 seconds
    static final int SHORT_DELAY = 2000; // 2 seconds


    static final long[] DEFAULT_VIBRATE_PATTERN = {0, 250, 250, 250};
    static final long[] DEFAULT_VIBRATE_PATTERN = {0, 250, 250, 250};
@@ -232,6 +233,7 @@ public class NotificationManagerService extends SystemService {
    @Nullable StatusBarManagerInternal mStatusBar;
    @Nullable StatusBarManagerInternal mStatusBar;
    Vibrator mVibrator;
    Vibrator mVibrator;
    private VrManagerInternal mVrManagerInternal;
    private VrManagerInternal mVrManagerInternal;
    private WindowManagerInternal mWindowManagerInternal;


    final IBinder mForegroundToken = new Binder();
    final IBinder mForegroundToken = new Binder();
    private Handler mHandler;
    private Handler mHandler;
@@ -452,13 +454,15 @@ public class NotificationManagerService extends SystemService {
        final String pkg;
        final String pkg;
        final ITransientNotification callback;
        final ITransientNotification callback;
        int duration;
        int duration;
        Binder token;


        ToastRecord(int pid, String pkg, ITransientNotification callback, int duration)
        ToastRecord(int pid, String pkg, ITransientNotification callback, int duration,
        {
                    Binder token) {
            this.pid = pid;
            this.pid = pid;
            this.pkg = pkg;
            this.pkg = pkg;
            this.callback = callback;
            this.callback = callback;
            this.duration = duration;
            this.duration = duration;
            this.token = token;
        }
        }


        void update(int duration) {
        void update(int duration) {
@@ -1125,6 +1129,7 @@ public class NotificationManagerService extends SystemService {
            mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
            mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
            mVrManagerInternal = getLocalService(VrManagerInternal.class);
            mVrManagerInternal = getLocalService(VrManagerInternal.class);
            mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
            mZenModeHelper.onSystemReady();
            mZenModeHelper.onSystemReady();
        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
            // This observer will force an update when observe is called, causing us to
            // This observer will force an update when observe is called, causing us to
@@ -1325,10 +1330,13 @@ public class NotificationManagerService extends SystemService {
                            }
                            }
                        }
                        }


                        record = new ToastRecord(callingPid, pkg, callback, duration);
                        Binder token = new Binder();
                        mWindowManagerInternal.addWindowToken(token,
                                WindowManager.LayoutParams.TYPE_TOAST);
                        record = new ToastRecord(callingPid, pkg, callback, duration, token);
                        mToastQueue.add(record);
                        mToastQueue.add(record);
                        index = mToastQueue.size() - 1;
                        index = mToastQueue.size() - 1;
                        keepProcessAliveLocked(callingPid);
                        keepProcessAliveIfNeededLocked(callingPid);
                    }
                    }
                    // If it's at index 0, it's the current toast.  It doesn't matter if it's
                    // If it's at index 0, it's the current toast.  It doesn't matter if it's
                    // new or just been updated.  Call back and tell it to show itself.
                    // new or just been updated.  Call back and tell it to show itself.
@@ -2987,7 +2995,7 @@ public class NotificationManagerService extends SystemService {
        while (record != null) {
        while (record != null) {
            if (DBG) Slog.d(TAG, "Show pkg=" + record.pkg + " callback=" + record.callback);
            if (DBG) Slog.d(TAG, "Show pkg=" + record.pkg + " callback=" + record.callback);
            try {
            try {
                record.callback.show();
                record.callback.show(record.token);
                scheduleTimeoutLocked(record);
                scheduleTimeoutLocked(record);
                return;
                return;
            } catch (RemoteException e) {
            } catch (RemoteException e) {
@@ -2998,7 +3006,7 @@ public class NotificationManagerService extends SystemService {
                if (index >= 0) {
                if (index >= 0) {
                    mToastQueue.remove(index);
                    mToastQueue.remove(index);
                }
                }
                keepProcessAliveLocked(record.pid);
                keepProcessAliveIfNeededLocked(record.pid);
                if (mToastQueue.size() > 0) {
                if (mToastQueue.size() > 0) {
                    record = mToastQueue.get(0);
                    record = mToastQueue.get(0);
                } else {
                } else {
@@ -3018,8 +3026,11 @@ public class NotificationManagerService extends SystemService {
            // don't worry about this, we're about to remove it from
            // don't worry about this, we're about to remove it from
            // the list anyway
            // the list anyway
        }
        }
        mToastQueue.remove(index);

        keepProcessAliveLocked(record.pid);
        ToastRecord lastToast = mToastQueue.remove(index);
        mWindowManagerInternal.removeWindowToken(lastToast.token, true);

        keepProcessAliveIfNeededLocked(record.pid);
        if (mToastQueue.size() > 0) {
        if (mToastQueue.size() > 0) {
            // Show the next one. If the callback fails, this will remove
            // Show the next one. If the callback fails, this will remove
            // it from the list, so don't assume that the list hasn't changed
            // it from the list, so don't assume that the list hasn't changed
@@ -3063,7 +3074,7 @@ public class NotificationManagerService extends SystemService {
    }
    }


    // lock on mToastQueue
    // lock on mToastQueue
    void keepProcessAliveLocked(int pid)
    void keepProcessAliveIfNeededLocked(int pid)
    {
    {
        int toastCount = 0; // toasts from this pid
        int toastCount = 0; // toasts from this pid
        ArrayList<ToastRecord> list = mToastQueue;
        ArrayList<ToastRecord> list = mToastQueue;
Loading