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

Commit edd3d651 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Revert "Q Upstream: Use ParcelFileDescriptor for storing large clip...

Merge "Revert "Q Upstream: Use ParcelFileDescriptor for storing large clip data."" into rvc-dev am: 046df72d am: a3ccb11d

Change-Id: I7c17027ad23365b2b1a0c063ae77fe2d09e78bf4
parents f937acbc a3ccb11d
Loading
Loading
Loading
Loading
+3 −67
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.StrictMode;
import android.text.Html;
@@ -171,11 +170,6 @@ public class ClipData implements Parcelable {
    static final String[] MIMETYPES_TEXT_INTENT = new String[] {
        ClipDescription.MIMETYPE_TEXT_INTENT };

    // Constants used in {@link #writeHtmlTextToParcel}.
    static final int PARCEL_MAX_SIZE_BYTES = 800 * 1024;
    static final int PARCEL_TYPE_STRING = 0;
    static final int PARCEL_TYPE_PFD = 1;

    final ClipDescription mClipDescription;

    final Bitmap mIcon;
@@ -231,8 +225,7 @@ public class ClipData implements Parcelable {
         * with an alternative HTML formatted representation.  You <em>must</em>
         * supply a plain text representation in addition to HTML text; coercion
         * will not be done from HTML formatted text into plain text.
         * <p class="note"><strong>Note:</strong> It is strongly recommended to
         * use content: URI for sharing large clip data. Starting on API 30,
         * <p><strong>Warning:</strong> Use content: URI for sharing large clip data.
         * ClipData.Item doesn't accept an HTML text if it's larger than 800KB.
         * </p>
         */
@@ -1135,7 +1128,7 @@ public class ClipData implements Parcelable {
        for (int i=0; i<N; i++) {
            Item item = mItems.get(i);
            TextUtils.writeToParcel(item.mText, dest, flags);
            writeHtmlTextToParcel(item.mHtmlText, dest, flags);
            dest.writeString8(item.mHtmlText);
            if (item.mIntent != null) {
                dest.writeInt(1);
                item.mIntent.writeToParcel(dest, flags);
@@ -1162,7 +1155,7 @@ public class ClipData implements Parcelable {
        final int N = in.readInt();
        for (int i=0; i<N; i++) {
            CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            String htmlText = readHtmlTextFromParcel(in);
            String htmlText = in.readString8();
            Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null;
            Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null;
            mItems.add(new Item(text, htmlText, intent, uri));
@@ -1182,61 +1175,4 @@ public class ClipData implements Parcelable {
                return new ClipData[size];
            }
        };

    /**
     * Helper function for writing an HTML text into a parcel.
     * If the text size is larger than 400KB, it writes the text to a file descriptor to prevent the
     * parcel from exceeding 800KB binder size limit. {@link android.os.Binder#checkParcel()}
     * Otherwise, it directly writes the text into the parcel.
     * Note: This function is a workaround for existing applications that still use HTML for sharing
     * large clip data. We will ask application developers to use content: URI instead and remove
     * this function in API 30.
     */
    private static void writeHtmlTextToParcel(String text, Parcel dest, int flags) {
        byte[] textData = (text != null) ? text.getBytes() : new byte[0];
        if (textData.length > PARCEL_MAX_SIZE_BYTES / 2
                && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
            try {
                ParcelFileDescriptor pfd = ParcelFileDescriptor.fromData(textData, null);
                dest.writeInt(PARCEL_TYPE_PFD);
                dest.writeParcelable(pfd, flags);
            } catch (IOException e) {
                throw new IllegalStateException(
                        "Error creating the shared memory area: " + e.toString());
            }
        } else {
            dest.writeInt(PARCEL_TYPE_STRING);
            dest.writeString8(text);
        }
    }

    /**
     * Reads a text written by writeHtmlTextToParcel.
     */
    private static String readHtmlTextFromParcel(Parcel in) {
        if (in.readInt() == PARCEL_TYPE_STRING) {
            return in.readString8();
        }
        ParcelFileDescriptor pfd =
                in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
        if (pfd == null) {
            throw new IllegalStateException("Error reading ParcelFileDescriptor from Parcel");
        }
        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
        InputStreamReader reader = new InputStreamReader(fis);
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[4096];
        int numRead;
        try {
            while ((numRead = reader.read(buffer)) != -1) {
                builder.append(buffer, 0, numRead);
            }
            return builder.toString();
        } catch (IOException e) {
            throw new IllegalStateException(
                    "Error reading data from ParcelFileDescriptor: "  + e.toString());
        } finally {
            IoUtils.closeQuietly(fis);
        }
    }
}