1 /* 2 * Copyright 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.pdf.data; 18 19 import android.annotation.SuppressLint; 20 import android.os.Build; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 24 import androidx.annotation.RequiresApi; 25 import androidx.annotation.RestrictTo; 26 import androidx.pdf.models.SelectionBoundary; 27 28 import org.jspecify.annotations.NonNull; 29 30 import java.util.Objects; 31 32 /** Represents the selection of part of a piece of text - a start and a stop. */ 33 @RestrictTo(RestrictTo.Scope.LIBRARY) 34 public class TextSelection implements Parcelable { 35 36 public static final TextSelection EMPTY_SELECTION = new TextSelection( 37 SelectionBoundary.PAGE_START, SelectionBoundary.PAGE_START); 38 39 public static final Creator<TextSelection> CREATOR = new Creator<TextSelection>() { 40 @SuppressLint("ObsoleteSdkInt") //TODO: Remove after sdk extension 13 release 41 @Override 42 public TextSelection createFromParcel(Parcel parcel) { 43 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 44 return Api33Impl.createFromParcel(parcel); 45 } else { 46 return ApiPre33Impl.createFromParcel(parcel); 47 } 48 } 49 50 @Override 51 public TextSelection[] newArray(int size) { 52 return new TextSelection[size]; 53 } 54 }; 55 56 /** The start of the selection - index is inclusive. */ 57 private final SelectionBoundary mStart; 58 59 /** The end of the selection - index is exclusive. */ 60 private final SelectionBoundary mStop; 61 TextSelection(@onNull SelectionBoundary start, @NonNull SelectionBoundary stop)62 public TextSelection(@NonNull SelectionBoundary start, @NonNull SelectionBoundary stop) { 63 this.mStart = start; 64 this.mStop = stop; 65 } 66 getStart()67 public @NonNull SelectionBoundary getStart() { 68 return mStart; 69 } 70 getStop()71 public @NonNull SelectionBoundary getStop() { 72 return mStop; 73 } 74 75 @Override toString()76 public @NonNull String toString() { 77 return String.format("TextSelection(start=%s, stop=%s)", mStart, mStop); 78 } 79 80 @SuppressLint("ObsoleteSdkInt") //TODO: Remove after sdk extension 13 release 81 @Override writeToParcel(@onNull Parcel parcel, int flags)82 public void writeToParcel(@NonNull Parcel parcel, int flags) { 83 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 84 Api33Impl.writeToParcel(this, parcel, flags); 85 } else { 86 ApiPre33Impl.writeToParcel(this, parcel, flags); 87 } 88 } 89 90 @Override describeContents()91 public int describeContents() { 92 return 0; 93 } 94 95 @SuppressLint("ObsoleteSdkInt") //TODO: Remove after sdk extension 13 release 96 @RequiresApi(api = Build.VERSION_CODES.TIRAMISU) // API 33 97 private static final class Api33Impl { 98 Api33Impl()99 private Api33Impl() { 100 } // Prevent instantiation 101 createFromParcel(Parcel parcel)102 public static TextSelection createFromParcel(Parcel parcel) { 103 SelectionBoundary start = parcel.readParcelable( 104 SelectionBoundary.class.getClassLoader(), SelectionBoundary.class); 105 SelectionBoundary stop = parcel.readParcelable( 106 SelectionBoundary.class.getClassLoader(), SelectionBoundary.class); 107 108 Objects.requireNonNull(start, "Start SelectionBoundary cannot be null"); 109 Objects.requireNonNull(stop, "Stop SelectionBoundary cannot be null"); 110 111 return new TextSelection(start, stop); 112 } 113 writeToParcel( TextSelection selection, @NonNull Parcel parcel, int flags )114 public static void writeToParcel( 115 TextSelection selection, 116 @NonNull Parcel parcel, 117 int flags 118 ) { 119 parcel.writeParcelable(selection.mStart, flags); 120 parcel.writeParcelable(selection.mStop, flags); 121 } 122 } 123 124 private static final class ApiPre33Impl { 125 ApiPre33Impl()126 private ApiPre33Impl() { 127 } // Prevent instantiation 128 createFromParcel(Parcel parcel)129 public static TextSelection createFromParcel(Parcel parcel) { 130 SelectionBoundary start = SelectionBoundary.CREATOR.createFromParcel(parcel); 131 SelectionBoundary stop = SelectionBoundary.CREATOR.createFromParcel(parcel); 132 133 Objects.requireNonNull(start, "Start SelectionBoundary cannot be null"); 134 Objects.requireNonNull(stop, "Stop SelectionBoundary cannot be null"); 135 136 return new TextSelection(start, stop); 137 } 138 writeToParcel( TextSelection selection, @NonNull Parcel parcel, int flags )139 public static void writeToParcel( 140 TextSelection selection, 141 @NonNull Parcel parcel, 142 int flags 143 ) { 144 selection.mStart.writeToParcel(parcel, flags); 145 selection.mStop.writeToParcel(parcel, flags); 146 } 147 } 148 } 149