375 lines
14 KiB
Java
375 lines
14 KiB
Java
package androidx.core.widget;
|
|
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.pm.ResolveInfo;
|
|
import android.graphics.Paint;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.icu.text.DecimalFormatSymbols;
|
|
import android.os.Build;
|
|
import android.text.Editable;
|
|
import android.text.TextDirectionHeuristic;
|
|
import android.text.TextDirectionHeuristics;
|
|
import android.text.TextPaint;
|
|
import android.text.method.PasswordTransformationMethod;
|
|
import android.util.Log;
|
|
import android.view.ActionMode;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.widget.TextView;
|
|
import androidx.core.text.PrecomputedTextCompat;
|
|
import androidx.core.util.Preconditions;
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/* loaded from: classes.dex */
|
|
public final class TextViewCompat {
|
|
private static Field a;
|
|
private static boolean b;
|
|
private static Field c;
|
|
private static boolean d;
|
|
|
|
private static Field a(String str) {
|
|
Field field = null;
|
|
try {
|
|
field = TextView.class.getDeclaredField(str);
|
|
field.setAccessible(true);
|
|
return field;
|
|
} catch (NoSuchFieldException unused) {
|
|
Log.e("TextViewCompat", "Could not retrieve " + str + " field.");
|
|
return field;
|
|
}
|
|
}
|
|
|
|
public static void b(TextView textView, int i) {
|
|
Preconditions.a(i);
|
|
Paint.FontMetricsInt fontMetricsInt = textView.getPaint().getFontMetricsInt();
|
|
int i2 = (Build.VERSION.SDK_INT < 16 || textView.getIncludeFontPadding()) ? fontMetricsInt.bottom : fontMetricsInt.descent;
|
|
if (i > Math.abs(i2)) {
|
|
textView.setPadding(textView.getPaddingLeft(), textView.getPaddingTop(), textView.getPaddingRight(), i - i2);
|
|
}
|
|
}
|
|
|
|
public static int c(TextView textView) {
|
|
return textView.getPaddingBottom() + textView.getPaint().getFontMetricsInt().bottom;
|
|
}
|
|
|
|
public static int d(TextView textView) {
|
|
if (Build.VERSION.SDK_INT >= 16) {
|
|
return textView.getMaxLines();
|
|
}
|
|
if (!d) {
|
|
c = a("mMaxMode");
|
|
d = true;
|
|
}
|
|
Field field = c;
|
|
if (field == null || a(field, textView) != 1) {
|
|
return -1;
|
|
}
|
|
if (!b) {
|
|
a = a("mMaximum");
|
|
b = true;
|
|
}
|
|
Field field2 = a;
|
|
if (field2 != null) {
|
|
return a(field2, textView);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
private static TextDirectionHeuristic e(TextView textView) {
|
|
if (textView.getTransformationMethod() instanceof PasswordTransformationMethod) {
|
|
return TextDirectionHeuristics.LTR;
|
|
}
|
|
if (Build.VERSION.SDK_INT >= 28 && (textView.getInputType() & 15) == 3) {
|
|
byte directionality = Character.getDirectionality(DecimalFormatSymbols.getInstance(textView.getTextLocale()).getDigitStrings()[0].codePointAt(0));
|
|
return (directionality == 1 || directionality == 2) ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR;
|
|
}
|
|
boolean z = textView.getLayoutDirection() == 1;
|
|
switch (textView.getTextDirection()) {
|
|
case 2:
|
|
break;
|
|
case 3:
|
|
break;
|
|
case 4:
|
|
break;
|
|
case 5:
|
|
break;
|
|
case 6:
|
|
break;
|
|
case 7:
|
|
break;
|
|
default:
|
|
if (!z) {
|
|
break;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return TextDirectionHeuristics.LTR;
|
|
}
|
|
|
|
public static PrecomputedTextCompat.Params f(TextView textView) {
|
|
if (Build.VERSION.SDK_INT >= 28) {
|
|
return new PrecomputedTextCompat.Params(textView.getTextMetricsParams());
|
|
}
|
|
PrecomputedTextCompat.Params.Builder builder = new PrecomputedTextCompat.Params.Builder(new TextPaint(textView.getPaint()));
|
|
if (Build.VERSION.SDK_INT >= 23) {
|
|
builder.a(textView.getBreakStrategy());
|
|
builder.b(textView.getHyphenationFrequency());
|
|
}
|
|
if (Build.VERSION.SDK_INT >= 18) {
|
|
builder.a(e(textView));
|
|
}
|
|
return builder.a();
|
|
}
|
|
|
|
public static void c(TextView textView, int i) {
|
|
Preconditions.a(i);
|
|
if (i != textView.getPaint().getFontMetricsInt(null)) {
|
|
textView.setLineSpacing(i - r0, 1.0f);
|
|
}
|
|
}
|
|
|
|
private static int a(Field field, TextView textView) {
|
|
try {
|
|
return field.getInt(textView);
|
|
} catch (IllegalAccessException unused) {
|
|
Log.d("TextViewCompat", "Could not retrieve value of " + field.getName() + " field.");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public static void a(TextView textView, Drawable drawable, Drawable drawable2, Drawable drawable3, Drawable drawable4) {
|
|
int i = Build.VERSION.SDK_INT;
|
|
if (i >= 18) {
|
|
textView.setCompoundDrawablesRelative(drawable, drawable2, drawable3, drawable4);
|
|
return;
|
|
}
|
|
if (i >= 17) {
|
|
boolean z = textView.getLayoutDirection() == 1;
|
|
Drawable drawable5 = z ? drawable3 : drawable;
|
|
if (!z) {
|
|
drawable = drawable3;
|
|
}
|
|
textView.setCompoundDrawables(drawable5, drawable2, drawable, drawable4);
|
|
return;
|
|
}
|
|
textView.setCompoundDrawables(drawable, drawable2, drawable3, drawable4);
|
|
}
|
|
|
|
public static Drawable[] a(TextView textView) {
|
|
int i = Build.VERSION.SDK_INT;
|
|
if (i >= 18) {
|
|
return textView.getCompoundDrawablesRelative();
|
|
}
|
|
if (i >= 17) {
|
|
boolean z = textView.getLayoutDirection() == 1;
|
|
Drawable[] compoundDrawables = textView.getCompoundDrawables();
|
|
if (z) {
|
|
Drawable drawable = compoundDrawables[2];
|
|
Drawable drawable2 = compoundDrawables[0];
|
|
compoundDrawables[0] = drawable;
|
|
compoundDrawables[2] = drawable2;
|
|
}
|
|
return compoundDrawables;
|
|
}
|
|
return textView.getCompoundDrawables();
|
|
}
|
|
|
|
public static int b(TextView textView) {
|
|
return textView.getPaddingTop() - textView.getPaint().getFontMetricsInt().top;
|
|
}
|
|
|
|
public static void d(TextView textView, int i) {
|
|
if (Build.VERSION.SDK_INT >= 23) {
|
|
textView.setTextAppearance(i);
|
|
} else {
|
|
textView.setTextAppearance(textView.getContext(), i);
|
|
}
|
|
}
|
|
|
|
public static ActionMode.Callback a(TextView textView, ActionMode.Callback callback) {
|
|
int i = Build.VERSION.SDK_INT;
|
|
return (i < 26 || i > 27 || (callback instanceof OreoCallback)) ? callback : new OreoCallback(callback, textView);
|
|
}
|
|
|
|
public static void a(TextView textView, int i) {
|
|
int i2;
|
|
Preconditions.a(i);
|
|
if (Build.VERSION.SDK_INT >= 28) {
|
|
textView.setFirstBaselineToTopHeight(i);
|
|
return;
|
|
}
|
|
Paint.FontMetricsInt fontMetricsInt = textView.getPaint().getFontMetricsInt();
|
|
if (Build.VERSION.SDK_INT >= 16 && !textView.getIncludeFontPadding()) {
|
|
i2 = fontMetricsInt.ascent;
|
|
} else {
|
|
i2 = fontMetricsInt.top;
|
|
}
|
|
if (i > Math.abs(i2)) {
|
|
textView.setPadding(textView.getPaddingLeft(), i - (-i2), textView.getPaddingRight(), textView.getPaddingBottom());
|
|
}
|
|
}
|
|
|
|
private static class OreoCallback implements ActionMode.Callback {
|
|
private final ActionMode.Callback a;
|
|
private final TextView b;
|
|
private Class c;
|
|
private Method d;
|
|
private boolean e;
|
|
private boolean f = false;
|
|
|
|
OreoCallback(ActionMode.Callback callback, TextView textView) {
|
|
this.a = callback;
|
|
this.b = textView;
|
|
}
|
|
|
|
private void a(Menu menu) {
|
|
Context context = this.b.getContext();
|
|
PackageManager packageManager = context.getPackageManager();
|
|
if (!this.f) {
|
|
this.f = true;
|
|
try {
|
|
this.c = Class.forName("com.android.internal.view.menu.MenuBuilder");
|
|
this.d = this.c.getDeclaredMethod("removeItemAt", Integer.TYPE);
|
|
this.e = true;
|
|
} catch (ClassNotFoundException | NoSuchMethodException unused) {
|
|
this.c = null;
|
|
this.d = null;
|
|
this.e = false;
|
|
}
|
|
}
|
|
try {
|
|
Method declaredMethod = (this.e && this.c.isInstance(menu)) ? this.d : menu.getClass().getDeclaredMethod("removeItemAt", Integer.TYPE);
|
|
for (int size = menu.size() - 1; size >= 0; size--) {
|
|
MenuItem item = menu.getItem(size);
|
|
if (item.getIntent() != null && "android.intent.action.PROCESS_TEXT".equals(item.getIntent().getAction())) {
|
|
declaredMethod.invoke(menu, Integer.valueOf(size));
|
|
}
|
|
}
|
|
List<ResolveInfo> a = a(context, packageManager);
|
|
for (int i = 0; i < a.size(); i++) {
|
|
ResolveInfo resolveInfo = a.get(i);
|
|
menu.add(0, 0, i + 100, resolveInfo.loadLabel(packageManager)).setIntent(a(resolveInfo, this.b)).setShowAsAction(1);
|
|
}
|
|
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException unused2) {
|
|
}
|
|
}
|
|
|
|
@Override // android.view.ActionMode.Callback
|
|
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
|
|
return this.a.onActionItemClicked(actionMode, menuItem);
|
|
}
|
|
|
|
@Override // android.view.ActionMode.Callback
|
|
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
|
|
return this.a.onCreateActionMode(actionMode, menu);
|
|
}
|
|
|
|
@Override // android.view.ActionMode.Callback
|
|
public void onDestroyActionMode(ActionMode actionMode) {
|
|
this.a.onDestroyActionMode(actionMode);
|
|
}
|
|
|
|
@Override // android.view.ActionMode.Callback
|
|
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
|
|
a(menu);
|
|
return this.a.onPrepareActionMode(actionMode, menu);
|
|
}
|
|
|
|
private List<ResolveInfo> a(Context context, PackageManager packageManager) {
|
|
ArrayList arrayList = new ArrayList();
|
|
if (!(context instanceof Activity)) {
|
|
return arrayList;
|
|
}
|
|
for (ResolveInfo resolveInfo : packageManager.queryIntentActivities(a(), 0)) {
|
|
if (a(resolveInfo, context)) {
|
|
arrayList.add(resolveInfo);
|
|
}
|
|
}
|
|
return arrayList;
|
|
}
|
|
|
|
private boolean a(ResolveInfo resolveInfo, Context context) {
|
|
if (context.getPackageName().equals(resolveInfo.activityInfo.packageName)) {
|
|
return true;
|
|
}
|
|
if (!resolveInfo.activityInfo.exported) {
|
|
return false;
|
|
}
|
|
String str = resolveInfo.activityInfo.permission;
|
|
return str == null || context.checkSelfPermission(str) == 0;
|
|
}
|
|
|
|
private Intent a(ResolveInfo resolveInfo, TextView textView) {
|
|
return a().putExtra("android.intent.extra.PROCESS_TEXT_READONLY", !a(textView)).setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
|
|
}
|
|
|
|
private boolean a(TextView textView) {
|
|
return (textView instanceof Editable) && textView.onCheckIsTextEditor() && textView.isEnabled();
|
|
}
|
|
|
|
private Intent a() {
|
|
return new Intent().setAction("android.intent.action.PROCESS_TEXT").setType("text/plain");
|
|
}
|
|
}
|
|
|
|
public static void a(TextView textView, PrecomputedTextCompat.Params params) {
|
|
if (Build.VERSION.SDK_INT >= 18) {
|
|
textView.setTextDirection(a(params.c()));
|
|
}
|
|
if (Build.VERSION.SDK_INT < 23) {
|
|
float textScaleX = params.d().getTextScaleX();
|
|
textView.getPaint().set(params.d());
|
|
if (textScaleX == textView.getTextScaleX()) {
|
|
textView.setTextScaleX((textScaleX / 2.0f) + 1.0f);
|
|
}
|
|
textView.setTextScaleX(textScaleX);
|
|
return;
|
|
}
|
|
textView.getPaint().set(params.d());
|
|
textView.setBreakStrategy(params.a());
|
|
textView.setHyphenationFrequency(params.b());
|
|
}
|
|
|
|
public static void a(TextView textView, PrecomputedTextCompat precomputedTextCompat) {
|
|
if (Build.VERSION.SDK_INT >= 28) {
|
|
textView.setText(precomputedTextCompat.b());
|
|
} else {
|
|
if (f(textView).equals(precomputedTextCompat.a())) {
|
|
textView.setText(precomputedTextCompat);
|
|
return;
|
|
}
|
|
throw new IllegalArgumentException("Given text can not be applied to TextView.");
|
|
}
|
|
}
|
|
|
|
private static int a(TextDirectionHeuristic textDirectionHeuristic) {
|
|
if (textDirectionHeuristic == TextDirectionHeuristics.FIRSTSTRONG_RTL || textDirectionHeuristic == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
|
|
return 1;
|
|
}
|
|
if (textDirectionHeuristic == TextDirectionHeuristics.ANYRTL_LTR) {
|
|
return 2;
|
|
}
|
|
if (textDirectionHeuristic == TextDirectionHeuristics.LTR) {
|
|
return 3;
|
|
}
|
|
if (textDirectionHeuristic == TextDirectionHeuristics.RTL) {
|
|
return 4;
|
|
}
|
|
if (textDirectionHeuristic == TextDirectionHeuristics.LOCALE) {
|
|
return 5;
|
|
}
|
|
if (textDirectionHeuristic == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
|
|
return 6;
|
|
}
|
|
return textDirectionHeuristic == TextDirectionHeuristics.FIRSTSTRONG_RTL ? 7 : 1;
|
|
}
|
|
}
|