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

Commit f984307b authored by Xin Li's avatar Xin Li
Browse files

Merge UP1A.231005.007

Bug: 291102124
Merged-In: Idcbd0f2ba87290f090d693f0a64cb46fe8270b95
Change-Id: I64a40b9b56d5b18f8423d53abb5c1ba4429d5037
parents 24758d1b 299fe6f5
Loading
Loading
Loading
Loading
+23 −9
Original line number Diff line number Diff line
@@ -511,17 +511,31 @@ public class DatabaseUtils {
     */
    public static void appendEscapedSQLString(StringBuilder sb, String sqlString) {
        sb.append('\'');
        if (sqlString.indexOf('\'') != -1) {
        int length = sqlString.length();
        for (int i = 0; i < length; i++) {
            char c = sqlString.charAt(i);
            if (Character.isHighSurrogate(c)) {
                if (i == length - 1) {
                    continue;
                }
                if (Character.isLowSurrogate(sqlString.charAt(i + 1))) {
                    // add them both
                    sb.append(c);
                    sb.append(sqlString.charAt(i + 1));
                    continue;
                } else {
                    // this is a lone surrogate, skip it
                    continue;
                }
            }
            if (Character.isLowSurrogate(c)) {
                continue;
            }
            if (c == '\'') {
                sb.append('\'');
            }
            sb.append(c);
        }
        } else
            sb.append(sqlString);
        sb.append('\'');
    }

+17 −19
Original line number Diff line number Diff line
@@ -882,10 +882,11 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
        }

        static Uri readFrom(Parcel parcel) {
            final StringUri stringUri = new StringUri(parcel.readString8());
            return new OpaqueUri(
                parcel.readString8(),
                Part.readFrom(parcel),
                Part.readFrom(parcel)
                stringUri.parseScheme(),
                stringUri.getSsp(),
                stringUri.getFragmentPart()
            );
        }

@@ -895,9 +896,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {

        public void writeToParcel(Parcel parcel, int flags) {
            parcel.writeInt(TYPE_ID);
            parcel.writeString8(scheme);
            ssp.writeTo(parcel);
            fragment.writeTo(parcel);
            parcel.writeString8(toString());
        }

        public boolean isHierarchical() {
@@ -1196,22 +1195,25 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
                Part query, Part fragment) {
            this.scheme = scheme;
            this.authority = Part.nonNull(authority);
            this.path = path == null ? PathPart.NULL : path;
            this.path = generatePath(path);
            this.query = Part.nonNull(query);
            this.fragment = Part.nonNull(fragment);
        }

        static Uri readFrom(Parcel parcel) {
            final String scheme = parcel.readString8();
            final Part authority = Part.readFrom(parcel);
        private PathPart generatePath(PathPart originalPath) {
            // In RFC3986 the path should be determined based on whether there is a scheme or
            // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3).
            final boolean hasSchemeOrAuthority =
                    (scheme != null && scheme.length() > 0) || !authority.isEmpty();
            final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel);
            final Part query = Part.readFrom(parcel);
            final Part fragment = Part.readFrom(parcel);
            return new HierarchicalUri(scheme, authority, path, query, fragment);
            final PathPart newPath = hasSchemeOrAuthority ? PathPart.makeAbsolute(originalPath)
                                                          : originalPath;
            return newPath == null ? PathPart.NULL : newPath;
        }

        static Uri readFrom(Parcel parcel) {
            final StringUri stringUri = new StringUri(parcel.readString8());
            return new HierarchicalUri(stringUri.getScheme(), stringUri.getAuthorityPart(),
                    stringUri.getPathPart(), stringUri.getQueryPart(), stringUri.getFragmentPart());
        }

        public int describeContents() {
@@ -1220,11 +1222,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {

        public void writeToParcel(Parcel parcel, int flags) {
            parcel.writeInt(TYPE_ID);
            parcel.writeString8(scheme);
            authority.writeTo(parcel);
            path.writeTo(parcel);
            query.writeTo(parcel);
            fragment.writeTo(parcel);
            parcel.writeString8(toString());
        }

        public boolean isHierarchical() {
+32 −33
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.internal.inputmethod.ImeTracing;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.util.function.TriFunction;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -77,7 +78,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;

/**
 * Implements {@link WindowInsetsController} on the client.
@@ -621,7 +621,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    private final InsetsState mLastDispatchedState = new InsetsState();

    private final Rect mFrame = new Rect();
    private final BiFunction<InsetsController, InsetsSource, InsetsSourceConsumer> mConsumerCreator;
    private final TriFunction<InsetsController, Integer, Integer, InsetsSourceConsumer>
            mConsumerCreator;
    private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>();
    private final InsetsSourceConsumer mImeSourceConsumer;
    private final Host mHost;
@@ -689,13 +690,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

                    // Don't change the indexes of the sources while traversing. Remove it later.
                    mPendingRemoveIndexes.add(index1);

                    // Remove the consumer as well except the IME one. IME consumer should always
                    // be there since we need to communicate with InputMethodManager no matter we
                    // have the source or not.
                    if (source1.getType() != ime()) {
                        mSourceConsumers.remove(source1.getId());
                    }
                }

                @Override
@@ -750,12 +744,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            };

    public InsetsController(Host host) {
        this(host, (controller, source) -> {
            if (source.getType() == ime()) {
                return new ImeInsetsSourceConsumer(source.getId(), controller.mState,
        this(host, (controller, id, type) -> {
            if (type == ime()) {
                return new ImeInsetsSourceConsumer(id, controller.mState,
                        Transaction::new, controller);
            } else {
                return new InsetsSourceConsumer(source.getId(), source.getType(), controller.mState,
                return new InsetsSourceConsumer(id, type, controller.mState,
                        Transaction::new, controller);
            }
        }, host.getHandler());
@@ -763,7 +757,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

    @VisibleForTesting
    public InsetsController(Host host,
            BiFunction<InsetsController, InsetsSource, InsetsSourceConsumer> consumerCreator,
            TriFunction<InsetsController, Integer, Integer, InsetsSourceConsumer> consumerCreator,
            Handler handler) {
        mHost = host;
        mConsumerCreator = consumerCreator;
@@ -815,7 +809,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        };

        // Make mImeSourceConsumer always non-null.
        mImeSourceConsumer = getSourceConsumer(new InsetsSource(ID_IME, ime()));
        mImeSourceConsumer = getSourceConsumer(ID_IME, ime());
    }

    @VisibleForTesting
@@ -893,7 +887,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    cancelledUserAnimationTypes[0] |= type;
                }
            }
            getSourceConsumer(source).updateSource(source, animationType);
            final InsetsSourceConsumer consumer = mSourceConsumers.get(source.getId());
            if (consumer != null) {
                consumer.updateSource(source, animationType);
            } else {
                mState.addSource(source);
            }
            existingTypes |= type;
            if (source.isVisible()) {
                visibleTypes |= type;
@@ -997,8 +996,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        @InsetsType int controllableTypes = 0;
        int consumedControlCount = 0;
        final int[] showTypes = new int[1];
        final int[] hideTypes = new int[1];
        final @InsetsType int[] showTypes = new int[1];
        final @InsetsType int[] hideTypes = new int[1];

        // Ensure to update all existing source consumers
        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
@@ -1014,15 +1013,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            consumer.setControl(control, showTypes, hideTypes);
        }

        // Ensure to create source consumers if not available yet.
        if (consumedControlCount != mTmpControlArray.size()) {
            // Whoops! The server sent us some controls without sending corresponding sources.
            for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
                final InsetsSourceControl control = mTmpControlArray.valueAt(i);
                final InsetsSourceConsumer consumer = mSourceConsumers.get(control.getId());
                if (consumer == null) {
                    control.release(SurfaceControl::release);
                    Log.e(TAG, control + " has no consumer.");
                }
                getSourceConsumer(control.getId(), control.getType())
                        .setControl(control, showTypes, hideTypes);
            }
        }

@@ -1587,6 +1583,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (type == ime()) {
            abortPendingImeControlRequest();
        }
        if (consumer.getType() != ime()) {
            // IME consumer should always be there since we need to communicate with
            // InputMethodManager no matter we have the control or not.
            mSourceConsumers.remove(consumer.getId());
        }
    }

    private void cancelAnimation(InsetsAnimationControlRunner control, boolean invokeCallback) {
@@ -1640,21 +1641,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    }

    @VisibleForTesting
    public @NonNull InsetsSourceConsumer getSourceConsumer(InsetsSource source) {
        final int sourceId = source.getId();
        InsetsSourceConsumer consumer = mSourceConsumers.get(sourceId);
    public @NonNull InsetsSourceConsumer getSourceConsumer(int id, int type) {
        InsetsSourceConsumer consumer = mSourceConsumers.get(id);
        if (consumer != null) {
            return consumer;
        }
        if (source.getType() == ime() && mImeSourceConsumer != null) {
        if (type == ime() && mImeSourceConsumer != null) {
            // WindowInsets.Type.ime() should be only provided by one source.
            mSourceConsumers.remove(mImeSourceConsumer.getId());
            consumer = mImeSourceConsumer;
            consumer.setId(sourceId);
            consumer.setId(id);
        } else {
            consumer = mConsumerCreator.apply(this, source);
            consumer = mConsumerCreator.apply(this, id, type);
        }
        mSourceConsumers.put(sourceId, consumer);
        mSourceConsumers.put(id, consumer);
        return consumer;
    }

@@ -1663,8 +1663,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        return mImeSourceConsumer;
    }

    @VisibleForTesting
    public void notifyVisibilityChanged() {
    void notifyVisibilityChanged() {
        mHost.notifyInsetsChanged();
    }

+6 −3
Original line number Diff line number Diff line
@@ -149,9 +149,12 @@ public class InsetsSourceConsumer {
            // Check if we need to restore server visibility.
            final InsetsSource localSource = mState.peekSource(mId);
            final InsetsSource serverSource = mController.getLastDispatchedState().peekSource(mId);
            if (localSource != null && serverSource != null
                    && localSource.isVisible() != serverSource.isVisible()) {
                localSource.setVisible(serverSource.isVisible());
            final boolean localVisible = localSource != null && localSource.isVisible();
            final boolean serverVisible = serverSource != null && serverSource.isVisible();
            if (localSource != null) {
                localSource.setVisible(serverVisible);
            }
            if (localVisible != serverVisible) {
                mController.notifyVisibilityChanged();
            }
        } else {
+9 −2
Original line number Diff line number Diff line
@@ -42,6 +42,13 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi
        return NULL;
    }

    // b/274058082: Pass a copy of the key character map to avoid concurrent
    // access
    std::shared_ptr<KeyCharacterMap> map = deviceInfo.getKeyCharacterMap();
    if (map != nullptr) {
        map = std::make_shared<KeyCharacterMap>(*map);
    }

    ScopedLocalRef<jstring> descriptorObj(env,
            env->NewStringUTF(deviceInfo.getIdentifier().descriptor.c_str()));
    if (!descriptorObj.get()) {
@@ -62,7 +69,7 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi

    ScopedLocalRef<jobject> kcmObj(env,
                                   android_view_KeyCharacterMap_create(env, deviceInfo.getId(),
            deviceInfo.getKeyCharacterMap()));
                                                                       map));
    if (!kcmObj.get()) {
        return NULL;
    }
Loading