[go: nahoru, domu]

ListenableFuture API Overhaul

Create new LisenableFuture<> based API underlying callback loading APIs.

 - Simplifies async initialization - PagedLists with async initial
   loads no longer start empty

 - Lays groundwork for cancellation

 - Enables other async APIs in the future

 - No longer need to disable placeholders to disable
   PositionalDataSource tiling, due to late PagedList creation.

 - DataSource#getExecutor is pretty gross, but lets us build callback
   impls on top of Listenable*DataSource APIs without adding them to
   Params. Problem is you can't call ListenableFuture based load
   methods on callback when a PagedList isn't used without crashing
   (e.g. in tests).

 - Refresh in LivePagedListBuilder currently uses private APIs

 - Can't yet use 'Result' types with callbacks - needed once we add
   more functionality.

 - Tiled (non-contiguous) loading was removed, will be added back in a
   follow-up

 - RxPagedListBuilder support for new refresh system will be in a
   follow-up

Test: ./gradlew :paging:paging-common:test :paging:paging-common-ktx:test :paging:paging-runtime:cC :paging:paging-runtime-ktx:cC :paging:
paging-rxjava:test :paging:paging-rxjava-ktx:test
Fixes: 110843692

Change-Id: Ied0f1da732a1527f9fef524e37889146084acb7b
diff --git a/paging/common/api/current.txt b/paging/common/api/current.txt
index cf13c47..3c9f6d2 100644
--- a/paging/common/api/current.txt
+++ b/paging/common/api/current.txt
@@ -5,8 +5,9 @@
     method @AnyThread public void addInvalidatedCallback(androidx.paging.DataSource.InvalidatedCallback);
     method @AnyThread public void invalidate();
     method @WorkerThread public boolean isInvalid();
-    method public abstract <ToValue> androidx.paging.DataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
-    method public abstract <ToValue> androidx.paging.DataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
+    method public boolean isRetryableError(Throwable);
+    method public <ToValue> androidx.paging.DataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
+    method public <ToValue> androidx.paging.DataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
     method @AnyThread public void removeInvalidatedCallback(androidx.paging.DataSource.InvalidatedCallback);
   }
 
@@ -21,10 +22,13 @@
     method @AnyThread public void onInvalidated();
   }
 
-  public abstract class ItemKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
-    method public abstract Key getKey(Value);
+  public abstract class ItemKeyedDataSource<Key, Value> extends androidx.paging.ListenableItemKeyedDataSource<Key,Value> {
+    ctor public ItemKeyedDataSource();
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadAfter(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
     method public abstract void loadAfter(androidx.paging.ItemKeyedDataSource.LoadParams<Key>, androidx.paging.ItemKeyedDataSource.LoadCallback<Value>);
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadBefore(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
     method public abstract void loadBefore(androidx.paging.ItemKeyedDataSource.LoadParams<Key>, androidx.paging.ItemKeyedDataSource.LoadCallback<Value>);
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.InitialResult<Value>> loadInitial(androidx.paging.ListenableItemKeyedDataSource.LoadInitialParams<Key>);
     method public abstract void loadInitial(androidx.paging.ItemKeyedDataSource.LoadInitialParams<Key>, androidx.paging.ItemKeyedDataSource.LoadInitialCallback<Value>);
     method public final <ToValue> androidx.paging.ItemKeyedDataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
     method public final <ToValue> androidx.paging.ItemKeyedDataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
@@ -34,7 +38,6 @@
     ctor public ItemKeyedDataSource.LoadCallback();
     method public void onError(Throwable);
     method public abstract void onResult(java.util.List<Value>);
-    method public void onRetryableError(Throwable);
   }
 
   public abstract static class ItemKeyedDataSource.LoadInitialCallback<Value> extends androidx.paging.ItemKeyedDataSource.LoadCallback<Value> {
@@ -42,22 +45,114 @@
     method public abstract void onResult(java.util.List<Value>, int, int);
   }
 
-  public static class ItemKeyedDataSource.LoadInitialParams<Key> {
+  public static class ItemKeyedDataSource.LoadInitialParams<Key> extends androidx.paging.ListenableItemKeyedDataSource.LoadInitialParams<Key> {
     ctor public ItemKeyedDataSource.LoadInitialParams(Key?, int, boolean);
+  }
+
+  public static class ItemKeyedDataSource.LoadParams<Key> extends androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key> {
+    ctor public ItemKeyedDataSource.LoadParams(Key, int);
+  }
+
+  public abstract class ListenableItemKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
+    ctor public ListenableItemKeyedDataSource();
+    method public abstract Key? getKey(Value);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadAfter(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadBefore(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.InitialResult<Value>> loadInitial(androidx.paging.ListenableItemKeyedDataSource.LoadInitialParams<Key>);
+  }
+
+  public static class ListenableItemKeyedDataSource.InitialResult<V> {
+    ctor public ListenableItemKeyedDataSource.InitialResult(java.util.List<V>, int, int);
+    ctor public ListenableItemKeyedDataSource.InitialResult(java.util.List<V>);
+    method public boolean equals(Object?);
+  }
+
+  public static class ListenableItemKeyedDataSource.LoadInitialParams<Key> {
+    ctor public ListenableItemKeyedDataSource.LoadInitialParams(Key?, int, boolean);
     field public final boolean placeholdersEnabled;
     field public final Key? requestedInitialKey;
     field public final int requestedLoadSize;
   }
 
-  public static class ItemKeyedDataSource.LoadParams<Key> {
-    ctor public ItemKeyedDataSource.LoadParams(Key, int);
+  public static class ListenableItemKeyedDataSource.LoadParams<Key> {
+    ctor public ListenableItemKeyedDataSource.LoadParams(Key, int);
     field public final Key key;
     field public final int requestedLoadSize;
   }
 
-  public abstract class PageKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
+  public static class ListenableItemKeyedDataSource.Result<V> {
+    ctor public ListenableItemKeyedDataSource.Result(java.util.List<V>);
+    method public boolean equals(Object?);
+  }
+
+  public abstract class ListenablePageKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
+    ctor public ListenablePageKeyedDataSource();
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadAfter(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadBefore(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.InitialResult<Key,Value>> loadInitial(androidx.paging.ListenablePageKeyedDataSource.LoadInitialParams<Key>);
+  }
+
+  public static class ListenablePageKeyedDataSource.InitialResult<Key, Value> {
+    ctor public ListenablePageKeyedDataSource.InitialResult(java.util.List<Value>, int, int, Key?, Key?);
+    ctor public ListenablePageKeyedDataSource.InitialResult(java.util.List<Value>, Key?, Key?);
+    method public boolean equals(Object?);
+  }
+
+  public static class ListenablePageKeyedDataSource.LoadInitialParams<Key> {
+    ctor public ListenablePageKeyedDataSource.LoadInitialParams(int, boolean);
+    field public final boolean placeholdersEnabled;
+    field public final int requestedLoadSize;
+  }
+
+  public static class ListenablePageKeyedDataSource.LoadParams<Key> {
+    ctor public ListenablePageKeyedDataSource.LoadParams(Key, int);
+    field public final Key key;
+    field public final int requestedLoadSize;
+  }
+
+  public static class ListenablePageKeyedDataSource.Result<Key, Value> {
+    ctor public ListenablePageKeyedDataSource.Result(java.util.List<Value>, Key?);
+    method public boolean equals(Object?);
+  }
+
+  public abstract class ListenablePositionalDataSource<T> extends androidx.paging.DataSource<java.lang.Integer,T> {
+    ctor public ListenablePositionalDataSource();
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.InitialResult<T>> loadInitial(androidx.paging.ListenablePositionalDataSource.LoadInitialParams);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.RangeResult<T>> loadRange(androidx.paging.ListenablePositionalDataSource.LoadRangeParams);
+  }
+
+  public static class ListenablePositionalDataSource.InitialResult<V> {
+    ctor public ListenablePositionalDataSource.InitialResult(java.util.List<V>, int, int);
+    ctor public ListenablePositionalDataSource.InitialResult(java.util.List<V>, int);
+    method public boolean equals(Object?);
+  }
+
+  public static class ListenablePositionalDataSource.LoadInitialParams {
+    ctor public ListenablePositionalDataSource.LoadInitialParams(int, int, int, boolean);
+    field public final int pageSize;
+    field public final boolean placeholdersEnabled;
+    field public final int requestedLoadSize;
+    field public final int requestedStartPosition;
+  }
+
+  public static class ListenablePositionalDataSource.LoadRangeParams {
+    ctor public ListenablePositionalDataSource.LoadRangeParams(int, int);
+    field public final int loadSize;
+    field public final int startPosition;
+  }
+
+  public static class ListenablePositionalDataSource.RangeResult<V> {
+    ctor public ListenablePositionalDataSource.RangeResult(java.util.List<V>);
+    method public boolean equals(Object?);
+  }
+
+  public abstract class PageKeyedDataSource<Key, Value> extends androidx.paging.ListenablePageKeyedDataSource<Key,Value> {
+    ctor public PageKeyedDataSource();
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadAfter(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
     method public abstract void loadAfter(androidx.paging.PageKeyedDataSource.LoadParams<Key>, androidx.paging.PageKeyedDataSource.LoadCallback<Key,Value>);
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadBefore(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
     method public abstract void loadBefore(androidx.paging.PageKeyedDataSource.LoadParams<Key>, androidx.paging.PageKeyedDataSource.LoadCallback<Key,Value>);
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.InitialResult<Key,Value>> loadInitial(androidx.paging.ListenablePageKeyedDataSource.LoadInitialParams<Key>);
     method public abstract void loadInitial(androidx.paging.PageKeyedDataSource.LoadInitialParams<Key>, androidx.paging.PageKeyedDataSource.LoadInitialCallback<Key,Value>);
     method public final <ToValue> androidx.paging.PageKeyedDataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
     method public final <ToValue> androidx.paging.PageKeyedDataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
@@ -67,7 +162,6 @@
     ctor public PageKeyedDataSource.LoadCallback();
     method public void onError(Throwable);
     method public abstract void onResult(java.util.List<Value>, Key?);
-    method public void onRetryableError(Throwable);
   }
 
   public abstract static class PageKeyedDataSource.LoadInitialCallback<Key, Value> {
@@ -75,32 +169,27 @@
     method public void onError(Throwable);
     method public abstract void onResult(java.util.List<Value>, int, int, Key?, Key?);
     method public abstract void onResult(java.util.List<Value>, Key?, Key?);
-    method public void onRetryableError(Throwable);
   }
 
-  public static class PageKeyedDataSource.LoadInitialParams<Key> {
+  public static class PageKeyedDataSource.LoadInitialParams<Key> extends androidx.paging.ListenablePageKeyedDataSource.LoadInitialParams<Key> {
     ctor public PageKeyedDataSource.LoadInitialParams(int, boolean);
-    field public final boolean placeholdersEnabled;
-    field public final int requestedLoadSize;
   }
 
-  public static class PageKeyedDataSource.LoadParams<Key> {
+  public static class PageKeyedDataSource.LoadParams<Key> extends androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key> {
     ctor public PageKeyedDataSource.LoadParams(Key, int);
-    field public final Key key;
-    field public final int requestedLoadSize;
   }
 
   public abstract class PagedList<T> extends java.util.AbstractList<T> {
     method public void addWeakCallback(java.util.List<T>?, androidx.paging.PagedList.Callback);
     method public void addWeakLoadStateListener(androidx.paging.PagedList.LoadStateListener);
-    method public void detach();
+    method public abstract void detach();
     method public T? get(int);
     method public androidx.paging.PagedList.Config getConfig();
     method public abstract androidx.paging.DataSource<?,T> getDataSource();
     method public abstract Object? getLastKey();
     method public int getLoadedCount();
     method public int getPositionOffset();
-    method public boolean isDetached();
+    method public abstract boolean isDetached();
     method public boolean isImmutable();
     method public void loadAround(int);
     method public void removeWeakCallback(androidx.paging.PagedList.Callback);
@@ -120,8 +209,9 @@
   public static final class PagedList.Builder<Key, Value> {
     ctor public PagedList.Builder(androidx.paging.DataSource<Key,Value>, androidx.paging.PagedList.Config);
     ctor public PagedList.Builder(androidx.paging.DataSource<Key,Value>, int);
-    method @WorkerThread public androidx.paging.PagedList<Value> build();
-    method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback?);
+    method @Deprecated @WorkerThread public androidx.paging.PagedList<Value> build();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.paging.PagedList<Value>> buildAsync();
+    method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>?);
     method public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor);
     method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key?);
     method public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor);
@@ -171,10 +261,13 @@
     enum_constant public static final androidx.paging.PagedList.LoadType START;
   }
 
-  public abstract class PositionalDataSource<T> extends androidx.paging.DataSource<java.lang.Integer,T> {
-    method public static int computeInitialLoadPosition(androidx.paging.PositionalDataSource.LoadInitialParams, int);
-    method public static int computeInitialLoadSize(androidx.paging.PositionalDataSource.LoadInitialParams, int, int);
+  public abstract class PositionalDataSource<T> extends androidx.paging.ListenablePositionalDataSource<T> {
+    ctor public PositionalDataSource();
+    method public static int computeInitialLoadPosition(androidx.paging.ListenablePositionalDataSource.LoadInitialParams, int);
+    method public static int computeInitialLoadSize(androidx.paging.ListenablePositionalDataSource.LoadInitialParams, int, int);
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.InitialResult<T>> loadInitial(androidx.paging.ListenablePositionalDataSource.LoadInitialParams);
     method @WorkerThread public abstract void loadInitial(androidx.paging.PositionalDataSource.LoadInitialParams, androidx.paging.PositionalDataSource.LoadInitialCallback<T>);
+    method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.RangeResult<T>> loadRange(androidx.paging.ListenablePositionalDataSource.LoadRangeParams);
     method @WorkerThread public abstract void loadRange(androidx.paging.PositionalDataSource.LoadRangeParams, androidx.paging.PositionalDataSource.LoadRangeCallback<T>);
     method public final <V> androidx.paging.PositionalDataSource<V> map(androidx.arch.core.util.Function<T,V>);
     method public final <V> androidx.paging.PositionalDataSource<V> mapByPage(androidx.arch.core.util.Function<java.util.List<T>,java.util.List<V>>);
@@ -185,28 +278,20 @@
     method public void onError(Throwable);
     method public abstract void onResult(java.util.List<T>, int, int);
     method public abstract void onResult(java.util.List<T>, int);
-    method public void onRetryableError(Throwable);
   }
 
-  public static class PositionalDataSource.LoadInitialParams {
+  public static class PositionalDataSource.LoadInitialParams extends androidx.paging.ListenablePositionalDataSource.LoadInitialParams {
     ctor public PositionalDataSource.LoadInitialParams(int, int, int, boolean);
-    field public final int pageSize;
-    field public final boolean placeholdersEnabled;
-    field public final int requestedLoadSize;
-    field public final int requestedStartPosition;
   }
 
   public abstract static class PositionalDataSource.LoadRangeCallback<T> {
     ctor public PositionalDataSource.LoadRangeCallback();
     method public void onError(Throwable);
     method public abstract void onResult(java.util.List<T>);
-    method public void onRetryableError(Throwable);
   }
 
-  public static class PositionalDataSource.LoadRangeParams {
+  public static class PositionalDataSource.LoadRangeParams extends androidx.paging.ListenablePositionalDataSource.LoadRangeParams {
     ctor public PositionalDataSource.LoadRangeParams(int, int);
-    field public final int loadSize;
-    field public final int startPosition;
   }
 
 }