diff options
author | Christofer Ã…kersten <akersten@google.com> | 2019-02-04 17:56:10 -0800 |
---|---|---|
committer | Christofer Ã…kersten <akersten@google.com> | 2019-02-04 17:56:10 -0800 |
commit | 31ab3fd96a150282f045d006f620d32495601b7b (patch) | |
tree | 8d36685a0dff6719a6c06b2253a9af10edbe5b78 | |
parent | d7cdc7bc09e1e43bf0440a606a8f16555535607a (diff) | |
download | UniversalMediaPlayer-31ab3fd96a150282f045d006f620d32495601b7b.tar.gz |
Remove unused classes
Test: compile
Change-Id: If790a3c8044bb1e1dca2d258cccae818bec10cac
-rw-r--r-- | java/com/android/pump/concurrent/DirectExecutor.java | 33 | ||||
-rw-r--r-- | java/com/android/pump/concurrent/MainThreadExecutor.java | 47 | ||||
-rw-r--r-- | java/com/android/pump/concurrent/Task.java | 49 | ||||
-rw-r--r-- | java/com/android/pump/concurrent/TaskExecutor.java | 99 | ||||
-rw-r--r-- | java/com/android/pump/concurrent/TaskQueue.java | 465 | ||||
-rw-r--r-- | java/com/android/pump/concurrent/UiThreadExecutor.java | 31 | ||||
-rw-r--r-- | java/com/android/pump/concurrent/UriTask.java | 38 | ||||
-rw-r--r-- | java/com/android/pump/util/OrderedCollection.java | 124 | ||||
-rw-r--r-- | java/com/android/pump/widget/HeaderRecyclerView.java | 294 |
9 files changed, 0 insertions, 1180 deletions
diff --git a/java/com/android/pump/concurrent/DirectExecutor.java b/java/com/android/pump/concurrent/DirectExecutor.java deleted file mode 100644 index 089960c..0000000 --- a/java/com/android/pump/concurrent/DirectExecutor.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.concurrent; - -import java.util.concurrent.Executor; - -import androidx.annotation.AnyThread; -import androidx.annotation.NonNull; - -@AnyThread -public final class DirectExecutor { - private static final Executor EXECUTOR = Runnable::run; - - private DirectExecutor() { } - - public static @NonNull Executor get() { - return EXECUTOR; - } -} diff --git a/java/com/android/pump/concurrent/MainThreadExecutor.java b/java/com/android/pump/concurrent/MainThreadExecutor.java deleted file mode 100644 index eb87b87..0000000 --- a/java/com/android/pump/concurrent/MainThreadExecutor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.concurrent; - -import android.os.Handler; -import android.os.Looper; - -import java.util.concurrent.Executor; - -import androidx.annotation.AnyThread; -import androidx.annotation.NonNull; - -@AnyThread -public final class MainThreadExecutor { - private static final Executor EXECUTOR = new Executor() { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - @Override - public void execute(@NonNull Runnable command) { - if (mHandler.getLooper() != Looper.myLooper()) { - mHandler.post(command); - } else { - command.run(); - } - } - }; - - private MainThreadExecutor() { } - - public static @NonNull Executor get() { - return EXECUTOR; - } -} diff --git a/java/com/android/pump/concurrent/Task.java b/java/com/android/pump/concurrent/Task.java deleted file mode 100644 index 34e725d..0000000 --- a/java/com/android/pump/concurrent/Task.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.concurrent; - -import androidx.annotation.AnyThread; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -@AnyThread -public abstract class Task implements Runnable { - private boolean mCancelled; - - public abstract void execute(); - - public abstract void merge(@NonNull Task task); - - public abstract void finish(); - - @Override - public final void run() { - if (!mCancelled) { - execute(); - } - } - - @Override - public abstract boolean equals(@Nullable Object obj); - - @Override - public abstract int hashCode(); - - void cancel() { - mCancelled = true; - } -} diff --git a/java/com/android/pump/concurrent/TaskExecutor.java b/java/com/android/pump/concurrent/TaskExecutor.java deleted file mode 100644 index 458e42e..0000000 --- a/java/com/android/pump/concurrent/TaskExecutor.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.concurrent; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import androidx.annotation.AnyThread; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -@AnyThread -public class TaskExecutor extends ThreadPoolExecutor { - public static @NonNull ExecutorService newFixedThreadPool(int nThreads) { - return new TaskExecutor(nThreads, nThreads, 0, TimeUnit.MILLISECONDS, new TaskQueue()); - } - - public static @NonNull ExecutorService newFixedThreadPool(int nThreads, - @NonNull ThreadFactory threadFactory) { - return new TaskExecutor(nThreads, nThreads, 0, TimeUnit.MILLISECONDS, new TaskQueue(), - threadFactory); - } - - public static @NonNull ExecutorService newCachedThreadPool() { - return new TaskExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new TaskQueue()); - } - - public static @NonNull ExecutorService newCachedThreadPool( - @NonNull ThreadFactory threadFactory) { - return new TaskExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new TaskQueue(), - threadFactory); - } - - public TaskExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, - @NonNull TimeUnit unit, @NonNull TaskQueue workQueue) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); - } - - public TaskExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, - @NonNull TimeUnit unit, @NonNull TaskQueue workQueue, - @NonNull ThreadFactory threadFactory) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); - } - - public TaskExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, - @NonNull TimeUnit unit, @NonNull TaskQueue workQueue, - @NonNull RejectedExecutionHandler handler) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); - } - - public TaskExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, - @NonNull TimeUnit unit, @NonNull TaskQueue workQueue, - @NonNull ThreadFactory threadFactory, @NonNull RejectedExecutionHandler handler) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, - handler); - } - - @Override - public void execute(@NonNull Runnable command) { - if (!(command instanceof Task)) { - throw new IllegalArgumentException("The Runnable must be a Task"); - } - super.execute(command); - } - - @Override - protected void beforeExecute(@NonNull Thread t, @NonNull Runnable r) { - getQueue().prepare((Task) r); - super.beforeExecute(t, r); - } - - @Override - protected void afterExecute(@NonNull Runnable r, @Nullable Throwable t) { - super.afterExecute(r, t); - getQueue().finish((Task) r); - } - - @Override - public @NonNull TaskQueue getQueue() { - return (TaskQueue) super.getQueue(); - } -} diff --git a/java/com/android/pump/concurrent/TaskQueue.java b/java/com/android/pump/concurrent/TaskQueue.java deleted file mode 100644 index dc0d93f..0000000 --- a/java/com/android/pump/concurrent/TaskQueue.java +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.concurrent; - -import com.android.pump.util.Clog; - -import java.util.AbstractQueue; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; - -import androidx.annotation.AnyThread; -import androidx.annotation.GuardedBy; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -@AnyThread -public class TaskQueue extends AbstractQueue<Runnable> implements BlockingQueue<Runnable> { - private static final String TAG = Clog.tag(TaskQueue.class); - - private static final int NANOS_PER_MILLI = 1000000; - - private final Object mLock = new Object(); - - @GuardedBy("mLock") - private final List mQueue = new List(); - @GuardedBy("mLock") - private final List mRunning = new List(); - - @Override - public @NonNull Iterator<Runnable> iterator() { - Clog.i(TAG, "iterator()"); - return new Iterator<Runnable>() { - private final Iterator<Runnable> mIterator = mQueue.iterator(); - - @Override - public boolean hasNext() { - synchronized (mLock) { - return mIterator.hasNext(); - } - } - - @Override - public @Nullable Runnable next() { - synchronized (mLock) { - return mIterator.next(); - } - } - - @Override - public void remove() { - synchronized (mLock) { - mIterator.remove(); - } - } - }; - } - - @Override - public int size() { - Clog.i(TAG, "size()"); - return mQueue.size(); - } - - @Override - public void put(@NonNull Runnable runnable) throws InterruptedException { - Clog.i(TAG, "put(" + runnable + ")"); - offer(runnable); - } - - @Override - public boolean offer(@NonNull Runnable runnable, long timeout, @NonNull TimeUnit unit) - throws InterruptedException { - Clog.i(TAG, "offer(" + runnable + ", " + timeout + ", " + unit + ")"); - return offer(runnable); - } - - @Override - public @NonNull Runnable take() throws InterruptedException { - Clog.i(TAG, "take()"); - synchronized (mLock) { - while (mQueue.size() == 0) { - mLock.wait(); - } - Task task = dequeue(); - if (mQueue.size() > 0) { - mLock.notifyAll(); - } - return task; - } - } - - @Override - public @Nullable Runnable poll(long timeout, @NonNull TimeUnit unit) - throws InterruptedException { - Clog.i(TAG, "poll(" + timeout + ", " + unit + ")"); - synchronized (mLock) { - if (mQueue.size() == 0) { - wait(timeout, unit); - if (mQueue.size() == 0) { - return null; - } - } - Task task = dequeue(); - if (mQueue.size() > 0) { - mLock.notifyAll(); - } - return task; - } - } - - @Override - public int remainingCapacity() { - Clog.i(TAG, "remainingCapacity()"); - return Integer.MAX_VALUE; - } - - @Override - public int drainTo(@NonNull Collection<? super Runnable> c) { - Clog.i(TAG, "drainTo(" + c + ")"); - return drainTo(c, Integer.MAX_VALUE); - } - - @Override - public int drainTo(@NonNull Collection<? super Runnable> c, int maxElements) { - Clog.i(TAG, "drainTo(" + c + ", " + maxElements + ")"); - if (c == this) { - throw new IllegalArgumentException("Queue can't drain itself"); - } - if (maxElements <= 0) { - return 0; - } - synchronized (mLock) { - /* - int n = Math.min(mCount, maxElements); - Node node = mHead; - for (int i = 0; i < n; ++i) { - c.add(node.task); - node = node.next; - } - mHead = node; - if (mHead == null) { - mTail = null; - } - mCount -= n; - mModificationId++; - return n; - */ - throw new IllegalStateException("Not yet implemented"); - } - } - - @Override - public boolean offer(@NonNull Runnable runnable) { - Clog.i(TAG, "offer(" + runnable + ")"); - if (!(runnable instanceof Task)) { - throw new IllegalArgumentException("The Runnable must be a Task"); - } - synchronized (mLock) { - boolean notify = mQueue.size() == 0; - enqueue((Task) runnable); - if (notify) { - mLock.notifyAll(); - } - return true; - } - } - - @Override - public @Nullable Runnable poll() { - Clog.i(TAG, "poll()"); - synchronized (mLock) { - if (mQueue.size() == 0) { - return null; - } - Task task = dequeue(); - if (mQueue.size() > 0) { - mLock.notifyAll(); - } - return task; - } - } - - @Override - public @Nullable Runnable peek() { - Clog.i(TAG, "peek()"); - synchronized (mLock) { - return mQueue.peek(); - } - } - - @Override - public boolean remove(@Nullable Object o) { - Clog.i(TAG, "remove(" + o + ")"); - if (!(o instanceof Task)) { - return false; - } - synchronized (mLock) { - return mQueue.remove((Task) o) != null; - } - } - - @Override - public boolean contains(@Nullable Object o) { - Clog.i(TAG, "contains(" + o + ")"); - if (!(o instanceof Task)) { - return false; - } - synchronized (mLock) { - return mQueue.find((Task) o) != null; - } - } - - @Override - public @NonNull Object[] toArray() { - Clog.i(TAG, "toArray()"); - synchronized (mLock) { - /* - Object[] a = new Object[mCount]; - int i = 0; - for (Node node = mHead; node != null; node = node.next) { - a[i++] = node.task; - } - return a; - */ - throw new IllegalStateException("Not yet implemented"); - } - } - - @Override - public @NonNull <T> T[] toArray(@NonNull T[] a) { - Clog.i(TAG, "toArray(" + a + ")"); - synchronized (mLock) { - /* - if (a.length < mCount) { - a = (T[]) Array.newInstance(a.getClass().getComponentType(), mCount); - } - int i = 0; - for (Node node = mHead; node != null; node = node.next) { - a[i++] = (T) node.task; - } - if (a.length > i) { - a[i] = null; - } - return a; - */ - throw new IllegalStateException("Not yet implemented"); - } - } - - @Override - public void clear() { - Clog.i(TAG, "clear()"); - synchronized (mLock) { - mQueue.clear(); - } - } - - void prepare(@NonNull Task task) { - Clog.i(TAG, "prepare(" + task + ")"); - synchronized (mLock) { - Task runningTask = mRunning.find(task); - if (runningTask != null) { - if (runningTask != task) { - runningTask.merge(task); // TODO find another solution - task.cancel(); - } - } else { - Task queuedTask = mQueue.remove(task); - if (queuedTask != null) { - task.merge(queuedTask); // TODO find another solution - } - mRunning.put(task); - } - } - } - - void finish(@NonNull Task task) { - Clog.i(TAG, "finished(" + task + ")"); - synchronized (mLock) { - Task removed = mRunning.remove(task); - if (removed != task) { - throw new IllegalStateException("Failed to find running task " + task + - " found " + removed); - } - } - task.finish(); - } - - @GuardedBy("mLock") - private void enqueue(@NonNull Task task) { - Clog.i(TAG, "enqueue(" + task + ")"); - Task runningTask = mRunning.find(task); - if (runningTask != null) { - runningTask.merge(task); // TODO find another solution - return; - } - Task queuedTask = mQueue.find(task); - if (queuedTask != null) { - queuedTask.merge(task); // TODO find another solution - return; - } - mQueue.put(task); - } - - @GuardedBy("mLock") - private @NonNull Task dequeue() { - Clog.i(TAG, "dequeue()"); - // TODO Reuse the node just dequeued - Task task = mQueue.get(); - mRunning.put(task); - return task; - } - - @GuardedBy("mLock") - private void wait(long timeout, @NonNull TimeUnit unit) throws InterruptedException { - long duration = unit.toNanos(timeout); - long start = System.nanoTime(); - for (;;) { - mLock.wait(duration / NANOS_PER_MILLI, (int) (duration % NANOS_PER_MILLI)); - long now = System.nanoTime(); - long elapsed = now - start; - if (elapsed >= duration) { - break; - } - duration -= elapsed; - start = now; - } - } - - private static class List { - private int mModificationId; - - private int mSize; - private Node mHead; - - private int size() { - return mSize; - } - - private void clear() { - mModificationId++; - mSize = 0; - mHead = null; - } - - private @Nullable Task peek() { - return mHead == null ? null : mHead.task; - } - - private void put(@NonNull Task task) { - mModificationId++; - mSize++; - mHead = new Node(task, mHead); - } - - private @NonNull Task get() { - mModificationId++; - mSize--; - Node node = mHead; - mHead = node.next; - return node.task; - } - - private @Nullable Task find(@NonNull Task task) { - for (Node node = mHead; node != null; node = node.next) { - if (task.equals(node.task)) { - return node.task; - } - } - return null; - } - - private @Nullable Task remove(@NonNull Task task) { - for (Node node = mHead, prev = null; node != null; node = (prev = node).next) { - if (task.equals(node.task)) { - mModificationId++; - mSize--; - if (prev == null) { - mHead = node.next; - } else { - prev.next = node.next; - } - return node.task; - } - } - return null; - } - - private @NonNull Iterator<Runnable> iterator() { - return new Iterator<Runnable>() { - private int mExpectedModificationId; - - private Node mPrev; - private Node mCurrent; - private Node mNext = mHead; - - @Override - public boolean hasNext() { - return mNext != null; - } - - @Override - public @NonNull Runnable next() { - if (mModificationId != mExpectedModificationId) { - throw new ConcurrentModificationException(); - } - if (mNext == null) { - throw new NoSuchElementException(); - } - mPrev = mCurrent; - mCurrent = mNext; - mNext = mNext.next; - return mCurrent.task; - } - - @Override - public void remove() { - if (mModificationId != mExpectedModificationId) { - throw new ConcurrentModificationException(); - } - if (mCurrent == mPrev) { - throw new IllegalStateException(); - } - mModificationId++; - mSize--; - if (mPrev == null) { - mHead = mNext; - } else { - mPrev.next = mNext; - } - mCurrent = mPrev; - mExpectedModificationId = mModificationId; - } - }; - } - - private static class Node { - private final Task task; - private Node next; - - private Node(@NonNull Task task, @Nullable Node next) { - this.task = task; - this.next = next; - } - } - } -} diff --git a/java/com/android/pump/concurrent/UiThreadExecutor.java b/java/com/android/pump/concurrent/UiThreadExecutor.java deleted file mode 100644 index 2b7e320..0000000 --- a/java/com/android/pump/concurrent/UiThreadExecutor.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.concurrent; - -import java.util.concurrent.Executor; - -import androidx.annotation.AnyThread; -import androidx.annotation.NonNull; - -@AnyThread -public final class UiThreadExecutor { - private UiThreadExecutor() { } - - public static @NonNull Executor get() { - return MainThreadExecutor.get(); - } -} diff --git a/java/com/android/pump/concurrent/UriTask.java b/java/com/android/pump/concurrent/UriTask.java deleted file mode 100644 index 495d19b..0000000 --- a/java/com/android/pump/concurrent/UriTask.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.concurrent; - -import android.net.Uri; - -import androidx.annotation.AnyThread; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -@AnyThread -public abstract class UriTask extends Task { - public abstract @NonNull Uri getUri(); - - @Override - public final boolean equals(@Nullable Object obj) { - return obj instanceof UriTask && getUri().equals(((UriTask) obj).getUri()); - } - - @Override - public final int hashCode() { - return getUri().hashCode(); - } -} diff --git a/java/com/android/pump/util/OrderedCollection.java b/java/com/android/pump/util/OrderedCollection.java deleted file mode 100644 index a25ca14..0000000 --- a/java/com/android/pump/util/OrderedCollection.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.util; - -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import androidx.annotation.AnyThread; -import androidx.annotation.NonNull; - -@AnyThread -public class OrderedCollection<T, U> extends AbstractCollection<T> { - private final KeyRetriever<T, U> mKeyRetriever; - private final KeyComparator<U> mKeyComparator; - private final List<T> mItems = new ArrayList<>(); - - @FunctionalInterface - public interface KeyRetriever<T, U> { - @NonNull U getKey(@NonNull T value); - } - - @FunctionalInterface - public interface KeyComparator<U> { - int compare(@NonNull U lhs, @NonNull U rhs); - } - - public OrderedCollection(@NonNull KeyRetriever<T, U> keyRetriever, - @NonNull KeyComparator<U> keyComparator) { - mKeyRetriever = keyRetriever; - mKeyComparator = keyComparator; - } - - public @NonNull T get(@NonNull U key) { - int index = indexOfU(key); - if (index >= 0) { - return mItems.get(index); - } - throw new IllegalArgumentException(); - } - - @Override - public @NonNull Iterator<T> iterator() { - return mItems.iterator(); - } - - @Override - public int size() { - return mItems.size(); - } - - @Override - public boolean contains(@NonNull Object o) { - return indexOfO(o) >= 0; - } - - @Override - public boolean add(@NonNull T e) { - int index = indexOfT(e); - if (index >= 0) { - return false; - } - mItems.add(~index, e); - return true; - } - - @Override - public boolean remove(@NonNull Object o) { - int index = indexOfO(o); - if (index >= 0) { - mItems.remove(index); - return true; - } - return false; - } - - @Override - public void clear() { - mItems.clear(); - } - - @SuppressWarnings("unchecked") - private int indexOfO(@NonNull Object o) { - return indexOfT((T) o); - } - - private int indexOfT(@NonNull T e) { - return indexOfU(mKeyRetriever.getKey(e)); - } - - private int indexOfU(@NonNull U key) { - int lo = 0; - int hi = mItems.size() - 1; - - while (lo <= hi) { - int mid = (lo + hi) >>> 1; - int cmp = mKeyComparator.compare(mKeyRetriever.getKey(mItems.get(mid)), key); - - if (cmp < 0) { - lo = mid + 1; - } else if (cmp > 0) { - hi = mid - 1; - } else { - return mid; - } - } - return ~lo; - } -} diff --git a/java/com/android/pump/widget/HeaderRecyclerView.java b/java/com/android/pump/widget/HeaderRecyclerView.java deleted file mode 100644 index c2a1c51..0000000 --- a/java/com/android/pump/widget/HeaderRecyclerView.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.pump.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; - -import java.util.List; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup; -import androidx.recyclerview.widget.RecyclerView; - -@UiThread -public class HeaderRecyclerView extends RecyclerView { - public HeaderRecyclerView(@NonNull Context context) { - super(context); - } - - public HeaderRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - } - - public HeaderRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, - int defStyle) { - super(context, attrs, defStyle); - } - - @Override - public void swapAdapter(@Nullable Adapter adapter, boolean removeAndRecycleExistingViews) { - if (adapter != null && !(adapter instanceof HeaderRecyclerAdapter)) { - adapter = new HeaderRecyclerAdapter<>(cast(adapter)); - } - super.swapAdapter(adapter, removeAndRecycleExistingViews); - } - - @Override - public void setAdapter(@Nullable Adapter adapter) { - if (adapter != null && !(adapter instanceof HeaderRecyclerAdapter)) { - adapter = new HeaderRecyclerAdapter<>(cast(adapter)); - } - super.setAdapter(adapter); - } - - @Override - public void setLayoutManager(@Nullable LayoutManager layoutManager) { - if (layoutManager instanceof GridLayoutManager) { - GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager; - // TODO override GridLayoutManager.setSpanCount() & setSpanSizeLookup() - SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup(); - if (!(spanSizeLookup instanceof HeaderSpanSizeLookup)) { - gridLayoutManager.setSpanSizeLookup(new HeaderSpanSizeLookup(spanSizeLookup, - gridLayoutManager.getSpanCount())); - } - } - super.setLayoutManager(layoutManager); - } - - @SuppressWarnings("unchecked") - private static <T> T cast(@Nullable Object obj) { - return (T) obj; - } - - private static class HeaderRecyclerAdapter<VH extends ViewHolder> extends Adapter<ViewHolder> { - private final static int HEADER = Integer.MIN_VALUE; - //private final static int FOOTER = Integer.MAX_VALUE; TODO add footer - - private final Adapter<VH> mDelegate; - - private HeaderRecyclerAdapter(@NonNull Adapter<VH> delegate) { - mDelegate = delegate; - setHasStableIds(mDelegate.hasStableIds()); - mDelegate.registerAdapterDataObserver(new AdapterDataObserver() { - @Override - public void onChanged() { - notifyDataSetChanged(); - } - - @Override - public void onItemRangeChanged(int positionStart, int itemCount) { - notifyItemRangeChanged(toPosition(positionStart), itemCount); - } - - @Override - public void onItemRangeChanged(int positionStart, int itemCount, - @Nullable Object payload) { - notifyItemRangeChanged(toPosition(positionStart), itemCount, payload); - } - - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - notifyItemRangeInserted(toPosition(positionStart), itemCount); - } - - @Override - public void onItemRangeRemoved(int positionStart, int itemCount) { - notifyItemRangeRemoved(toPosition(positionStart), itemCount); - } - - @Override - public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { - for (int i = 0; i < itemCount; ++i) { - notifyItemMoved(toPosition(fromPosition + i), toPosition(toPosition + i)); - } - } - }); - } - - @Override - public @NonNull ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if (viewType == HEADER) { - // TODO Handle this differently? - FrameLayout frameLayout = new FrameLayout(parent.getContext()); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.WRAP_CONTENT); - frameLayout.setLayoutParams(params); - - return new HeaderViewHolder(frameLayout); - } else { - return mDelegate.onCreateViewHolder(parent, viewType); - } - } - - @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - if (isHeader(position)) { - // TODO - } else { - mDelegate.onBindViewHolder(cast(holder), fromPosition(position)); - } - } - - @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position, - @NonNull List<Object> payloads) { - if (isHeader(position)) { - onBindViewHolder(holder, position); - } else { - mDelegate.onBindViewHolder(cast(holder), fromPosition(position), payloads); - } - } - - @Override - public int getItemViewType(int position) { - if (isHeader(position)) { - return HEADER; - } - return mDelegate.getItemViewType(fromPosition(position)); - } - - @Override - public long getItemId(int position) { - if (isHeader(position)) { - return Long.MIN_VALUE; - } - return mDelegate.getItemId(fromPosition(position)); - } - - @Override - public int getItemCount() { - return getCount(mDelegate.getItemCount()); - } - - @Override - public void onViewRecycled(@NonNull ViewHolder holder) { - if (!(holder instanceof HeaderViewHolder)) { - mDelegate.onViewRecycled(cast(holder)); - } - } - - @Override - public boolean onFailedToRecycleView(@NonNull ViewHolder holder) { - if (!(holder instanceof HeaderViewHolder)) { - mDelegate.onFailedToRecycleView(cast(holder)); - } - return false; - } - - @Override - public void onViewAttachedToWindow(@NonNull ViewHolder holder) { - if (!(holder instanceof HeaderViewHolder)) { - mDelegate.onViewAttachedToWindow(cast(holder)); - } - } - - @Override - public void onViewDetachedFromWindow(@NonNull ViewHolder holder) { - if (!(holder instanceof HeaderViewHolder)) { - mDelegate.onViewDetachedFromWindow(cast(holder)); - } - } - - @Override - public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { - mDelegate.onAttachedToRecyclerView(recyclerView); - } - - @Override - public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { - mDelegate.onDetachedFromRecyclerView(recyclerView); - } - } - - private static class HeaderViewHolder extends ViewHolder { - private HeaderViewHolder(@NonNull View itemView) { - super(itemView); - } - } - - private static class HeaderSpanSizeLookup extends SpanSizeLookup { - private final SpanSizeLookup mDelegate; - private final int mSpanCount; - - private HeaderSpanSizeLookup(@NonNull SpanSizeLookup delegate, int spanCount) { - mDelegate = delegate; - mSpanCount = spanCount; - setSpanIndexCacheEnabled(mDelegate.isSpanIndexCacheEnabled()); - } - - @Override - public int getSpanSize(int position) { - if (isHeader(position)) { - return mSpanCount; - } - return mDelegate.getSpanSize(fromPosition(position)); - } - - @Override - public int getSpanIndex(int position, int spanCount) { - if (isHeader(position)) { - return 0; - } - return mDelegate.getSpanIndex(fromPosition(position), spanCount); - } - - public int getSpanGroupIndex(int adapterPosition, int spanCount) { - if (isHeader(adapterPosition)) { - return 0; - } - return mDelegate.getSpanIndex(fromPosition(adapterPosition), spanCount) - + (hasHeader() ? 1 : 0); - } - } - - private static boolean hasHeader() { - return true; - } - - private static boolean isHeader(int position) { - return hasHeader() && position == 0; - } - - private static int getCount(int count) { - if (hasHeader()) { - return count + 1; - } - return count; - } - - private static int toPosition(int position) { - if (hasHeader()) { - return position + 1; - } - return position; - } - - private static int fromPosition(int position) { - if (hasHeader()) { - return position - 1; - } - return position; - } -} |