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

Commit cb9ed7b8 authored by /e/ robot's avatar /e/ robot
Browse files

Merge remote-tracking branch 'origin/lineage-16.0' into v1-pie

parents 0996e6ad 6e7d07c3
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.widget;

import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY;
@@ -31,11 +32,13 @@ import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Px;
import android.annotation.RequiresPermission;
import android.annotation.Size;
import android.annotation.StringRes;
import android.annotation.StyleRes;
import android.annotation.XmlRes;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.assist.AssistStructure;
import android.content.ClipData;
@@ -72,6 +75,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelableParcel;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.BoringLayout;
import android.text.DynamicLayout;
@@ -723,6 +727,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener

    private InputFilter[] mFilters = NO_FILTERS;

    /**
     * To keep the information to indicate if there is necessary to restrict the power of
     * INTERACT_ACROSS_USERS_FULL.
     * <p>
     * SystemUI always run as user 0 to process all of direct reply. SystemUI has the poer of
     * INTERACT_ACROSS_USERS_FULL. However, all of the notifications not only belong to user 0 but
     * also to the other users in multiple user environment.
     * </p>
     *
     * @see #setRestrictedAcrossUser(boolean)
     */
    private boolean mIsRestrictedAcrossUser;

    private volatile Locale mCurrentSpellCheckerLocaleCache;

    // It is possible to have a selection even when mEditor is null (programmatically set, like when
@@ -10439,6 +10456,24 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                : mCurrentSpellCheckerLocaleCache;
    }

    /**
     * To notify the TextView to restricted the power of the app granted INTERACT_ACROSS_USERS_FULL
     * permission.
     * <p>
     * Most of applications should not granted the INTERACT_ACROSS_USERS_FULL permssion.
     * SystemUI is the special one that run in user 0 process to handle multiple user notification.
     * Unforunately, the power of INTERACT_ACROSS_USERS_FULL should be limited or restricted for
     * preventing from information leak.</p>
     * <p>This function call is called for SystemUI Keyguard and Notification.</p>
     *
     * @param isRestricted is true if the power of INTERACT_ACROSS_USERS_FULL should be limited.
     * @hide
     */
    @RequiresPermission(INTERACT_ACROSS_USERS_FULL)
    public final void setRestrictedAcrossUser(boolean isRestricted) {
        mIsRestrictedAcrossUser = isRestricted;
    }

    /**
     * This is a temporary method. Future versions may support multi-locale text.
     * Caveat: This method may not return the latest text services locale, but this should be
@@ -11647,6 +11682,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    }

    boolean canCut() {
        if (mIsRestrictedAcrossUser
                && UserHandle.myUserId() != ActivityManager.getCurrentUser()) {
            // When it's restricted, and the curren user is not the process user. It can't cut
            // because it may cut the text of the user 10 into the clipboard of user 0.
            return false;
        }
        if (hasPasswordTransformationMethod()) {
            return false;
        }
@@ -11660,6 +11701,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    }

    boolean canCopy() {
        if (mIsRestrictedAcrossUser
                && UserHandle.myUserId() != ActivityManager.getCurrentUser()) {
            // When it's restricted, and the curren user is not the process user. It can't copy
            // because it may copy the text of the user 10 to the clipboard of user 0.
            return false;
        }
        if (hasPasswordTransformationMethod()) {
            return false;
        }
@@ -11689,6 +11736,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    }

    boolean canPaste() {
        if (mIsRestrictedAcrossUser
                && UserHandle.myUserId() != ActivityManager.getCurrentUser()) {
            // When it's restricted, and the curren user is not the process user. It can't paste
            // because it may copy the text from the user 0 clipboard in current user is 10.
            return false;
        }
        return (mText instanceof Editable
                && mEditor != null && mEditor.mKeyListener != null
                && getSelectionStart() >= 0
+2 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView

    @Override
    protected void resetState() {
        mPasswordEntry.setRestrictedAcrossUser(true);
        mSecurityMessageDisplay.setMessage("");
        final boolean wasDisabled = mPasswordEntry.isEnabled();
        setPasswordEntryEnabled(true);
@@ -169,6 +170,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
                Context.INPUT_METHOD_SERVICE);

        mPasswordEntry = findViewById(getPasswordTextViewId());
        mPasswordEntry.setRestrictedAcrossUser(true);
        mPasswordEntryDisabler = new TextViewInputDisabler(mPasswordEntry);
        mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
        mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
+39 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.RemoteInput;
@@ -28,11 +29,14 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.Editable;
import android.text.InputType;
import android.text.SpannedString;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -45,6 +49,7 @@ import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.view.textclassifier.TextClassifier;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
@@ -187,11 +192,35 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
                LayoutInflater.from(context).inflate(R.layout.remote_input, root, false);
        v.mController = controller;
        v.mEntry = entry;
        v.mEditText.setRestrictedAcrossUser(true);
        v.setTag(VIEW_TAG);

        // Disable the TextClassifier to avoid cross user interactions.
        v.mEditText.setTextClassifier(TextClassifier.NO_OP);

        return v;
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback, int type) {
        try {
            UserHandle notificationUser = mEntry.notification.getUser();
            UserHandle currentUser = UserHandle.of(ActivityManager.getCurrentUser());
            if (!UserHandle.ALL.equals(notificationUser)
                    && !currentUser.equals(notificationUser)) {
                // If this happens to be a selection action mode, a non-NO_OP TextClassifier could
                // leak data across users. This widget uses TextClassifier.NO_OP so this is fine.
                // Log the security fix.
                android.util.EventLog.writeEvent(0x534e4554, "123232892", -1, "");
            }
        } catch (Throwable t) {
            // Avoid crashing because of this log attempt.
            Log.i(TAG, "Error attempting to log security fix for bug 123232892", t);

        }
        return super.startActionMode(callback, type);
    }

    @Override
    public void onClick(View v) {
        if (v == mSendButton) {
@@ -292,6 +321,16 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
        if (mWrapper != null) {
            mWrapper.setRemoteInputVisible(true);
        }

        // Disable suggestions on non-owner (secondary) user.
        // SpellCheckerService of primary user runs on secondary as well which shows
        // "Add to dictionary" dialog on the primary user. (See b/123232892)
        // Note: this doesn't affect work-profile users on P or older versions.
        if (UserHandle.myUserId() != ActivityManager.getCurrentUser()) {
            mEditText.setInputType(
                    mEditText.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
        }

        mEditText.setInnerFocusable(true);
        mEditText.mShowImeOnInputConnection = true;
        mEditText.setText(mEntry.remoteInputText);
+10 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
import android.view.textclassifier.TextClassifier;
import android.widget.EditText;
import android.widget.ImageButton;

@@ -109,4 +110,13 @@ public class RemoteInputViewTest extends SysuiTestCase {
        mView.setVisibility(View.INVISIBLE);
        mView.setVisibility(View.VISIBLE);
    }

    @Test
    public void testUsesNoOpTextClassifier() {
        RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).build();
        mView.setRemoteInput(new RemoteInput[]{input}, input);

        EditText editText = mView.findViewById(R.id.remote_input_text);
        assertEquals(TextClassifier.NO_OP, editText.getTextClassifier());
    }
}
+4 −7
Original line number Diff line number Diff line
@@ -2356,9 +2356,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
    }

    private boolean networkRequiresValidation(NetworkAgentInfo nai) {
        return NetworkMonitor.isValidationRequired(
                mDefaultRequest.networkCapabilities, nai.networkCapabilities);
    private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
        return nai.networkMonitor.isPrivateDnsValidationRequired();
    }

    private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
@@ -2376,16 +2375,14 @@ public class ConnectivityService extends IConnectivityManager.Stub

        for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
            handlePerNetworkPrivateDnsConfig(nai, cfg);
            if (networkRequiresValidation(nai)) {
            if (networkRequiresPrivateDnsValidation(nai)) {
                handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
            }
        }
    }

    private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
        // Private DNS only ever applies to networks that might provide
        // Internet access and therefore also require validation.
        if (!networkRequiresValidation(nai)) return;
        if (!networkRequiresPrivateDnsValidation(nai)) return;

        // Notify the NetworkMonitor thread in case it needs to cancel or
        // schedule DNS resolutions. If a DNS resolution is required the
Loading