Updated AndroidX

master
M66B 2 months ago
parent 54b5ef8e88
commit 1b6d83dda8

@ -535,7 +535,7 @@ configurations.configureEach {
} else if (details.requested.group == "androidx.lifecycle" && } else if (details.requested.group == "androidx.lifecycle" &&
details.requested.name != "lifecycle-extensions") { details.requested.name != "lifecycle-extensions") {
//print("Pinning " + details.requested.group + ":" + details.requested.name + "\n") //print("Pinning " + details.requested.group + ":" + details.requested.name + "\n")
details.useVersion "2.8.4" details.useVersion "2.8.5"
} else if (details.requested.group == "org.apache.poi") { } else if (details.requested.group == "org.apache.poi") {
//print("Pinning " + details.requested.group + ":" + details.requested.name + "\n") //print("Pinning " + details.requested.group + ":" + details.requested.name + "\n")
details.useVersion "3.17" details.useVersion "3.17"
@ -557,12 +557,12 @@ dependencies {
def annotation_version_experimental = "1.4.1" // 1.5.0-alpha01 def annotation_version_experimental = "1.4.1" // 1.5.0-alpha01
def core_version = "1.13.1" // 1.15.0-alpha01 def core_version = "1.13.1" // 1.15.0-alpha01
def appcompat_version = "1.7.0" def appcompat_version = "1.7.0"
def emoji_version = "1.4.0" // 1.5.0-rc01 def emoji_version = "1.5.0"
def flatbuffers_version = "2.0.0" def flatbuffers_version = "2.0.0"
def activity_version = " 1.9.1" // 1.10.0-alpha01 def activity_version = " 1.9.2" // 1.10.0-alpha02
def fragment_version = "1.8.2" def fragment_version = "1.8.3"
def windows_version = "1.3.0" // 1.4.0-alpha01 def windows_version = "1.3.0" // 1.4.0-alpha02
def webkit_version = "1.10.0" // 1.11.0/1.12.0-beta01 def webkit_version = "1.10.0" // 1.11.0/1.12.0-rc01
def recyclerview_version = "1.3.2" // 1.4.0-beta01 def recyclerview_version = "1.3.2" // 1.4.0-beta01
def coordinatorlayout_version = "1.2.0" // 1.3.0-alpha02 def coordinatorlayout_version = "1.2.0" // 1.3.0-alpha02
def constraintlayout_version = "2.1.4" // 2.2.0-alpha14 def constraintlayout_version = "2.1.4" // 2.2.0-alpha14
@ -571,14 +571,14 @@ dependencies {
def lbm_version = "1.1.0" def lbm_version = "1.1.0"
def swiperefresh_version = "1.2.0-alpha01" def swiperefresh_version = "1.2.0-alpha01"
def documentfile_version = "1.1.0-alpha01" def documentfile_version = "1.1.0-alpha01"
def lifecycle_version = "2.8.4" def lifecycle_version = "2.8.5" // 2.9.0-alpha02
def lifecycle_extensions_version = "2.2.0" def lifecycle_extensions_version = "2.2.0"
def room_version = "2.4.3" // 2.5.2/2.6.1/2.7.0-alpha07 def room_version = "2.4.3" // 2.5.2/2.6.1/2.7.0-alpha07
def sqlite_version = "2.4.0" // 2.5.0-alpha07 def sqlite_version = "2.4.0" // 2.5.0-alpha07
def requery_version = "3.39.2" def requery_version = "3.39.2"
def paging_version = "2.1.2" // 3.3.0-rc01 def paging_version = "2.1.2" // 3.3.0-rc01
def preference_version = "1.2.1" def preference_version = "1.2.1"
def work_version = "2.9.1" // 2.10.0-alpha02 def work_version = "2.9.1" // 2.10.0-alpha03
def exif_version = "1.3.7" def exif_version = "1.3.7"
def biometric_version = "1.2.0-alpha05" // 1.4.0-alpha02 def biometric_version = "1.2.0-alpha05" // 1.4.0-alpha02
def billingclient_version = "6.0.1" // 6.2.0 def billingclient_version = "6.0.1" // 6.2.0
@ -632,17 +632,18 @@ dependencies {
implementation "androidx.core:core:$core_version" implementation "androidx.core:core:$core_version"
// https://mvnrepository.com/artifact/androidx.appcompat/appcompat // https://mvnrepository.com/artifact/androidx.appcompat/appcompat
// https://mvnrepository.com/artifact/androidx.emoji2/emoji2
// https://mvnrepository.com/artifact/androidx.activity/activity // https://mvnrepository.com/artifact/androidx.activity/activity
// https://mvnrepository.com/artifact/androidx.fragment/fragment // https://mvnrepository.com/artifact/androidx.fragment/fragment
// https://mvnrepository.com/artifact/androidx.window/window-java // https://mvnrepository.com/artifact/androidx.window/window-java
implementation "androidx.appcompat:appcompat:$appcompat_version" implementation "androidx.appcompat:appcompat:$appcompat_version"
//implementation "androidx.emoji2:emoji2:$emoji_version"
implementation "com.google.flatbuffers:flatbuffers-java:$flatbuffers_version"
implementation "androidx.activity:activity:$activity_version" implementation "androidx.activity:activity:$activity_version"
implementation "androidx.fragment:fragment:$fragment_version" implementation "androidx.fragment:fragment:$fragment_version"
implementation "androidx.window:window-java:$windows_version" implementation "androidx.window:window-java:$windows_version"
// https://mvnrepository.com/artifact/androidx.emoji2/emoji2
implementation "androidx.emoji2:emoji2:$emoji_version"
implementation "com.google.flatbuffers:flatbuffers-java:$flatbuffers_version"
// https://developer.android.com/jetpack/androidx/releases/webkit // https://developer.android.com/jetpack/androidx/releases/webkit
// https://mvnrepository.com/artifact/androidx.webkit/webkit // https://mvnrepository.com/artifact/androidx.webkit/webkit
implementation "androidx.webkit:webkit:$webkit_version" implementation "androidx.webkit:webkit:$webkit_version"

@ -21,7 +21,6 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Process; import android.os.Process;
import androidx.annotation.DoNotInline;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
@ -81,15 +80,19 @@ class ConcurrencyHelpers {
} }
} }
static Executor mainThreadExecutor() {
return convertHandlerToExecutor(mainHandlerAsync());
}
/** /**
* @deprecated Exists only for upgrade path, remove with * Convert a handler to an executor.
* {@link FontRequestEmojiCompatConfig#setHandler(Handler)} *
* We need to do this in places where Context is not available, and cannot use ContextCompat.
* *
* @param handler a background thread handler * @param handler a background thread handler
* @return an executor that posts all work to that handler * @return an executor that posts all work to that handler
*/ */
@NonNull @NonNull
@Deprecated
static Executor convertHandlerToExecutor(@NonNull Handler handler) { static Executor convertHandlerToExecutor(@NonNull Handler handler) {
return handler::post; return handler::post;
} }
@ -100,7 +103,6 @@ class ConcurrencyHelpers {
// Non-instantiable. // Non-instantiable.
} }
@DoNotInline
public static Handler createAsync(Looper looper) { public static Handler createAsync(Looper looper) {
return Handler.createAsync(looper); return Handler.createAsync(looper);
} }

@ -241,8 +241,6 @@ public final class DefaultEmojiCompatConfig {
private static DefaultEmojiCompatConfigHelper getHelperForApi() { private static DefaultEmojiCompatConfigHelper getHelperForApi() {
if (Build.VERSION.SDK_INT >= 28) { if (Build.VERSION.SDK_INT >= 28) {
return new DefaultEmojiCompatConfigHelper_API28(); return new DefaultEmojiCompatConfigHelper_API28();
} else if (Build.VERSION.SDK_INT >= 19) {
return new DefaultEmojiCompatConfigHelper_API19();
} else { } else {
return new DefaultEmojiCompatConfigHelper(); return new DefaultEmojiCompatConfigHelper();
} }
@ -250,30 +248,17 @@ public final class DefaultEmojiCompatConfig {
} }
/** /**
* Helper to lookup signatures in package manager.
*
*/ */
@RestrictTo(RestrictTo.Scope.LIBRARY) @RestrictTo(RestrictTo.Scope.LIBRARY)
public static class DefaultEmojiCompatConfigHelper { public static class DefaultEmojiCompatConfigHelper {
/**
* Get the signing signatures for a package in package manager.
*/
@SuppressWarnings("deprecation") // replaced in API 28
@NonNull
public Signature[] getSigningSignatures(@NonNull PackageManager packageManager,
@NonNull String providerPackage) throws PackageManager.NameNotFoundException {
PackageInfo packageInfoForSignatures = packageManager.getPackageInfo(providerPackage,
PackageManager.GET_SIGNATURES);
return packageInfoForSignatures.signatures;
}
/** /**
* Get the content provider by intent. * Get the content provider by intent.
*/ */
@NonNull @NonNull
@SuppressWarnings("deprecation")
public List<ResolveInfo> queryIntentContentProviders(@NonNull PackageManager packageManager, public List<ResolveInfo> queryIntentContentProviders(@NonNull PackageManager packageManager,
@NonNull Intent intent, int flags) { @NonNull Intent intent, int flags) {
return Collections.emptyList(); return packageManager.queryIntentContentProviders(intent, flags);
} }
/** /**
@ -283,30 +268,19 @@ public final class DefaultEmojiCompatConfig {
*/ */
@Nullable @Nullable
public ProviderInfo getProviderInfo(@NonNull ResolveInfo resolveInfo) { public ProviderInfo getProviderInfo(@NonNull ResolveInfo resolveInfo) {
throw new IllegalStateException("Unable to get provider info prior to API 19"); return resolveInfo.providerInfo;
}
} }
/** /**
* Actually do lookups > API 19 * Get the signing signatures for a package in package manager.
*
*/ */
@RestrictTo(RestrictTo.Scope.LIBRARY) @SuppressWarnings("deprecation") // using deprecated API to match exact behavior in core
@RequiresApi(19)
public static class DefaultEmojiCompatConfigHelper_API19
extends DefaultEmojiCompatConfigHelper {
@NonNull @NonNull
@Override public Signature[] getSigningSignatures(@NonNull PackageManager packageManager,
@SuppressWarnings("deprecation") @NonNull String providerPackage) throws PackageManager.NameNotFoundException {
public List<ResolveInfo> queryIntentContentProviders(@NonNull PackageManager packageManager, PackageInfo packageInfoForSignatures = packageManager.getPackageInfo(providerPackage,
@NonNull Intent intent, int flags) { PackageManager.GET_SIGNATURES);
return packageManager.queryIntentContentProviders(intent, flags); return packageInfoForSignatures.signatures;
}
@Nullable
@Override
public ProviderInfo getProviderInfo(@NonNull ResolveInfo resolveInfo) {
return resolveInfo.providerInfo;
} }
} }
@ -316,7 +290,7 @@ public final class DefaultEmojiCompatConfig {
@RestrictTo(RestrictTo.Scope.LIBRARY) @RestrictTo(RestrictTo.Scope.LIBRARY)
@RequiresApi(28) @RequiresApi(28)
public static class DefaultEmojiCompatConfigHelper_API28 public static class DefaultEmojiCompatConfigHelper_API28
extends DefaultEmojiCompatConfigHelper_API19 { extends DefaultEmojiCompatConfigHelper {
@SuppressWarnings("deprecation") // using deprecated API to match exact behavior in core @SuppressWarnings("deprecation") // using deprecated API to match exact behavior in core
@Override @Override
@NonNull @NonNull

@ -22,10 +22,7 @@ import android.app.Application;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable; import android.text.Editable;
import android.text.method.KeyListener; import android.text.method.KeyListener;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -40,7 +37,6 @@ import androidx.annotation.IntDef;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.collection.ArraySet; import androidx.collection.ArraySet;
@ -50,9 +46,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -352,17 +348,12 @@ public class EmojiCompat {
private final @NonNull ReadWriteLock mInitLock; private final @NonNull ReadWriteLock mInitLock;
@GuardedBy("mInitLock") @GuardedBy("mInitLock")
private final @NonNull Set<InitCallback> mInitCallbacks; private final @NonNull Set<InitWithExecutor> mInitCallbacks;
@GuardedBy("mInitLock") @GuardedBy("mInitLock")
@LoadState @LoadState
private volatile int mLoadState; private volatile int mLoadState;
/**
* Handler with main looper to run the callbacks on.
*/
private final @NonNull Handler mMainHandler;
/** /**
* Helper class for pre 19 compatibility. * Helper class for pre 19 compatibility.
*/ */
@ -464,15 +455,13 @@ public class EmojiCompat {
mMetadataLoader = config.mMetadataLoader; mMetadataLoader = config.mMetadataLoader;
mMetadataLoadStrategy = config.mMetadataLoadStrategy; mMetadataLoadStrategy = config.mMetadataLoadStrategy;
mGlyphChecker = config.mGlyphChecker; mGlyphChecker = config.mGlyphChecker;
mMainHandler = new Handler(Looper.getMainLooper());
mInitCallbacks = new ArraySet<>(); mInitCallbacks = new ArraySet<>();
SpanFactory localSpanFactory = config.mSpanFactory; SpanFactory localSpanFactory = config.mSpanFactory;
mSpanFactory = localSpanFactory != null ? localSpanFactory : new DefaultSpanFactory(); mSpanFactory = localSpanFactory != null ? localSpanFactory : new DefaultSpanFactory();
if (config.mInitCallbacks != null && !config.mInitCallbacks.isEmpty()) { if (config.mInitCallbacks != null && !config.mInitCallbacks.isEmpty()) {
mInitCallbacks.addAll(config.mInitCallbacks); mInitCallbacks.addAll(config.mInitCallbacks);
} }
mHelper = Build.VERSION.SDK_INT < 19 ? new CompatInternal(this) : new CompatInternal19( mHelper = new CompatInternal(this);
this);
loadMetadata(); loadMetadata();
} }
@ -699,31 +688,37 @@ public class EmojiCompat {
@SuppressWarnings("WeakerAccess") /* synthetic access */ @SuppressWarnings("WeakerAccess") /* synthetic access */
void onMetadataLoadSuccess() { void onMetadataLoadSuccess() {
final Collection<InitCallback> initCallbacks = new ArrayList<>(); Set<InitWithExecutor> localRefCbs = mInitCallbacks;
final ArrayList<InitWithExecutor> initCallbacks = new ArrayList<>(localRefCbs.size());
mInitLock.writeLock().lock(); mInitLock.writeLock().lock();
try { try {
mLoadState = LOAD_STATE_SUCCEEDED; mLoadState = LOAD_STATE_SUCCEEDED;
initCallbacks.addAll(mInitCallbacks); initCallbacks.addAll(localRefCbs);
mInitCallbacks.clear(); localRefCbs.clear();
} finally { } finally {
mInitLock.writeLock().unlock(); mInitLock.writeLock().unlock();
} }
mMainHandler.post(new ListenerDispatcher(initCallbacks, mLoadState)); for (int i = 0; i < initCallbacks.size(); i++) {
initCallbacks.get(i).dispatchInitialized();
}
} }
@SuppressWarnings("WeakerAccess") /* synthetic access */ @SuppressWarnings("WeakerAccess") /* synthetic access */
void onMetadataLoadFailed(@Nullable final Throwable throwable) { void onMetadataLoadFailed(@NonNull final Throwable throwable) {
final Collection<InitCallback> initCallbacks = new ArrayList<>(); Set<InitWithExecutor> localRefCbs = mInitCallbacks;
final ArrayList<InitWithExecutor> initCallbacks = new ArrayList<>(localRefCbs.size());
mInitLock.writeLock().lock(); mInitLock.writeLock().lock();
try { try {
mLoadState = LOAD_STATE_FAILED; mLoadState = LOAD_STATE_FAILED;
initCallbacks.addAll(mInitCallbacks); initCallbacks.addAll(localRefCbs);
mInitCallbacks.clear(); localRefCbs.clear();
} finally { } finally {
mInitLock.writeLock().unlock(); mInitLock.writeLock().unlock();
} }
mMainHandler.post(new ListenerDispatcher(initCallbacks, mLoadState, throwable)); for (int i = 0; i < initCallbacks.size(); i++) {
initCallbacks.get(i).dispatchFailed(throwable);
}
} }
/** /**
@ -741,14 +736,38 @@ public class EmojiCompat {
*/ */
@SuppressWarnings("ExecutorRegistration") @SuppressWarnings("ExecutorRegistration")
public void registerInitCallback(@NonNull InitCallback initCallback) { public void registerInitCallback(@NonNull InitCallback initCallback) {
registerInitCallback(ConcurrencyHelpers.mainThreadExecutor(), initCallback);
}
/**
* Registers an initialization callback. If the initialization is already completed by the time
* the listener is added, the callback functions are called immediately.
* <p/>
* When used on devices running API 18 or below, {@link InitCallback#onInitialized()} is called
* without loading any metadata. In such cases {@link InitCallback#onFailed(Throwable)} is never
* called.
*
* @param executor executor to dispatch callback on
* @param initCallback the initialization callback to register, cannot be {@code null}
*
* @see #unregisterInitCallback(InitCallback)
*/
public void registerInitCallback(@NonNull Executor executor,
@NonNull InitCallback initCallback) {
Preconditions.checkNotNull(initCallback, "initCallback cannot be null"); Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
InitWithExecutor newCb = new InitWithExecutor(executor, initCallback);
mInitLock.writeLock().lock(); mInitLock.writeLock().lock();
try { try {
if (mLoadState == LOAD_STATE_SUCCEEDED || mLoadState == LOAD_STATE_FAILED) { if (mLoadState == LOAD_STATE_SUCCEEDED) {
mMainHandler.post(new ListenerDispatcher(initCallback, mLoadState)); newCb.dispatchInitialized();
} else if (mLoadState == LOAD_STATE_FAILED) {
newCb.dispatchFailed(new IllegalStateException("Initialization failed prior to "
+ "registering this callback, please add an initialization callback to "
+ "the EmojiCompat.Config instead to see the cause."));
} else { } else {
mInitCallbacks.add(initCallback); mInitCallbacks.add(newCb);
} }
} finally { } finally {
mInitLock.writeLock().unlock(); mInitLock.writeLock().unlock();
@ -764,7 +783,15 @@ public class EmojiCompat {
Preconditions.checkNotNull(initCallback, "initCallback cannot be null"); Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
mInitLock.writeLock().lock(); mInitLock.writeLock().lock();
try { try {
mInitCallbacks.remove(initCallback); ArrayList<InitWithExecutor> toRemove = new ArrayList<>();
for (InitWithExecutor item : mInitCallbacks) {
if (item.mInitCallback == initCallback) {
toRemove.add(item);
}
}
for (InitWithExecutor item : toRemove) {
mInitCallbacks.remove(item);
}
} finally { } finally {
mInitLock.writeLock().unlock(); mInitLock.writeLock().unlock();
} }
@ -859,11 +886,7 @@ public class EmojiCompat {
*/ */
public static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode, public static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode,
@NonNull final KeyEvent event) { @NonNull final KeyEvent event) {
if (Build.VERSION.SDK_INT >= 19) {
return EmojiProcessor.handleOnKeyDown(editable, keyCode, event); return EmojiProcessor.handleOnKeyDown(editable, keyCode, event);
} else {
return false;
}
} }
/** /**
@ -888,12 +911,8 @@ public class EmojiCompat {
@NonNull final InputConnection inputConnection, @NonNull final Editable editable, @NonNull final InputConnection inputConnection, @NonNull final Editable editable,
@IntRange(from = 0) final int beforeLength, @IntRange(from = 0) final int afterLength, @IntRange(from = 0) final int beforeLength, @IntRange(from = 0) final int afterLength,
final boolean inCodePoints) { final boolean inCodePoints) {
if (Build.VERSION.SDK_INT >= 19) {
return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable, return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable,
beforeLength, afterLength, inCodePoints); beforeLength, afterLength, inCodePoints);
} else {
return false;
}
} }
/** /**
@ -1190,7 +1209,6 @@ public class EmojiCompat {
* *
* @return EmojiSpan instance that can use TypefaceEmojiRasterizer to draw emoji. * @return EmojiSpan instance that can use TypefaceEmojiRasterizer to draw emoji.
*/ */
@RequiresApi(19)
@NonNull @NonNull
EmojiSpan createSpan(@NonNull TypefaceEmojiRasterizer rasterizer); EmojiSpan createSpan(@NonNull TypefaceEmojiRasterizer rasterizer);
} }
@ -1209,7 +1227,6 @@ public class EmojiCompat {
* *
* @return {@link TypefaceEmojiSpan} * @return {@link TypefaceEmojiSpan}
*/ */
@RequiresApi(19)
@NonNull @NonNull
@Override @Override
public EmojiSpan createSpan(@NonNull TypefaceEmojiRasterizer rasterizer) { public EmojiSpan createSpan(@NonNull TypefaceEmojiRasterizer rasterizer) {
@ -1252,6 +1269,24 @@ public class EmojiCompat {
void load(@NonNull MetadataRepoLoaderCallback loaderCallback); void load(@NonNull MetadataRepoLoaderCallback loaderCallback);
} }
private static final class InitWithExecutor {
InitCallback mInitCallback;
Executor mExecutor;
InitWithExecutor(@NonNull Executor executor, @NonNull InitCallback initCallback) {
mInitCallback = initCallback;
mExecutor = executor;
}
void dispatchInitialized() {
mExecutor.execute(() -> mInitCallback.onInitialized());
}
void dispatchFailed(Throwable throwable) {
mExecutor.execute(() -> mInitCallback.onFailed(throwable));
}
}
/** /**
* Interface to check if a given emoji exists on the system. * Interface to check if a given emoji exists on the system.
*/ */
@ -1286,7 +1321,7 @@ public class EmojiCompat {
* information, and some predefined OEMs, it is possible to write the following code * information, and some predefined OEMs, it is possible to write the following code
* snippet. * snippet.
* *
* {@sample frameworks/support/samples/SupportEmojiDemos/src/main/java/com/example/android/support/text/emoji/sample/GlyphCheckerSample.java glyphchecker} * {@sample samples/SupportEmojiDemos/src/main/java/com/example/android/support/text/emoji/sample/GlyphCheckerSample.java glyphchecker}
* *
* @param charSequence the CharSequence that is being processed * @param charSequence the CharSequence that is being processed
* @param start the inclusive starting offset for the emoji in the {@code charSequence} * @param start the inclusive starting offset for the emoji in the {@code charSequence}
@ -1349,7 +1384,7 @@ public class EmojiCompat {
int[] mEmojiAsDefaultStyleExceptions; int[] mEmojiAsDefaultStyleExceptions;
@SuppressWarnings("WeakerAccess") /* synthetic access */ @SuppressWarnings("WeakerAccess") /* synthetic access */
@Nullable @Nullable
Set<InitCallback> mInitCallbacks; Set<InitWithExecutor> mInitCallbacks;
@SuppressWarnings("WeakerAccess") /* synthetic access */ @SuppressWarnings("WeakerAccess") /* synthetic access */
boolean mEmojiSpanIndicatorEnabled; boolean mEmojiSpanIndicatorEnabled;
@SuppressWarnings("WeakerAccess") /* synthetic access */ @SuppressWarnings("WeakerAccess") /* synthetic access */
@ -1380,13 +1415,27 @@ public class EmojiCompat {
@SuppressWarnings("ExecutorRegistration") @SuppressWarnings("ExecutorRegistration")
@NonNull @NonNull
public Config registerInitCallback(@NonNull InitCallback initCallback) { public Config registerInitCallback(@NonNull InitCallback initCallback) {
registerInitCallback(ConcurrencyHelpers.mainThreadExecutor(), initCallback);
return this;
}
/**
* Registers an initialization callback.
*
* @param executor executor to dispatch callback on
* @param initCallback the initialization callback to register, cannot be {@code null}
*
* @return EmojiCompat.Config instance
*/
@NonNull
public Config registerInitCallback(@NonNull Executor executor,
@NonNull InitCallback initCallback) {
Preconditions.checkNotNull(initCallback, "initCallback cannot be null"); Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
if (mInitCallbacks == null) { if (mInitCallbacks == null) {
mInitCallbacks = new ArraySet<>(); mInitCallbacks = new ArraySet<>();
} }
mInitCallbacks.add(new InitWithExecutor(executor, initCallback));
mInitCallbacks.add(initCallback);
return this; return this;
} }
@ -1401,7 +1450,15 @@ public class EmojiCompat {
public Config unregisterInitCallback(@NonNull InitCallback initCallback) { public Config unregisterInitCallback(@NonNull InitCallback initCallback) {
Preconditions.checkNotNull(initCallback, "initCallback cannot be null"); Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
if (mInitCallbacks != null) { if (mInitCallbacks != null) {
mInitCallbacks.remove(initCallback); ArrayList<InitWithExecutor> toRemove = new ArrayList<>();
for (InitWithExecutor item : mInitCallbacks) {
if (item.mInitCallback == initCallback) {
toRemove.add(item);
}
}
for (InitWithExecutor item : toRemove) {
mInitCallbacks.remove(item);
}
} }
return this; return this;
} }
@ -1576,112 +1633,7 @@ public class EmojiCompat {
} }
} }
/** private static final class CompatInternal {
* Runnable to call success/failure case for the listeners.
*/
private static class ListenerDispatcher implements Runnable {
private final List<InitCallback> mInitCallbacks;
private final Throwable mThrowable;
private final int mLoadState;
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
ListenerDispatcher(@NonNull final InitCallback initCallback,
@LoadState final int loadState) {
this(Arrays.asList(Preconditions.checkNotNull(initCallback,
"initCallback cannot be null")), loadState, null);
}
ListenerDispatcher(@NonNull final Collection<InitCallback> initCallbacks,
@LoadState final int loadState) {
this(initCallbacks, loadState, null);
}
ListenerDispatcher(@NonNull final Collection<InitCallback> initCallbacks,
@LoadState final int loadState,
@Nullable final Throwable throwable) {
Preconditions.checkNotNull(initCallbacks, "initCallbacks cannot be null");
mInitCallbacks = new ArrayList<>(initCallbacks);
mLoadState = loadState;
mThrowable = throwable;
}
@Override
public void run() {
final int size = mInitCallbacks.size();
switch (mLoadState) {
case LOAD_STATE_SUCCEEDED:
for (int i = 0; i < size; i++) {
mInitCallbacks.get(i).onInitialized();
}
break;
case LOAD_STATE_FAILED:
default:
for (int i = 0; i < size; i++) {
mInitCallbacks.get(i).onFailed(mThrowable);
}
break;
}
}
}
/**
* Internal helper class to behave no-op for certain functions.
*/
private static class CompatInternal {
final EmojiCompat mEmojiCompat;
CompatInternal(EmojiCompat emojiCompat) {
mEmojiCompat = emojiCompat;
}
void loadMetadata() {
// Moves into LOAD_STATE_SUCCESS state immediately.
mEmojiCompat.onMetadataLoadSuccess();
}
boolean hasEmojiGlyph(@NonNull final CharSequence sequence) {
// Since no metadata is loaded, EmojiCompat cannot detect or render any emojis.
return false;
}
boolean hasEmojiGlyph(@NonNull final CharSequence sequence, final int metadataVersion) {
// Since no metadata is loaded, EmojiCompat cannot detect or render any emojis.
return false;
}
int getEmojiStart(@NonNull final CharSequence cs, @IntRange(from = 0) final int offset) {
// Since no metadata is loaded, EmojiCompat cannot detect any emojis.
return -1;
}
int getEmojiEnd(@NonNull final CharSequence cs, @IntRange(from = 0) final int offset) {
// Since no metadata is loaded, EmojiCompat cannot detect any emojis.
return -1;
}
CharSequence process(@NonNull final CharSequence charSequence,
@IntRange(from = 0) final int start, @IntRange(from = 0) final int end,
@IntRange(from = 0) final int maxEmojiCount, boolean replaceAll) {
// Returns the given charSequence as it is.
return charSequence;
}
void updateEditorInfoAttrs(@NonNull final EditorInfo outAttrs) {
// Does not add any EditorInfo attributes.
}
String getAssetSignature() {
return "";
}
@CodepointSequenceMatchResult
public int getEmojiMatch(CharSequence sequence, int metadataVersion) {
return EMOJI_UNSUPPORTED;
}
}
@RequiresApi(19)
private static final class CompatInternal19 extends CompatInternal {
/** /**
* Responsible to process a CharSequence and add the spans. @{code Null} until the time the * Responsible to process a CharSequence and add the spans. @{code Null} until the time the
* metadata is loaded. * metadata is loaded.
@ -1692,13 +1644,12 @@ public class EmojiCompat {
* Keeps the information about emojis. Null until the time the data is loaded. * Keeps the information about emojis. Null until the time the data is loaded.
*/ */
private volatile MetadataRepo mMetadataRepo; private volatile MetadataRepo mMetadataRepo;
private final EmojiCompat mEmojiCompat;
CompatInternal(EmojiCompat emojiCompat) {
CompatInternal19(EmojiCompat emojiCompat) { mEmojiCompat = emojiCompat;
super(emojiCompat);
} }
@Override
void loadMetadata() { void loadMetadata() {
try { try {
final MetadataRepoLoaderCallback callback = new MetadataRepoLoaderCallback() { final MetadataRepoLoaderCallback callback = new MetadataRepoLoaderCallback() {
@ -1718,7 +1669,6 @@ public class EmojiCompat {
} }
} }
@SuppressWarnings("SyntheticAccessor")
void onMetadataLoadSuccess(@NonNull final MetadataRepo metadataRepo) { void onMetadataLoadSuccess(@NonNull final MetadataRepo metadataRepo) {
//noinspection ConstantConditions //noinspection ConstantConditions
if (metadataRepo == null) { if (metadataRepo == null) {
@ -1740,45 +1690,37 @@ public class EmojiCompat {
mEmojiCompat.onMetadataLoadSuccess(); mEmojiCompat.onMetadataLoadSuccess();
} }
@Override
boolean hasEmojiGlyph(@NonNull CharSequence sequence) { boolean hasEmojiGlyph(@NonNull CharSequence sequence) {
return mProcessor.getEmojiMatch(sequence) == EMOJI_SUPPORTED; return mProcessor.getEmojiMatch(sequence) == EMOJI_SUPPORTED;
} }
@Override
boolean hasEmojiGlyph(@NonNull CharSequence sequence, int metadataVersion) { boolean hasEmojiGlyph(@NonNull CharSequence sequence, int metadataVersion) {
int emojiMatch = mProcessor.getEmojiMatch(sequence, metadataVersion); int emojiMatch = mProcessor.getEmojiMatch(sequence, metadataVersion);
return emojiMatch == EMOJI_SUPPORTED; return emojiMatch == EMOJI_SUPPORTED;
} }
@Override
public int getEmojiMatch(CharSequence sequence, int metadataVersion) { public int getEmojiMatch(CharSequence sequence, int metadataVersion) {
return mProcessor.getEmojiMatch(sequence, metadataVersion); return mProcessor.getEmojiMatch(sequence, metadataVersion);
} }
@Override
int getEmojiStart(@NonNull final CharSequence sequence, final int offset) { int getEmojiStart(@NonNull final CharSequence sequence, final int offset) {
return mProcessor.getEmojiStart(sequence, offset); return mProcessor.getEmojiStart(sequence, offset);
} }
@Override
int getEmojiEnd(@NonNull final CharSequence sequence, final int offset) { int getEmojiEnd(@NonNull final CharSequence sequence, final int offset) {
return mProcessor.getEmojiEnd(sequence, offset); return mProcessor.getEmojiEnd(sequence, offset);
} }
@Override
CharSequence process(@NonNull CharSequence charSequence, int start, int end, CharSequence process(@NonNull CharSequence charSequence, int start, int end,
int maxEmojiCount, boolean replaceAll) { int maxEmojiCount, boolean replaceAll) {
return mProcessor.process(charSequence, start, end, maxEmojiCount, replaceAll); return mProcessor.process(charSequence, start, end, maxEmojiCount, replaceAll);
} }
@Override
void updateEditorInfoAttrs(@NonNull EditorInfo outAttrs) { void updateEditorInfoAttrs(@NonNull EditorInfo outAttrs) {
outAttrs.extras.putInt(EDITOR_INFO_METAVERSION_KEY, mMetadataRepo.getMetadataVersion()); outAttrs.extras.putInt(EDITOR_INFO_METAVERSION_KEY, mMetadataRepo.getMetadataVersion());
outAttrs.extras.putBoolean(EDITOR_INFO_REPLACE_ALL_KEY, mEmojiCompat.mReplaceAll); outAttrs.extras.putBoolean(EDITOR_INFO_REPLACE_ALL_KEY, mEmojiCompat.mReplaceAll);
} }
@Override
String getAssetSignature() { String getAssetSignature() {
final String sha = mMetadataRepo.getMetadataList().sourceSha(); final String sha = mMetadataRepo.getMetadataList().sourceSha();
return sha == null ? "" : sha; return sha == null ? "" : sha;

@ -17,12 +17,10 @@
package androidx.emoji2.text; package androidx.emoji2.text;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.WorkerThread; import androidx.annotation.WorkerThread;
import androidx.core.os.TraceCompat; import androidx.core.os.TraceCompat;
import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.DefaultLifecycleObserver;
@ -84,20 +82,16 @@ public class EmojiCompatInitializer implements Initializer<Boolean> {
@NonNull @NonNull
@Override @Override
public Boolean create(@NonNull Context context) { public Boolean create(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 19) {
EmojiCompat.init(new BackgroundDefaultConfig(context)); EmojiCompat.init(new BackgroundDefaultConfig(context));
delayUntilFirstResume(context); delayUntilFirstResume(context);
return true; return true;
} }
return false;
}
/** /**
* Wait until the first frame of the application to do anything. * Wait until the first frame of the application to do anything.
* *
* This allows startup code to run before the delay is scheduled. * This allows startup code to run before the delay is scheduled.
*/ */
@RequiresApi(19)
void delayUntilFirstResume(@NonNull Context context) { void delayUntilFirstResume(@NonNull Context context) {
// schedule delay after first Activity resumes // schedule delay after first Activity resumes
AppInitializer appInitializer = AppInitializer.getInstance(context); AppInitializer appInitializer = AppInitializer.getInstance(context);
@ -113,7 +107,6 @@ public class EmojiCompatInitializer implements Initializer<Boolean> {
}); });
} }
@RequiresApi(19)
void loadEmojiCompatAfterDelay() { void loadEmojiCompatAfterDelay() {
final Handler mainHandler = ConcurrencyHelpers.mainHandlerAsync(); final Handler mainHandler = ConcurrencyHelpers.mainHandlerAsync();
mainHandler.postDelayed(new LoadEmojiCompatRunnable(), STARTUP_THREAD_CREATION_DELAY_MS); mainHandler.postDelayed(new LoadEmojiCompatRunnable(), STARTUP_THREAD_CREATION_DELAY_MS);
@ -144,7 +137,6 @@ public class EmojiCompatInitializer implements Initializer<Boolean> {
} }
} }
@RequiresApi(19)
static class BackgroundDefaultConfig extends EmojiCompat.Config { static class BackgroundDefaultConfig extends EmojiCompat.Config {
protected BackgroundDefaultConfig(Context context) { protected BackgroundDefaultConfig(Context context) {
super(new BackgroundDefaultLoader(context)); super(new BackgroundDefaultLoader(context));
@ -152,7 +144,6 @@ public class EmojiCompatInitializer implements Initializer<Boolean> {
} }
} }
@RequiresApi(19)
static class BackgroundDefaultLoader implements EmojiCompat.MetadataRepoLoader { static class BackgroundDefaultLoader implements EmojiCompat.MetadataRepoLoader {
private final Context mContext; private final Context mContext;

@ -19,7 +19,6 @@ package androidx.emoji2.text;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.os.Build; import android.os.Build;
import androidx.annotation.DoNotInline;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
@ -44,7 +43,6 @@ class EmojiExclusions {
private EmojiExclusions_Api34() { /* cannot instantiate */ } private EmojiExclusions_Api34() { /* cannot instantiate */ }
@NonNull @NonNull
@DoNotInline
static Set<int[]> getExclusions() { static Set<int[]> getExclusions() {
// TODO: Call directly when API34 is published // TODO: Call directly when API34 is published
return EmojiExclusions_Reflections.getExclusions(); return EmojiExclusions_Reflections.getExclusions();

@ -33,7 +33,6 @@ import androidx.annotation.IntDef;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -48,7 +47,6 @@ import java.util.Set;
*/ */
@AnyThread @AnyThread
@RestrictTo(LIBRARY) @RestrictTo(LIBRARY)
@RequiresApi(19)
final class EmojiProcessor { final class EmojiProcessor {
/** /**
@ -781,7 +779,6 @@ final class EmojiProcessor {
/** /**
* Copy of BaseInputConnection findIndexBackward and findIndexForward functions. * Copy of BaseInputConnection findIndexBackward and findIndexForward functions.
*/ */
@RequiresApi(19)
private static final class CodepointIndexFinder { private static final class CodepointIndexFinder {
private static final int INVALID_INDEX = -1; private static final int INVALID_INDEX = -1;

@ -23,7 +23,6 @@ import android.text.style.ReplacementSpan;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.util.Preconditions; import androidx.core.util.Preconditions;
@ -32,7 +31,6 @@ import androidx.core.util.Preconditions;
* Base span class for the emoji replacement. When an emoji is found and needs to be replaced in a * Base span class for the emoji replacement. When an emoji is found and needs to be replaced in a
* CharSequence, an instance of this class is added to the CharSequence. * CharSequence, an instance of this class is added to the CharSequence.
*/ */
@RequiresApi(19)
public abstract class EmojiSpan extends ReplacementSpan { public abstract class EmojiSpan extends ReplacementSpan {
/** /**

@ -27,7 +27,6 @@ import android.os.SystemClock;
import androidx.annotation.GuardedBy; import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
import androidx.annotation.WorkerThread; import androidx.annotation.WorkerThread;
import androidx.core.graphics.TypefaceCompatUtil; import androidx.core.graphics.TypefaceCompatUtil;
@ -252,7 +251,6 @@ public class FontRequestEmojiCompatConfig extends EmojiCompat.Config {
} }
@Override @Override
@RequiresApi(19)
public void load(@NonNull final EmojiCompat.MetadataRepoLoaderCallback loaderCallback) { public void load(@NonNull final EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
Preconditions.checkNotNull(loaderCallback, "LoaderCallback cannot be null"); Preconditions.checkNotNull(loaderCallback, "LoaderCallback cannot be null");
synchronized (mLock) { synchronized (mLock) {
@ -261,7 +259,6 @@ public class FontRequestEmojiCompatConfig extends EmojiCompat.Config {
loadInternal(); loadInternal();
} }
@RequiresApi(19)
void loadInternal() { void loadInternal() {
synchronized (mLock) { synchronized (mLock) {
if (mCallback == null) { if (mCallback == null) {
@ -295,7 +292,6 @@ public class FontRequestEmojiCompatConfig extends EmojiCompat.Config {
return fonts[0]; // Assuming the GMS Core provides only one font file. return fonts[0]; // Assuming the GMS Core provides only one font file.
} }
@RequiresApi(19)
@WorkerThread @WorkerThread
private void scheduleRetry(Uri uri, long waitMs) { private void scheduleRetry(Uri uri, long waitMs) {
synchronized (mLock) { synchronized (mLock) {
@ -342,7 +338,6 @@ public class FontRequestEmojiCompatConfig extends EmojiCompat.Config {
} }
// Must be called on the mHandler. // Must be called on the mHandler.
@RequiresApi(19)
@SuppressWarnings("WeakerAccess") /* synthetic access */ @SuppressWarnings("WeakerAccess") /* synthetic access */
@WorkerThread @WorkerThread
void createMetadata() { void createMetadata() {

@ -20,7 +20,6 @@ import android.content.res.AssetManager;
import androidx.annotation.AnyThread; import androidx.annotation.AnyThread;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
import androidx.emoji2.text.flatbuffer.MetadataList; import androidx.emoji2.text.flatbuffer.MetadataList;
@ -35,7 +34,6 @@ import java.nio.ByteOrder;
*/ */
@RestrictTo(RestrictTo.Scope.LIBRARY) @RestrictTo(RestrictTo.Scope.LIBRARY)
@AnyThread @AnyThread
@RequiresApi(19)
class MetadataListReader { class MetadataListReader {
/** /**

@ -23,7 +23,6 @@ import android.util.SparseArray;
import androidx.annotation.AnyThread; import androidx.annotation.AnyThread;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.os.TraceCompat; import androidx.core.os.TraceCompat;
@ -38,7 +37,6 @@ import java.nio.ByteBuffer;
* Class to hold the emoji metadata required to process and draw emojis. * Class to hold the emoji metadata required to process and draw emojis.
*/ */
@AnyThread @AnyThread
@RequiresApi(19)
public final class MetadataRepo { public final class MetadataRepo {
/** /**
* The default children size of the root node. * The default children size of the root node.

@ -27,7 +27,6 @@ import androidx.annotation.AnyThread;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.emoji2.text.flatbuffer.MetadataItem; import androidx.emoji2.text.flatbuffer.MetadataItem;
@ -50,7 +49,6 @@ import java.lang.annotation.RetentionPolicy;
* *
*/ */
@AnyThread @AnyThread
@RequiresApi(19)
public class TypefaceEmojiRasterizer { public class TypefaceEmojiRasterizer {
/** /**
* Defines whether the system can render the emoji. * Defines whether the system can render the emoji.

@ -26,7 +26,6 @@ import android.text.style.MetricAffectingSpan;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo; import androidx.annotation.RestrictTo;
/** /**
@ -34,7 +33,6 @@ import androidx.annotation.RestrictTo;
* *
*/ */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@RequiresApi(19)
public final class TypefaceEmojiSpan extends EmojiSpan { public final class TypefaceEmojiSpan extends EmojiSpan {
/** /**

@ -0,0 +1,13 @@
diff --git a/app/src/main/java/androidx/emoji2/text/SpannableBuilder.java b/app/src/main/java/androidx/emoji2/text/SpannableBuilder.java
index 366c7b3629..e6fef5cddb 100644
--- a/app/src/main/java/androidx/emoji2/text/SpannableBuilder.java
+++ b/app/src/main/java/androidx/emoji2/text/SpannableBuilder.java
@@ -46,7 +46,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public final class SpannableBuilder extends SpannableStringBuilder {
+public final class SpannableBuilder extends eu.faircode.email.SpannableStringBuilderEx {
/**
* DynamicLayout$ChangeWatcher class.
*/
Loading…
Cancel
Save