301 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			301 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package androidx.recyclerview.widget;
 | |
| 
 | |
| import androidx.core.os.TraceCompat;
 | |
| import androidx.recyclerview.widget.RecyclerView;
 | |
| import java.util.ArrayList;
 | |
| import java.util.Arrays;
 | |
| import java.util.Collections;
 | |
| import java.util.Comparator;
 | |
| import java.util.concurrent.TimeUnit;
 | |
| 
 | |
| /* loaded from: classes.dex */
 | |
| final class GapWorker implements Runnable {
 | |
|     static final ThreadLocal<GapWorker> sGapWorker = new ThreadLocal<>();
 | |
|     static Comparator<Task> sTaskComparator = new Comparator<Task>() { // from class: androidx.recyclerview.widget.GapWorker.1
 | |
|         @Override // java.util.Comparator
 | |
|         public int compare(Task task, Task task2) {
 | |
|             if ((task.view == null) != (task2.view == null)) {
 | |
|                 return task.view == null ? 1 : -1;
 | |
|             }
 | |
|             if (task.immediate != task2.immediate) {
 | |
|                 return task.immediate ? -1 : 1;
 | |
|             }
 | |
|             int i = task2.viewVelocity - task.viewVelocity;
 | |
|             if (i != 0) {
 | |
|                 return i;
 | |
|             }
 | |
|             int i2 = task.distanceToItem - task2.distanceToItem;
 | |
|             if (i2 != 0) {
 | |
|                 return i2;
 | |
|             }
 | |
|             return 0;
 | |
|         }
 | |
|     };
 | |
|     long mFrameIntervalNs;
 | |
|     long mPostTimeNs;
 | |
|     ArrayList<RecyclerView> mRecyclerViews = new ArrayList<>();
 | |
|     private ArrayList<Task> mTasks = new ArrayList<>();
 | |
| 
 | |
|     GapWorker() {
 | |
|     }
 | |
| 
 | |
|     static class Task {
 | |
|         public int distanceToItem;
 | |
|         public boolean immediate;
 | |
|         public int position;
 | |
|         public RecyclerView view;
 | |
|         public int viewVelocity;
 | |
| 
 | |
|         public void clear() {
 | |
|             this.immediate = false;
 | |
|             this.viewVelocity = 0;
 | |
|             this.distanceToItem = 0;
 | |
|             this.view = null;
 | |
|             this.position = 0;
 | |
|         }
 | |
| 
 | |
|         Task() {
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     static class LayoutPrefetchRegistryImpl implements RecyclerView.LayoutManager.LayoutPrefetchRegistry {
 | |
|         int mCount;
 | |
|         int[] mPrefetchArray;
 | |
|         int mPrefetchDx;
 | |
|         int mPrefetchDy;
 | |
| 
 | |
|         void setPrefetchVector(int i, int i2) {
 | |
|             this.mPrefetchDx = i;
 | |
|             this.mPrefetchDy = i2;
 | |
|         }
 | |
| 
 | |
|         LayoutPrefetchRegistryImpl() {
 | |
|         }
 | |
| 
 | |
|         void collectPrefetchPositionsFromView(RecyclerView recyclerView, boolean z) {
 | |
|             this.mCount = 0;
 | |
|             int[] iArr = this.mPrefetchArray;
 | |
|             if (iArr != null) {
 | |
|                 Arrays.fill(iArr, -1);
 | |
|             }
 | |
|             RecyclerView.LayoutManager layoutManager = recyclerView.mLayout;
 | |
|             if (recyclerView.mAdapter == null || layoutManager == null || !layoutManager.isItemPrefetchEnabled()) {
 | |
|                 return;
 | |
|             }
 | |
|             if (z) {
 | |
|                 if (!recyclerView.mAdapterHelper.hasPendingUpdates()) {
 | |
|                     layoutManager.collectInitialPrefetchPositions(recyclerView.mAdapter.getItemCount(), this);
 | |
|                 }
 | |
|             } else if (!recyclerView.hasPendingAdapterUpdates()) {
 | |
|                 layoutManager.collectAdjacentPrefetchPositions(this.mPrefetchDx, this.mPrefetchDy, recyclerView.mState, this);
 | |
|             }
 | |
|             if (this.mCount > layoutManager.mPrefetchMaxCountObserved) {
 | |
|                 layoutManager.mPrefetchMaxCountObserved = this.mCount;
 | |
|                 layoutManager.mPrefetchMaxObservedInInitialPrefetch = z;
 | |
|                 recyclerView.mRecycler.updateViewCacheSize();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         @Override // androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry
 | |
|         public void addPosition(int i, int i2) {
 | |
|             if (i < 0) {
 | |
|                 throw new IllegalArgumentException("Layout positions must be non-negative");
 | |
|             }
 | |
|             if (i2 < 0) {
 | |
|                 throw new IllegalArgumentException("Pixel distance must be non-negative");
 | |
|             }
 | |
|             int i3 = this.mCount;
 | |
|             int i4 = i3 * 2;
 | |
|             int[] iArr = this.mPrefetchArray;
 | |
|             if (iArr == null) {
 | |
|                 int[] iArr2 = new int[4];
 | |
|                 this.mPrefetchArray = iArr2;
 | |
|                 Arrays.fill(iArr2, -1);
 | |
|             } else if (i4 >= iArr.length) {
 | |
|                 int[] iArr3 = new int[i3 * 4];
 | |
|                 this.mPrefetchArray = iArr3;
 | |
|                 System.arraycopy(iArr, 0, iArr3, 0, iArr.length);
 | |
|             }
 | |
|             int[] iArr4 = this.mPrefetchArray;
 | |
|             iArr4[i4] = i;
 | |
|             iArr4[i4 + 1] = i2;
 | |
|             this.mCount++;
 | |
|         }
 | |
| 
 | |
|         boolean lastPrefetchIncludedPosition(int i) {
 | |
|             if (this.mPrefetchArray != null) {
 | |
|                 int i2 = this.mCount * 2;
 | |
|                 for (int i3 = 0; i3 < i2; i3 += 2) {
 | |
|                     if (this.mPrefetchArray[i3] == i) {
 | |
|                         return true;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         void clearPrefetchPositions() {
 | |
|             int[] iArr = this.mPrefetchArray;
 | |
|             if (iArr != null) {
 | |
|                 Arrays.fill(iArr, -1);
 | |
|             }
 | |
|             this.mCount = 0;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public void add(RecyclerView recyclerView) {
 | |
|         this.mRecyclerViews.add(recyclerView);
 | |
|     }
 | |
| 
 | |
|     public void remove(RecyclerView recyclerView) {
 | |
|         this.mRecyclerViews.remove(recyclerView);
 | |
|     }
 | |
| 
 | |
|     void postFromTraversal(RecyclerView recyclerView, int i, int i2) {
 | |
|         if (recyclerView.isAttachedToWindow() && this.mPostTimeNs == 0) {
 | |
|             this.mPostTimeNs = recyclerView.getNanoTime();
 | |
|             recyclerView.post(this);
 | |
|         }
 | |
|         recyclerView.mPrefetchRegistry.setPrefetchVector(i, i2);
 | |
|     }
 | |
| 
 | |
|     private void buildTaskList() {
 | |
|         Task task;
 | |
|         int size = this.mRecyclerViews.size();
 | |
|         int i = 0;
 | |
|         for (int i2 = 0; i2 < size; i2++) {
 | |
|             RecyclerView recyclerView = this.mRecyclerViews.get(i2);
 | |
|             if (recyclerView.getWindowVisibility() == 0) {
 | |
|                 recyclerView.mPrefetchRegistry.collectPrefetchPositionsFromView(recyclerView, false);
 | |
|                 i += recyclerView.mPrefetchRegistry.mCount;
 | |
|             }
 | |
|         }
 | |
|         this.mTasks.ensureCapacity(i);
 | |
|         int i3 = 0;
 | |
|         for (int i4 = 0; i4 < size; i4++) {
 | |
|             RecyclerView recyclerView2 = this.mRecyclerViews.get(i4);
 | |
|             if (recyclerView2.getWindowVisibility() == 0) {
 | |
|                 LayoutPrefetchRegistryImpl layoutPrefetchRegistryImpl = recyclerView2.mPrefetchRegistry;
 | |
|                 int abs = Math.abs(layoutPrefetchRegistryImpl.mPrefetchDx) + Math.abs(layoutPrefetchRegistryImpl.mPrefetchDy);
 | |
|                 for (int i5 = 0; i5 < layoutPrefetchRegistryImpl.mCount * 2; i5 += 2) {
 | |
|                     if (i3 >= this.mTasks.size()) {
 | |
|                         task = new Task();
 | |
|                         this.mTasks.add(task);
 | |
|                     } else {
 | |
|                         task = this.mTasks.get(i3);
 | |
|                     }
 | |
|                     int i6 = layoutPrefetchRegistryImpl.mPrefetchArray[i5 + 1];
 | |
|                     task.immediate = i6 <= abs;
 | |
|                     task.viewVelocity = abs;
 | |
|                     task.distanceToItem = i6;
 | |
|                     task.view = recyclerView2;
 | |
|                     task.position = layoutPrefetchRegistryImpl.mPrefetchArray[i5];
 | |
|                     i3++;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         Collections.sort(this.mTasks, sTaskComparator);
 | |
|     }
 | |
| 
 | |
|     static boolean isPrefetchPositionAttached(RecyclerView recyclerView, int i) {
 | |
|         int unfilteredChildCount = recyclerView.mChildHelper.getUnfilteredChildCount();
 | |
|         for (int i2 = 0; i2 < unfilteredChildCount; i2++) {
 | |
|             RecyclerView.ViewHolder childViewHolderInt = RecyclerView.getChildViewHolderInt(recyclerView.mChildHelper.getUnfilteredChildAt(i2));
 | |
|             if (childViewHolderInt.mPosition == i && !childViewHolderInt.isInvalid()) {
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     private RecyclerView.ViewHolder prefetchPositionWithDeadline(RecyclerView recyclerView, int i, long j) {
 | |
|         if (isPrefetchPositionAttached(recyclerView, i)) {
 | |
|             return null;
 | |
|         }
 | |
|         RecyclerView.Recycler recycler = recyclerView.mRecycler;
 | |
|         try {
 | |
|             recyclerView.onEnterLayoutOrScroll();
 | |
|             RecyclerView.ViewHolder tryGetViewHolderForPositionByDeadline = recycler.tryGetViewHolderForPositionByDeadline(i, false, j);
 | |
|             if (tryGetViewHolderForPositionByDeadline != null) {
 | |
|                 if (tryGetViewHolderForPositionByDeadline.isBound() && !tryGetViewHolderForPositionByDeadline.isInvalid()) {
 | |
|                     recycler.recycleView(tryGetViewHolderForPositionByDeadline.itemView);
 | |
|                 } else {
 | |
|                     recycler.addViewHolderToRecycledViewPool(tryGetViewHolderForPositionByDeadline, false);
 | |
|                 }
 | |
|             }
 | |
|             return tryGetViewHolderForPositionByDeadline;
 | |
|         } finally {
 | |
|             recyclerView.onExitLayoutOrScroll(false);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void prefetchInnerRecyclerViewWithDeadline(RecyclerView recyclerView, long j) {
 | |
|         if (recyclerView == null) {
 | |
|             return;
 | |
|         }
 | |
|         if (recyclerView.mDataSetHasChangedAfterLayout && recyclerView.mChildHelper.getUnfilteredChildCount() != 0) {
 | |
|             recyclerView.removeAndRecycleViews();
 | |
|         }
 | |
|         LayoutPrefetchRegistryImpl layoutPrefetchRegistryImpl = recyclerView.mPrefetchRegistry;
 | |
|         layoutPrefetchRegistryImpl.collectPrefetchPositionsFromView(recyclerView, true);
 | |
|         if (layoutPrefetchRegistryImpl.mCount != 0) {
 | |
|             try {
 | |
|                 TraceCompat.beginSection("RV Nested Prefetch");
 | |
|                 recyclerView.mState.prepareForNestedPrefetch(recyclerView.mAdapter);
 | |
|                 for (int i = 0; i < layoutPrefetchRegistryImpl.mCount * 2; i += 2) {
 | |
|                     prefetchPositionWithDeadline(recyclerView, layoutPrefetchRegistryImpl.mPrefetchArray[i], j);
 | |
|                 }
 | |
|             } finally {
 | |
|                 TraceCompat.endSection();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void flushTaskWithDeadline(Task task, long j) {
 | |
|         RecyclerView.ViewHolder prefetchPositionWithDeadline = prefetchPositionWithDeadline(task.view, task.position, task.immediate ? Long.MAX_VALUE : j);
 | |
|         if (prefetchPositionWithDeadline == null || prefetchPositionWithDeadline.mNestedRecyclerView == null || !prefetchPositionWithDeadline.isBound() || prefetchPositionWithDeadline.isInvalid()) {
 | |
|             return;
 | |
|         }
 | |
|         prefetchInnerRecyclerViewWithDeadline(prefetchPositionWithDeadline.mNestedRecyclerView.get(), j);
 | |
|     }
 | |
| 
 | |
|     private void flushTasksWithDeadline(long j) {
 | |
|         for (int i = 0; i < this.mTasks.size(); i++) {
 | |
|             Task task = this.mTasks.get(i);
 | |
|             if (task.view == null) {
 | |
|                 return;
 | |
|             }
 | |
|             flushTaskWithDeadline(task, j);
 | |
|             task.clear();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     void prefetch(long j) {
 | |
|         buildTaskList();
 | |
|         flushTasksWithDeadline(j);
 | |
|     }
 | |
| 
 | |
|     @Override // java.lang.Runnable
 | |
|     public void run() {
 | |
|         try {
 | |
|             TraceCompat.beginSection("RV Prefetch");
 | |
|             if (!this.mRecyclerViews.isEmpty()) {
 | |
|                 int size = this.mRecyclerViews.size();
 | |
|                 long j = 0;
 | |
|                 for (int i = 0; i < size; i++) {
 | |
|                     RecyclerView recyclerView = this.mRecyclerViews.get(i);
 | |
|                     if (recyclerView.getWindowVisibility() == 0) {
 | |
|                         j = Math.max(recyclerView.getDrawingTime(), j);
 | |
|                     }
 | |
|                 }
 | |
|                 if (j != 0) {
 | |
|                     prefetch(TimeUnit.MILLISECONDS.toNanos(j) + this.mFrameIntervalNs);
 | |
|                 }
 | |
|             }
 | |
|         } finally {
 | |
|             this.mPostTimeNs = 0L;
 | |
|             TraceCompat.endSection();
 | |
|         }
 | |
|     }
 | |
| }
 |