Merge "copy new native libs if they are loaded in another classloader" into androidx-master-dev
diff --git a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
index 274eed9..5f28cd8 100644
--- a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
@@ -104,6 +104,7 @@
"-Xep:FutureReturnValueIgnored:ERROR",
"-Xep:HidingField:ERROR",
"-Xep:AutoValueFinalMethods:ERROR",
+ "-Xep:LockNotBeforeTry:ERROR",
// Nullaway
"-XepIgnoreUnknownCheckNames", // https://github.com/uber/NullAway/issues/25
diff --git a/room/runtime/src/main/java/androidx/room/InvalidationTracker.java b/room/runtime/src/main/java/androidx/room/InvalidationTracker.java
index f35b7f9..c7ea442 100644
--- a/room/runtime/src/main/java/androidx/room/InvalidationTracker.java
+++ b/room/runtime/src/main/java/androidx/room/InvalidationTracker.java
@@ -361,8 +361,8 @@
public void run() {
final Lock closeLock = mDatabase.getCloseLock();
Set<Integer> invalidatedTableIds = null;
+ closeLock.lock();
try {
- closeLock.lock();
if (!ensureInitialization()) {
return;
diff --git a/room/runtime/src/main/java/androidx/room/RoomDatabase.java b/room/runtime/src/main/java/androidx/room/RoomDatabase.java
index b038c89..8595be4 100644
--- a/room/runtime/src/main/java/androidx/room/RoomDatabase.java
+++ b/room/runtime/src/main/java/androidx/room/RoomDatabase.java
@@ -241,8 +241,8 @@
public void close() {
if (isOpen()) {
final Lock closeLock = mCloseLock.writeLock();
+ closeLock.lock();
try {
- closeLock.lock();
mInvalidationTracker.stopMultiInstanceInvalidation();
mOpenHelper.close();
} finally {
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/ContentUriKeyProvider.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/ContentUriKeyProvider.java
deleted file mode 100644
index cc83ca1..0000000
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/ContentUriKeyProvider.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2017 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.example.android.supportv7.widget.selection.fancy;
-
-import android.net.Uri;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.selection.ItemKeyProvider;
-
-import java.util.HashMap;
-import java.util.Map;
-
-class ContentUriKeyProvider extends ItemKeyProvider<Uri> {
-
- private final Uri[] mUris;
- private final Map<Uri, Integer> mPositions;
-
- ContentUriKeyProvider(String authority, String[] values) {
- // Advise the world we can supply ids/position for entire copus
- // at any time.
- super(SCOPE_MAPPED);
-
- mUris = new Uri[values.length];
- mPositions = new HashMap<>();
-
- for (int i = 0; i < values.length; i++) {
- mUris[i] = new Uri.Builder()
- .scheme("content")
- .encodedAuthority(authority)
- .appendPath(values[i])
- .build();
- mPositions.put(mUris[i], i);
- }
- }
-
- @Override
- public @Nullable Uri getKey(int position) {
- return mUris[position];
- }
-
- @Override
- public int getPosition(Uri key) {
- return mPositions.get(key);
- }
-}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyDetailsLookup.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyDetailsLookup.java
index 92ed977..c2d57f0 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyDetailsLookup.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyDetailsLookup.java
@@ -41,9 +41,11 @@
@Nullable View view = mRecView.findChildViewUnder(e.getX(), e.getY());
if (view != null) {
ViewHolder holder = mRecView.getChildViewHolder(view);
- if (holder instanceof FancyHolder) {
- return ((FancyHolder) holder).getItemDetails();
+ if (holder instanceof FancyItemHolder) {
+ return ((FancyItemHolder) holder).getItemDetails();
}
+ // FancyHeaderHolder doesn't hold a selectable item,
+ // so it doesn't support getItemDetails.
}
return null;
}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyHeaderHolder.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyHeaderHolder.java
new file mode 100644
index 0000000..4ed2d1f
--- /dev/null
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyHeaderHolder.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 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.example.android.supportv7.widget.selection.fancy;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.example.android.supportv7.R;
+
+final class FancyHeaderHolder extends FancyHolder {
+
+ private static final String HEADER_TAG = "I'm a header";
+ public final TextView mLabel;
+
+ FancyHeaderHolder(LinearLayout layout) {
+ super(layout);
+ layout.setTag(HEADER_TAG);
+ mLabel = layout.findViewById(R.id.label);
+ }
+
+ void update(String label) {
+ mLabel.setText(label.toUpperCase() + label + label + "...");
+ }
+
+ @Override
+ public String toString() {
+ return "Header{name:" + mLabel.getText() + "}";
+ }
+
+ static boolean isHeader(View view) {
+ return HEADER_TAG.equals(view.getTag());
+ }
+}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyHolder.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyHolder.java
index 6637d88..6fbc206 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyHolder.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyHolder.java
@@ -13,111 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.example.android.supportv7.widget.selection.fancy;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.view.MotionEvent;
import android.widget.LinearLayout;
-import android.widget.TextView;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
import androidx.recyclerview.widget.RecyclerView;
-import com.example.android.supportv7.R;
-
-final class FancyHolder extends RecyclerView.ViewHolder {
-
- private final LinearLayout mContainer;
- public final TextView mSelector;
- public final TextView mLabel;
- private final ItemDetails<Uri> mDetails;
-
- private @Nullable Uri mKey;
-
+abstract class FancyHolder extends RecyclerView.ViewHolder {
FancyHolder(LinearLayout layout) {
super(layout);
- mContainer = layout.findViewById(R.id.container);
- mSelector = layout.findViewById(R.id.selector);
- mLabel = layout.findViewById(R.id.label);
- mDetails = new ItemDetails<Uri>() {
- @Override
- public int getPosition() {
- return FancyHolder.this.getAdapterPosition();
- }
-
- @Override
- public Uri getSelectionKey() {
- return FancyHolder.this.mKey;
- }
-
- @Override
- public boolean inDragRegion(@NonNull MotionEvent e) {
- return FancyHolder.this.inDragRegion(e);
- }
-
- @Override
- public boolean inSelectionHotspot(@NonNull MotionEvent e) {
- return FancyHolder.this.inSelectRegion(e);
- }
-
- @NonNull
- @Override
- public String toString() {
- return FancyHolder.this.toString();
- }
- };
- }
-
- void update(Uri key, String label, boolean selected) {
- mKey = key;
- mLabel.setText(label);
- setSelected(selected);
- }
-
- private void setSelected(boolean selected) {
- mContainer.setActivated(selected);
- mSelector.setActivated(selected);
- }
-
- boolean inDragRegion(MotionEvent event) {
- // If itemView is activated = selected, then whole region is interactive
- if (itemView.isActivated()) {
- return true;
- }
-
- // Do everything in global coordinates - it makes things simpler.
- int[] coords = new int[2];
- mSelector.getLocationOnScreen(coords);
-
- Rect textBounds = new Rect();
- mLabel.getPaint().getTextBounds(
- mLabel.getText().toString(), 0, mLabel.getText().length(), textBounds);
-
- Rect rect = new Rect(
- coords[0],
- coords[1],
- coords[0] + mSelector.getWidth() + textBounds.width(),
- coords[1] + Math.max(mSelector.getHeight(), textBounds.height()));
-
- // If the tap occurred inside icon or the text, these are interactive spots.
- return rect.contains((int) event.getRawX(), (int) event.getRawY());
- }
-
- boolean inSelectRegion(MotionEvent e) {
- Rect iconRect = new Rect();
- mSelector.getGlobalVisibleRect(iconRect);
- return iconRect.contains((int) e.getRawX(), (int) e.getRawY());
- }
-
- ItemDetails<Uri> getItemDetails() {
- return mDetails;
- }
-
- @Override
- public String toString() {
- return "Item{name:" + mLabel.getText() + ", url:" + mKey + "}";
}
}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyItemHolder.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyItemHolder.java
new file mode 100644
index 0000000..c7761b2
--- /dev/null
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancyItemHolder.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2017 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.example.android.supportv7.widget.selection.fancy;
+
+import android.graphics.Rect;
+import android.net.Uri;
+import android.view.MotionEvent;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+
+import com.example.android.supportv7.R;
+
+final class FancyItemHolder extends FancyHolder {
+
+ private final LinearLayout mContainer;
+ private final TextView mSelector;
+ private final TextView mLabel;
+ private final ItemDetails<Uri> mDetails;
+
+ private @Nullable Uri mKey;
+
+ FancyItemHolder(LinearLayout layout) {
+ super(layout);
+
+ mContainer = layout.findViewById(R.id.container);
+ mSelector = layout.findViewById(R.id.selector);
+ mLabel = layout.findViewById(R.id.label);
+ mDetails = new ItemDetails<Uri>() {
+ @Override
+ public int getPosition() {
+ return FancyItemHolder.this.getAdapterPosition();
+ }
+
+ @Override
+ public Uri getSelectionKey() {
+ return FancyItemHolder.this.mKey;
+ }
+
+ @Override
+ public boolean inDragRegion(@NonNull MotionEvent e) {
+ return FancyItemHolder.this.inDragRegion(e);
+ }
+
+ @Override
+ public boolean inSelectionHotspot(@NonNull MotionEvent e) {
+ return FancyItemHolder.this.inSelectRegion(e);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return FancyItemHolder.this.toString();
+ }
+ };
+ }
+
+ void update(Uri key, String label, boolean selected) {
+ mKey = key;
+ mLabel.setText(label);
+ setSelected(selected);
+ }
+
+ private void setSelected(boolean selected) {
+ mContainer.setActivated(selected);
+ mSelector.setActivated(selected);
+ }
+
+ boolean inDragRegion(MotionEvent event) {
+ // If itemView is activated = selected, then whole region is interactive
+ if (itemView.isActivated()) {
+ return true;
+ }
+
+ // Do everything in global coordinates - it makes things simpler.
+ int[] coords = new int[2];
+ mSelector.getLocationOnScreen(coords);
+
+ Rect textBounds = new Rect();
+ mLabel.getPaint().getTextBounds(
+ mLabel.getText().toString(), 0, mLabel.getText().length(), textBounds);
+
+ Rect rect = new Rect(
+ coords[0],
+ coords[1],
+ coords[0] + mSelector.getWidth() + textBounds.width(),
+ coords[1] + Math.max(mSelector.getHeight(), textBounds.height()));
+
+ // If the tap occurred inside icon or the text, these are interactive spots.
+ return rect.contains((int) event.getRawX(), (int) event.getRawY());
+ }
+
+ boolean inSelectRegion(MotionEvent e) {
+ Rect iconRect = new Rect();
+ mSelector.getGlobalVisibleRect(iconRect);
+ return iconRect.contains((int) e.getRawX(), (int) e.getRawY());
+ }
+
+ ItemDetails<Uri> getItemDetails() {
+ return mDetails;
+ }
+
+ @Override
+ public String toString() {
+ return "Item{name:" + mLabel.getText() + ", url:" + mKey + "}";
+ }
+}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoActivity.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoActivity.java
index c54368b..38e0046 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoActivity.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoActivity.java
@@ -58,6 +58,7 @@
private GridLayoutManager mLayout;
private int mColumnCount = 1; // This will get updated when layout changes.
+ private boolean mIterceptListenerEnabled = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -66,6 +67,32 @@
setContentView(R.layout.selection_demo_layout);
mRecView = (RecyclerView) findViewById(R.id.list);
+ // If you want to provided special handling of clicks on items
+ // in RecyclerView (respond to a play button, or show a menu
+ // when a three-dot menu is clicked) you can't just add an OnClickListener
+ // to the View. This is because Selection lib installs an
+ // OnItemTouchListener w/ RecyclerView, and that listener eats
+ // up many of the touch/mouse events RecyclerView sends its way.
+ // To work around this install your own OnItemTouchListener *before*
+ // you build your SelectionTracker instance. That'll give your listener
+ // a chance to intercept events before Selection lib gobbles them up.
+ mRecView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
+ @Override
+ public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
+ return mIterceptListenerEnabled
+ && FancyHeaderHolder.isHeader(rv.findChildViewUnder(e.getX(), e.getY()));
+ }
+
+ @Override
+ public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
+ toast(FancySelectionDemoActivity.this, "Clicked on a header!");
+ }
+
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+ }
+ });
+
mLayout = new GridLayoutManager(this, mColumnCount);
mRecView.setLayoutManager(mLayout);
mAdapter = new FancySelectionDemoAdapter(this);
@@ -137,27 +164,19 @@
@CallSuper
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- menu.findItem(R.id.option_menu_add_column).setEnabled(mColumnCount <= 3);
- menu.findItem(R.id.option_menu_remove_column).setEnabled(mColumnCount > 1);
+ menu.findItem(R.id.option_menu_enable_listener)
+ .setEnabled(!mIterceptListenerEnabled);
+ menu.findItem(R.id.option_menu_disable_listener)
+ .setEnabled(mIterceptListenerEnabled);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.option_menu_add_column:
- // TODO: Add columns
- mLayout.setSpanCount(++mColumnCount);
- return true;
- case R.id.option_menu_remove_column:
- mLayout.setSpanCount(--mColumnCount);
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ mIterceptListenerEnabled = !mIterceptListenerEnabled;
+ return true;
}
-
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
@@ -302,4 +321,4 @@
return true;
}
}
-}
\ No newline at end of file
+}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoAdapter.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoAdapter.java
index 5d2f5cb..804e7ec 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoAdapter.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/fancy/FancySelectionDemoAdapter.java
@@ -23,8 +23,9 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.LinearLayout;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.recyclerview.selection.ItemKeyProvider;
import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.widget.RecyclerView;
@@ -32,29 +33,34 @@
import com.example.android.supportv7.Cheeses;
import com.example.android.supportv7.R;
+import java.util.HashMap;
+import java.util.Map;
+
final class FancySelectionDemoAdapter extends RecyclerView.Adapter<FancyHolder> {
- private final ContentUriKeyProvider mKeyProvider;
+ public static final int TYPE_HEADER = 1;
+ public static final int TYPE_ITEM = 2;
+
+ private final KeyProvider mKeyProvider;
private final Context mContext;
- // This should be replaced at "bind" time with a real test that
- // asks SelectionTracker.
- private SelectionTest mSelTest;
+ // This default implementation must be replaced
+ // with a real implementation in #bindSelectionHelper.
+ private SelectionTest mSelTest = new SelectionTest() {
+ @Override
+ public boolean isSelected(Uri id) {
+ throw new IllegalStateException(
+ "Adapter must be initialized with SelectionTracker");
+ }
+ };
FancySelectionDemoAdapter(Context context) {
mContext = context;
- mKeyProvider = new ContentUriKeyProvider("cheeses", Cheeses.sCheeseStrings);
- mSelTest = new SelectionTest() {
- @Override
- public boolean isSelected(Uri id) {
- throw new IllegalStateException(
- "Adapter must be initialized with SelectionTracker");
- }
- };
+ mKeyProvider = new KeyProvider("cheeses", Cheeses.sCheeseStrings);
// In the fancy edition of selection support we supply access to stable
// ids using content URI. Since we can map between position and selection key
- // at will we get fancy dependent functionality like band selection and range support.
+ // at-will we get band selection and range support.
setHasStableIds(false);
}
@@ -63,12 +69,12 @@
}
// Glue together SelectionTracker and the adapter.
- public void bindSelectionHelper(final SelectionTracker<Uri> selectionTracker) {
- checkArgument(selectionTracker != null);
+ public void bindSelectionHelper(final SelectionTracker<Uri> tracker) {
+ checkArgument(tracker != null);
mSelTest = new SelectionTest() {
@Override
public boolean isSelected(Uri id) {
- return selectionTracker.isSelected(id);
+ return tracker.isSelected(id);
}
};
}
@@ -83,7 +89,7 @@
@Override
public int getItemCount() {
- return Cheeses.sCheeseStrings.length;
+ return mKeyProvider.getCount();
}
@Override
@@ -92,15 +98,40 @@
}
@Override
- public void onBindViewHolder(FancyHolder holder, int position) {
- Uri uri = mKeyProvider.getKey(position);
- holder.update(uri, uri.getLastPathSegment(), mSelTest.isSelected(uri));
+ public void onBindViewHolder(@NonNull FancyHolder holder, int position) {
+ if (holder instanceof FancyHeaderHolder) {
+ Uri uri = mKeyProvider.getKey(position);
+ ((FancyHeaderHolder) holder).update(uri.getPathSegments().get(0));
+ } else if (holder instanceof FancyItemHolder) {
+ Uri uri = mKeyProvider.getKey(position);
+ ((FancyItemHolder) holder).update(uri, uri.getPathSegments().get(1),
+ mSelTest.isSelected(uri));
+ }
}
@Override
- public FancyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- LinearLayout layout = inflateLayout(mContext, parent, R.layout.selection_demo_list_item);
- return new FancyHolder(layout);
+ public int getItemViewType(int position) {
+ Uri key = mKeyProvider.getKey(position);
+ if (key.getPathSegments().size() == 1) {
+ return TYPE_HEADER;
+ } else if (key.getPathSegments().size() == 2) {
+ return TYPE_ITEM;
+ }
+
+ throw new RuntimeException("Unknown view type a position " + position);
+ }
+
+ @Override
+ public FancyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case TYPE_HEADER:
+ return new FancyHeaderHolder(
+ inflateLayout(mContext, parent, R.layout.selection_demo_list_header));
+ case TYPE_ITEM:
+ return new FancyItemHolder(
+ inflateLayout(mContext, parent, R.layout.selection_demo_list_item));
+ }
+ throw new RuntimeException("Unsupported view type" + viewType);
}
@SuppressWarnings("TypeParameterUnusedInFormals") // Convenience to avoid clumsy cast.
@@ -113,4 +144,62 @@
private interface SelectionTest {
boolean isSelected(Uri id);
}
+
+ private static final class KeyProvider extends ItemKeyProvider<Uri> {
+
+ private final Uri[] mUris;
+ private final Map<Uri, Integer> mPositions;
+
+ KeyProvider(String authority, String[] values) {
+ // Advise the world we can supply ids/position for entire copus
+ // at any time.
+ super(SCOPE_MAPPED);
+
+ // For the convenience of this demo, we simply trust, based on
+ // past understanding that Cheeses has at least one element
+ // starting with each letter of the English alphabet :)
+ mUris = new Uri[Cheeses.sCheeseStrings.length + 26];
+ mPositions = new HashMap<>();
+
+ char section = '-'; // anything value other than 'a' will do the trick here.
+ int headerOffset = 0;
+
+ for (int i = 0; i < Cheeses.sCheeseStrings.length; i++) {
+ char leadingChar = Cheeses.sCheeseStrings[i].toLowerCase().charAt(0);
+ // When we find a new leading character insert an artificial
+ // cheese header
+ if (leadingChar != section) {
+ section = leadingChar;
+ mUris[i + headerOffset] = new Uri.Builder()
+ .scheme("content")
+ .encodedAuthority(authority)
+ .appendPath(Character.toString(section))
+ .build();
+ mPositions.put(mUris[i + headerOffset], i + headerOffset);
+ headerOffset++;
+ }
+ mUris[i + headerOffset] = new Uri.Builder()
+ .scheme("content")
+ .encodedAuthority(authority)
+ .appendPath(Character.toString(section))
+ .appendPath(Cheeses.sCheeseStrings[i])
+ .build();
+ mPositions.put(mUris[i + headerOffset], i + headerOffset);
+ }
+ }
+
+ @Override
+ public @Nullable Uri getKey(int position) {
+ return mUris[position];
+ }
+
+ @Override
+ public int getPosition(@NonNull Uri key) {
+ return mPositions.get(key);
+ }
+
+ int getCount() {
+ return mUris.length;
+ }
+ }
}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/simple/SimpleSelectionDemoActivity.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/simple/SimpleSelectionDemoActivity.java
index fafddc4..63fda61 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/simple/SimpleSelectionDemoActivity.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/selection/simple/SimpleSelectionDemoActivity.java
@@ -19,12 +19,9 @@
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.MotionEvent;
import android.widget.Toast;
-import androidx.annotation.CallSuper;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
import androidx.recyclerview.selection.ItemKeyProvider;
@@ -128,39 +125,6 @@
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- boolean showMenu = super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.selection_demo_actions, menu);
- return showMenu;
- }
-
- @Override
- @CallSuper
- public boolean onPrepareOptionsMenu(Menu menu) {
- super.onPrepareOptionsMenu(menu);
- menu.findItem(R.id.option_menu_add_column).setEnabled(mColumnCount <= 3);
- menu.findItem(R.id.option_menu_remove_column).setEnabled(mColumnCount > 1);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.option_menu_add_column:
- // TODO: Add columns
- mLayout.setSpanCount(++mColumnCount);
- return true;
-
- case R.id.option_menu_remove_column:
- mLayout.setSpanCount(--mColumnCount);
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- @Override
public void onBackPressed() {
if (mSelectionTracker.clearSelection()) {
return;
diff --git a/samples/Support7Demos/src/main/res/color/selection_demo_item.xml b/samples/Support7Demos/src/main/res/color/selection_demo_item.xml
new file mode 100644
index 0000000..ea11b42
--- /dev/null
+++ b/samples/Support7Demos/src/main/res/color/selection_demo_item.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2019 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_activated="true"
+ android:color="?android:attr/colorForegroundInverse"
+ />
+ <item
+ android:state_activated="false"
+ android:color="?android:attr/colorForegroundInverse"
+ android:alpha=".3"
+ />
+</selector>
diff --git a/samples/Support7Demos/src/main/res/color/selection_demo_item_selector.xml b/samples/Support7Demos/src/main/res/color/selection_demo_item_selector.xml
index bd87b4c..c800127 100644
--- a/samples/Support7Demos/src/main/res/color/selection_demo_item_selector.xml
+++ b/samples/Support7Demos/src/main/res/color/selection_demo_item_selector.xml
@@ -16,12 +16,13 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:state_activated="true"
- android:color="?android:attr/colorForeground"
- />
- <item
android:state_activated="false"
android:color="?android:attr/colorForeground"
android:alpha=".3"
/>
+ <item
+ android:state_activated="true"
+ android:color="#FFFF0000"
+ android:alpha=".4"
+ />
</selector>
diff --git a/samples/Support7Demos/src/main/res/drawable/selection_demo_item.xml b/samples/Support7Demos/src/main/res/drawable/selection_demo_item.xml
new file mode 100644
index 0000000..52d11c5
--- /dev/null
+++ b/samples/Support7Demos/src/main/res/drawable/selection_demo_item.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_activated="true">
+ <color android:color="#22FF0000"></color>
+ </item>
+</selector>
diff --git a/samples/Support7Demos/src/main/res/drawable/selection_demo_item_background.xml b/samples/Support7Demos/src/main/res/drawable/selection_demo_item_background.xml
index e4dbd5f..e15b281 100644
--- a/samples/Support7Demos/src/main/res/drawable/selection_demo_item_background.xml
+++ b/samples/Support7Demos/src/main/res/drawable/selection_demo_item_background.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
- <color android:color="#220000FF"></color>
+ <color android:color="#2200FF00"></color>
</item>
</selector>
diff --git a/samples/Support7Demos/src/main/res/layout/selection_demo_list_header.xml b/samples/Support7Demos/src/main/res/layout/selection_demo_list_header.xml
new file mode 100644
index 0000000..13e127a
--- /dev/null
+++ b/samples/Support7Demos/src/main/res/layout/selection_demo_list_header.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:paddingStart="10dp"
+ android:paddingEnd="10dp"
+ android:paddingTop="5dp"
+ android:paddingBottom="5dp"
+ android:layout_height="50dp">
+ <LinearLayout
+ android:id="@+id/container"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:background="@drawable/selection_demo_item_background">
+ <TextView
+ android:id="@+id/label"
+ android:textSize="30sp"
+ android:textStyle="bold"
+ android:gravity="center_vertical"
+ android:paddingStart="10dp"
+ android:paddingEnd="10dp"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+ </TextView>
+ </LinearLayout>
+</LinearLayout>
diff --git a/samples/Support7Demos/src/main/res/layout/selection_demo_list_item.xml b/samples/Support7Demos/src/main/res/layout/selection_demo_list_item.xml
index 0d4b718..fb5e8e9 100644
--- a/samples/Support7Demos/src/main/res/layout/selection_demo_list_item.xml
+++ b/samples/Support7Demos/src/main/res/layout/selection_demo_list_item.xml
@@ -27,11 +27,10 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
- android:background="@drawable/selection_demo_item_background">
+ android:background="#FFFFFFFF">
<TextView
android:id="@+id/selector"
android:textSize="20sp"
- android:textStyle="bold"
android:gravity="center"
android:layout_height="match_parent"
android:layout_width="40dp"
@@ -47,7 +46,8 @@
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_height="match_parent"
- android:layout_width="match_parent">
+ android:layout_width="wrap_content"
+ android:background="@drawable/selection_demo_item">
</TextView>
</LinearLayout>
</LinearLayout>
diff --git a/samples/Support7Demos/src/main/res/menu/selection_demo_actions.xml b/samples/Support7Demos/src/main/res/menu/selection_demo_actions.xml
index 484d8b6..ce76ddc3 100644
--- a/samples/Support7Demos/src/main/res/menu/selection_demo_actions.xml
+++ b/samples/Support7Demos/src/main/res/menu/selection_demo_actions.xml
@@ -16,9 +16,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:id="@+id/option_menu_add_column"
- android:title="Add column" />
+ android:id="@+id/option_menu_enable_listener"
+ android:title="Enable OnItemTouchListener" />
<item
- android:id="@+id/option_menu_remove_column"
- android:title="Remove column" />
+ android:id="@+id/option_menu_disable_listener"
+ android:title="Disable OnItemTouchListener" />
</menu>
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
index 0945a5d..17c5a12 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
@@ -66,7 +66,7 @@
@SdkSuppress(minSdkVersion = 16)
fun test_onPerformPageAction() {
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(6)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(6)))
val initialPage = viewPager.currentItem
assertBasicState(initialPage)
@@ -93,7 +93,7 @@
@Test
fun test_collectionInfo() {
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(6)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(6)))
val initialPage = viewPager.currentItem
assertBasicState(initialPage)
@@ -124,7 +124,7 @@
@Test
fun test_onOrientationChange() {
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(2)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(2)))
val initialPage = viewPager.currentItem
assertBasicState(initialPage)
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
index 3815b5a..847c44c 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
@@ -102,7 +102,7 @@
test = setUpTest(config.orientation)
activityTestRule.runOnUiThread { test.viewPager.offscreenPageLimit = 1 }
dataSet = stringSequence(pageCount).toMutableList()
- test.setAdapterSync(config.adapterProvider(dataSet))
+ test.setAdapterSync(config.adapterProvider.provider(dataSet))
}
@Test
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt
index f2333f9..a61995a 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt
@@ -49,7 +49,7 @@
@Test
fun test_setAdapter() {
val recorder = test.viewPager.addNewRecordingCallback()
- test.setAdapterSync(viewAdapterProvider(stringSequence(pageCount)))
+ test.setAdapterSync(viewAdapterProvider.provider(stringSequence(pageCount)))
test.assertBasicState(0)
test.viewPager.setCurrentItemSync(1, false, 2, SECONDS)
test.assertBasicState(1)
@@ -195,7 +195,7 @@
private fun setUpAdapterSync(pageCount: Int, initialPage: Int? = null) {
dataSet = stringSequence(pageCount).toMutableList()
- test.setAdapterSync(viewAdapterProvider(dataSet))
+ test.setAdapterSync(viewAdapterProvider.provider(dataSet))
if (initialPage != null) {
test.viewPager.setCurrentItemSync(initialPage, false, 2, SECONDS)
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
index d724b7f..688625ca 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -599,9 +599,14 @@
typealias AdapterProvider = (TestActivity) -> RecyclerView.Adapter<out RecyclerView.ViewHolder>
-typealias AdapterProviderForItems = (items: List<String>) -> AdapterProvider
+data class AdapterProviderForItems(
+ val name: String,
+ val provider: (items: List<String>) -> AdapterProvider
+) {
+ override fun toString(): String = name
+}
-val fragmentAdapterProvider: AdapterProviderForItems = { items ->
+val fragmentAdapterProvider = AdapterProviderForItems("fragmentAdapterProvider") { items ->
{ activity: TestActivity ->
FragmentAdapter(
activity.supportFragmentManager,
@@ -616,35 +621,38 @@
* [FragmentStateAdapter.getItemId] and [FragmentStateAdapter.containsItem].
* Not suitable for testing [RecyclerView.Adapter.notifyDataSetChanged].
*/
-val fragmentAdapterProviderCustomIds: AdapterProviderForItems = { items ->
- { activity ->
- fragmentAdapterProvider(items)(activity).also {
- // more than position can represent, so a good test if ids are used consistently
- val offset = 3L * Int.MAX_VALUE
- val adapter = it as FragmentAdapter
- adapter.positionToItemId = { position -> position + offset }
- adapter.itemIdToContains = { itemId ->
- val position = itemId - offset
- position in (0 until adapter.itemCount)
+val fragmentAdapterProviderCustomIds =
+ AdapterProviderForItems("fragmentAdapterProviderCustomIds") { items ->
+ { activity ->
+ fragmentAdapterProvider.provider(items)(activity).also {
+ // more than position can represent, so a good test if ids are used consistently
+ val offset = 3L * Int.MAX_VALUE
+ val adapter = it as FragmentAdapter
+ adapter.positionToItemId = { position -> position + offset }
+ adapter.itemIdToContains = { itemId ->
+ val position = itemId - offset
+ position in (0 until adapter.itemCount)
+ }
}
}
}
-}
/**
* Same as [fragmentAdapterProvider] but with a custom implementation of
* [FragmentStateAdapter.getItemId] and [FragmentStateAdapter.containsItem].
* Suitable for testing [RecyclerView.Adapter.notifyDataSetChanged].
*/
-val fragmentAdapterProviderValueId: AdapterProviderForItems = { items ->
- { activity ->
- fragmentAdapterProvider(items)(activity).also {
- val adapter = it as FragmentAdapter
- adapter.positionToItemId = { position -> items[position].getId() }
- adapter.itemIdToContains = { itemId -> items.any { item -> item.getId() == itemId } }
+val fragmentAdapterProviderValueId =
+ AdapterProviderForItems("fragmentAdapterProviderValueId") { items ->
+ { activity ->
+ fragmentAdapterProvider.provider(items)(activity).also {
+ val adapter = it as FragmentAdapter
+ adapter.positionToItemId = { position -> items[position].getId() }
+ adapter.itemIdToContains =
+ { itemId -> items.any { item -> item.getId() == itemId } }
+ }
}
}
-}
/** Extracts the sole number from a [String] and converts it to a [Long] */
private fun (String).getId(): Long {
@@ -660,9 +668,9 @@
* [RecyclerView.Adapter.getItemId].
* Suitable for testing [RecyclerView.Adapter.notifyDataSetChanged].mu
*/
-val viewAdapterProviderValueId: AdapterProviderForItems = { items ->
+val viewAdapterProviderValueId = AdapterProviderForItems("viewAdapterProviderValueId") { items ->
{ activity ->
- viewAdapterProvider(items)(activity).also {
+ viewAdapterProvider.provider(items)(activity).also {
val adapter = it as ViewAdapter
adapter.positionToItemId = { position -> items[position].getId() }
adapter.setHasStableIds(true)
@@ -670,7 +678,8 @@
}
}
-val viewAdapterProvider: AdapterProviderForItems = { items -> { ViewAdapter(items) } }
+val viewAdapterProvider =
+ AdapterProviderForItems("viewAdapterProvider") { items -> { ViewAdapter(items) } }
fun stringSequence(pageCount: Int) = (0 until pageCount).map { it.toString() }
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
index e268559..045de41 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
@@ -39,19 +39,19 @@
// given
setUpTest(ORIENTATION_HORIZONTAL).apply {
// when no pages
- setAdapterSync(viewAdapterProvider(stringSequence(0)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(0)))
// then can't scroll
assertScrollNone()
// when 1 page
- setAdapterSync(viewAdapterProvider(stringSequence(1)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(1)))
// then can't scroll
assertScrollNone()
// when 2 pages
- setAdapterSync(viewAdapterProvider(stringSequence(2)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(2)))
// then can scroll right
assertScrollRight()
@@ -84,19 +84,19 @@
localeUtil.setLocale(LocaleTestUtils.RTL_LANGUAGE)
setUpTest(ORIENTATION_HORIZONTAL).apply {
// when no pages
- setAdapterSync(viewAdapterProvider(stringSequence(0)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(0)))
// then can't scroll
assertScrollNone()
// when 1 page
- setAdapterSync(viewAdapterProvider(stringSequence(1)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(1)))
// then can't scroll
assertScrollNone()
// when 2 pages
- setAdapterSync(viewAdapterProvider(stringSequence(2)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(2)))
// then can scroll left
assertScrollLeft()
@@ -126,19 +126,19 @@
// given
setUpTest(ORIENTATION_VERTICAL).apply {
// when no pages
- setAdapterSync(viewAdapterProvider(stringSequence(0)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(0)))
// then can't scroll
assertScrollNone()
// when 1 page
- setAdapterSync(viewAdapterProvider(stringSequence(1)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(1)))
// then can't scroll
assertScrollNone()
// when 2 pages
- setAdapterSync(viewAdapterProvider(stringSequence(2)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(2)))
// then can scroll down
assertScrollDown()
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt
index 7f22960..7a30f81 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ChangeDataSetWhileScrollingTest.kt
@@ -37,7 +37,7 @@
fun test_regression01() {
setUpTest(orientation).apply {
val items = listOf("49", "51").toMutableList()
- setAdapterSync(adapterProvider(items))
+ setAdapterSync(adapterProvider.provider(items))
assertBasicState(0, items[0])
viewPager.post {
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt
index fb2abd3..97443aa 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt
@@ -61,21 +61,22 @@
private lateinit var test: Context
private lateinit var adapterProvider: AdapterProvider
- private val touchConsumingViewAdapter: AdapterProviderForItems = { items ->
- {
- object : ViewAdapter(items) {
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- super.onBindViewHolder(holder, position)
- (holder.itemView as TouchConsumingTextView).consumeTouches =
+ private val touchConsumingViewAdapter =
+ AdapterProviderForItems("touchConsumingViewAdapter") { items ->
+ {
+ object : ViewAdapter(items) {
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ super.onBindViewHolder(holder, position)
+ (holder.itemView as TouchConsumingTextView).consumeTouches =
config.childViewConsumesTouches
+ }
}
}
}
- }
override fun setUp() {
super.setUp()
- adapterProvider = touchConsumingViewAdapter(stringSequence(pageCount))
+ adapterProvider = touchConsumingViewAdapter.provider(stringSequence(pageCount))
test = setUpTest(config.orientation).also {
it.viewPager.isUserInputEnabled = false
it.setAdapterSync(adapterProvider)
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt
index 0446457..5b9266c 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt
@@ -73,7 +73,7 @@
assertThat(config.distanceToTargetWhenStartDrag, greaterThan(0f))
val pageCount = max(config.startPage, config.targetPage) + 1
test = setUpTest(config.orientation)
- test.setAdapterSync(viewAdapterProvider(stringSequence(pageCount)))
+ test.setAdapterSync(viewAdapterProvider.provider(stringSequence(pageCount)))
test.viewPager.setCurrentItemSync(config.startPage, false, 2, SECONDS)
var recorder = test.viewPager.addNewRecordingCallback()
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
index eb6eb42..6ee9599 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
@@ -101,7 +101,7 @@
localeUtil.resetLocale()
localeUtil.setLocale(LocaleTestUtils.RTL_LANGUAGE)
}
- adapterProvider = viewAdapterProvider(stringSequence(pageCount))
+ adapterProvider = viewAdapterProvider.provider(stringSequence(pageCount))
test = setUpTest(config.orientation).also {
fakeDragger = PageSwiperFakeDrag(it.viewPager) { it.viewPager.pageSize }
it.viewPager.isUserInputEnabled = config.enableUserInput
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt
index 51f84084..71064fd 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt
@@ -57,7 +57,7 @@
fun test_swipeBetweenPages() {
setUpTest(orientation).apply {
val expectedValues = stringSequence(totalPages).toMutableList()
- val adapter = adapterProvider(expectedValues.toList()) // immutable defensive copy
+ val adapter = adapterProvider.provider(expectedValues.toList()) // defensive copy
setAdapterSync(adapter)
var ix = 0
@@ -86,7 +86,7 @@
fun test_setCurrentItem() {
setUpTest(orientation).apply {
val expectedValues = stringSequence(totalPages).toMutableList()
- val adapter = adapterProvider(expectedValues.toList()) // immutable defensive copy
+ val adapter = adapterProvider.provider(expectedValues.toList()) // defensive copy
setAdapterSync(adapter)
performAssertions(expectedValues, 0)
@@ -114,7 +114,7 @@
fun test_dataSetChange() {
setUpTest(orientation).apply {
val items = stringSequence(totalPages).toMutableList()
- setAdapterSync(adapterProvider(items))
+ setAdapterSync(adapterProvider.provider(items))
val adapter = viewPager.adapter!!
performAssertions(items, 0)
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt
index a46284a..ed066f6 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt
@@ -61,7 +61,7 @@
) {
// given
setUpTest(orientation).run {
- setAdapterSync(adapterProvider(stringSequence(3)))
+ setAdapterSync(adapterProvider.provider(stringSequence(3)))
// sanity checks
assertBasicState(0)
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt
index ee8c165..c0840ce 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt
@@ -49,7 +49,7 @@
fun test() {
testConfig.apply {
setUpTest(orientation).apply {
- setAdapterSync(adapterProvider(items))
+ setAdapterSync(adapterProvider.provider(items))
verifyViewPagerContent(items) // sanity check
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt
index de156e2..2920809 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt
@@ -82,7 +82,7 @@
test.viewPager.offscreenPageLimit = config.offscreenPageLimit
}
val recorder = test.viewPager.addNewRecordingCallback()
- test.setAdapterSync(config.adapterProvider(stringSequence(pageCount)))
+ test.setAdapterSync(config.adapterProvider.provider(stringSequence(pageCount)))
// Do not perform self check (which checks number of shown + cached fragments) in
// this test, as that check is not valid in the presence of offscreen page limit
test.assertBasicState(firstPage, performSelfCheck = false)
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
index 666bbb0..82f3535 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
@@ -133,12 +133,12 @@
}
private val adapterProvider: AdapterProviderForItems get() {
- return if (config.itemMarginPx > 0) {
- { items -> { MarginViewAdapter(config.itemMarginPx, items) } }
- } else {
- { items -> { ViewAdapter(items) } }
+ return AdapterProviderForItems("adapterProvider", if (config.itemMarginPx > 0) {
+ { items -> { MarginViewAdapter(config.itemMarginPx, items) } }
+ } else {
+ { items -> { ViewAdapter(items) } }
+ })
}
- }
class MarginViewAdapter(private val margin: Int, items: List<String>) : ViewAdapter(items) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@@ -186,7 +186,7 @@
@Test
fun test_pageSize() {
- test.setAdapterSync(adapterProvider(stringSequence(1)))
+ test.setAdapterSync(adapterProvider.provider(stringSequence(1)))
val f = if (viewPager.isHorizontal) fLeft + fRight else fTop + fBottom
@@ -232,7 +232,7 @@
*/
@Test
fun test_swipeBetweenPages() {
- test.setAdapterSync(adapterProvider(stringSequence(2)))
+ test.setAdapterSync(adapterProvider.provider(stringSequence(2)))
listOf(1, 0).forEach { targetPage ->
// given
val initialPage = viewPager.currentItem
@@ -292,7 +292,7 @@
val totalPages = 2
val edgePages = setOf(0, totalPages - 1)
- test.setAdapterSync(adapterProvider(stringSequence(totalPages)))
+ test.setAdapterSync(adapterProvider.provider(stringSequence(totalPages)))
listOf(0, 1, 1).forEach { targetPage ->
// given
val initialPage = viewPager.currentItem
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
index cc4bb92..fe9b258 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
@@ -109,7 +109,7 @@
@Test
fun test_swipeBetweenPages() {
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(4)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(4)))
listOf(1, 2, 3, 2, 1, 0).forEach { targetPage ->
// given
val initialPage = viewPager.currentItem
@@ -172,7 +172,7 @@
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(totalPages)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(totalPages)))
listOf(0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1, 0, 0, 0).forEach { targetPage ->
// given
val initialPage = viewPager.currentItem
@@ -235,7 +235,7 @@
fun test_peekOnAdjacentPage_next() {
// given
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(3)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(3)))
val callback = viewPager.addNewRecordingCallback()
val latch = viewPager.addWaitForScrolledLatch(0)
@@ -294,7 +294,7 @@
fun test_peekOnAdjacentPage_previous() {
// given
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(3)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(3)))
viewPager.setCurrentItemSync(2, false, 1, SECONDS)
@@ -371,7 +371,7 @@
fun test_selectItemProgrammatically_smoothScroll() {
// given
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(1000)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(1000)))
// when
listOf(6, 5, 6, 3, 10, 0, 0, 999, 999, 0).forEach { targetPage ->
@@ -412,7 +412,7 @@
fun test_multiplePageChanges() {
// given
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(10)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(10)))
val targetPages = listOf(4, 9)
val callback = viewPager.addNewRecordingCallback()
val latch = viewPager.addWaitForScrolledLatch(targetPages.last(), true)
@@ -462,7 +462,7 @@
fun test_noSmoothScroll_after_smoothScroll() {
// given
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(6)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(6)))
val targetPage = 4
val marker = 1
val callback = viewPager.addNewRecordingCallback()
@@ -580,7 +580,7 @@
// given
assertThat(targetPage, greaterThanOrEqualTo(4))
setUpTest(config.orientation).apply {
- val adapterProvider = viewAdapterProvider(stringSequence(5))
+ val adapterProvider = viewAdapterProvider.provider(stringSequence(5))
setAdapterSync(adapterProvider)
val marker = 1
val callback = viewPager.addNewRecordingCallback()
@@ -640,7 +640,7 @@
fun test_selectItemProgrammatically_noSmoothScroll() {
// given
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(3)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(3)))
// when
listOf(2, 2, 0, 0, 1, 2, 1, 0).forEach { targetPage ->
@@ -672,7 +672,7 @@
fun test_swipeReleaseSwipeBack() {
// given
val test = setUpTest(config.orientation)
- test.setAdapterSync(viewAdapterProvider(stringSequence(3)))
+ test.setAdapterSync(viewAdapterProvider.provider(stringSequence(3)))
val currentPage = test.viewPager.currentItem
val halfPage = test.viewPager.pageSize / 2f
val pageSwiper = PageSwiperManual(test.viewPager)
@@ -746,7 +746,7 @@
private fun test_selectItemProgrammatically_noCallback(smoothScroll: Boolean) {
// given
setUpTest(config.orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(3)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(3)))
// when
listOf(2, 2, 0, 0, 1, 2, 1, 0).forEach { targetPage ->
@@ -788,7 +788,7 @@
@Test
fun test_getScrollState() {
val test = setUpTest(config.orientation)
- test.setAdapterSync(viewAdapterProvider(stringSequence(5)))
+ test.setAdapterSync(viewAdapterProvider.provider(stringSequence(5)))
// Test SCROLL_STATE_SETTLING
test_getScrollState(test, SCROLL_STATE_SETTLING, 1) {
@@ -852,7 +852,7 @@
// given
val test = setUpTest(config.orientation)
val recorder = test.viewPager.addNewRecordingCallback()
- val adapterProvider = viewAdapterProvider(stringSequence(3))
+ val adapterProvider = viewAdapterProvider.provider(stringSequence(3))
val marker = 1
fun expectedEvents(page: Int): List<Event> {
@@ -901,7 +901,7 @@
private fun test_setCurrentItem_outOfBounds(smoothScroll: Boolean) {
val test = setUpTest(config.orientation)
val n = 3
- test.setAdapterSync(viewAdapterProvider(stringSequence(n)))
+ test.setAdapterSync(viewAdapterProvider.provider(stringSequence(n)))
val adapterCount = test.viewPager.adapter!!.itemCount
listOf(-5, -1, n, n + 1, adapterCount, adapterCount + 1).forEach { targetPage ->
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerItemAnimatorTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerItemAnimatorTest.kt
index 8dc6458..b0504d0 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerItemAnimatorTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerItemAnimatorTest.kt
@@ -42,7 +42,7 @@
@Test
fun test() {
setUpTest(ORIENTATION_HORIZONTAL).apply {
- setAdapterSync(viewAdapterProviderValueId(stringSequence(5)))
+ setAdapterSync(viewAdapterProviderValueId.provider(stringSequence(5)))
assertBasicState(0)
val rv = viewPager.getChildAt(0) as RecyclerView
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt
index 4d78da2..85ece6c 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt
@@ -125,7 +125,7 @@
fun test() {
// given
val test = setUpTest(config.orientation)
- test.setAdapterSync(viewAdapterProvider(stringSequence(100)))
+ test.setAdapterSync(viewAdapterProvider.provider(stringSequence(100)))
// when
config.pageList.forEach { targetPage ->
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt
index 8d6159b..e45e4d9 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt
@@ -138,7 +138,7 @@
config.apply {
// given
setUpTest(orientation).apply {
- setAdapterSync(viewAdapterProvider(stringSequence(totalPages)))
+ setAdapterSync(viewAdapterProvider.provider(stringSequence(totalPages)))
val callback = viewPager.addNewRecordingCallback()
var currentPage = viewPager.currentItem
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt
index 9cacdcd..91bf776 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt
@@ -40,7 +40,7 @@
testConfig.apply {
setUpTest(orientation).apply {
val expectedValues = stringSequence(totalPages).toMutableList()
- val adapter = adapterProvider(expectedValues.toList()) // immutable defensive copy
+ val adapter = adapterProvider.provider(expectedValues.toList()) // defensive copy
setAdapterSync(adapter)
assertBasicState(0)
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
index ebe5a6a..cb29e66 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
@@ -45,7 +45,7 @@
fun test_swipeBetweenPages() {
setUpTest(orientation).apply {
val expectedValues = stringSequence(totalPages)
- val adapter = adapterProvider(expectedValues)
+ val adapter = adapterProvider.provider(expectedValues)
val fragmentManager = activity.supportFragmentManager
diff --git a/viewpager2/src/main/java/androidx/viewpager2/adapter/FragmentStateAdapter.java b/viewpager2/src/main/java/androidx/viewpager2/adapter/FragmentStateAdapter.java
index b40f192..a616e861 100644
--- a/viewpager2/src/main/java/androidx/viewpager2/adapter/FragmentStateAdapter.java
+++ b/viewpager2/src/main/java/androidx/viewpager2/adapter/FragmentStateAdapter.java
@@ -473,7 +473,6 @@
/**
* Default implementation works for collections that don't add, move, remove items.
* <p>
- * TODO(b/122670460): add lint rule
* When overriding, also override {@link #containsItem(long)}.
* <p>
* If the item is not a part of the collection, return {@link RecyclerView#NO_ID}.
@@ -481,6 +480,7 @@
* @param position Adapter position
* @return stable item id {@link RecyclerView.Adapter#hasStableIds()}
*/
+ // TODO(b/122670460): add lint rule
@Override
public long getItemId(int position) {
return position;
@@ -489,9 +489,9 @@
/**
* Default implementation works for collections that don't add, move, remove items.
* <p>
- * TODO(b/122670460): add lint rule
* When overriding, also override {@link #getItemId(int)}
*/
+ // TODO(b/122670460): add lint rule
public boolean containsItem(long itemId) {
return itemId >= 0 && itemId < getItemCount();
}
diff --git a/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java b/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
index e69087b..32bdc64 100644
--- a/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
+++ b/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
@@ -582,8 +582,6 @@
* the current item and the specified item. Silently ignored if the adapter is not set or
* empty. Clamps item to the bounds of the adapter.
*
- * TODO(b/123069219): verify first layout behavior
- *
* @param item Item index to select
*/
public void setCurrentItem(int item) {
diff --git a/work/workmanager-benchmark/build.gradle b/work/workmanager-benchmark/build.gradle
index 8dd3ba4..4c74f21 100644
--- a/work/workmanager-benchmark/build.gradle
+++ b/work/workmanager-benchmark/build.gradle
@@ -32,7 +32,7 @@
dependencies {
androidTestImplementation(project(':work:work-runtime-ktx'))
androidTestImplementation(project(":benchmark:benchmark-junit4"))
- androidTestImplementation("androidx.room:room-runtime:2.2.2")
+ androidTestImplementation("androidx.room:room-runtime:2.2.3")
androidTestImplementation(JUNIT)
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/work/workmanager-gcm/build.gradle b/work/workmanager-gcm/build.gradle
index f960dec..e7f4a95 100644
--- a/work/workmanager-gcm/build.gradle
+++ b/work/workmanager-gcm/build.gradle
@@ -51,9 +51,9 @@
implementation(project(":room:room-runtime"))
androidTestImplementation(project(":room:room-testing"))
} else {
- annotationProcessor("androidx.room:room-compiler:2.2.2")
- implementation("androidx.room:room-runtime:2.2.2")
- androidTestImplementation("androidx.room:room-testing:2.2.2")
+ annotationProcessor("androidx.room:room-compiler:2.2.3")
+ implementation("androidx.room:room-runtime:2.2.3")
+ androidTestImplementation("androidx.room:room-testing:2.2.3")
}
androidTestImplementation(project(":work:work-runtime-ktx"))
diff --git a/work/workmanager-ktx/build.gradle b/work/workmanager-ktx/build.gradle
index e515cec..25ad0d8c 100644
--- a/work/workmanager-ktx/build.gradle
+++ b/work/workmanager-ktx/build.gradle
@@ -53,7 +53,7 @@
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation("androidx.room:room-testing:2.2.2")
+ androidTestImplementation("androidx.room:room-testing:2.2.3")
testImplementation(JUNIT)
}
diff --git a/work/workmanager-testing/build.gradle b/work/workmanager-testing/build.gradle
index 84b62ad..42f84b7 100644
--- a/work/workmanager-testing/build.gradle
+++ b/work/workmanager-testing/build.gradle
@@ -38,7 +38,7 @@
dependencies {
api(project(':work:work-runtime-ktx'))
implementation("androidx.lifecycle:lifecycle-livedata-core:2.1.0")
- implementation("androidx.room:room-runtime:2.2.2")
+ implementation("androidx.room:room-runtime:2.2.3")
androidTestImplementation("androidx.arch.core:core-testing:2.1.0")
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
diff --git a/work/workmanager/build.gradle b/work/workmanager/build.gradle
index 1c15e53..48a698e 100644
--- a/work/workmanager/build.gradle
+++ b/work/workmanager/build.gradle
@@ -62,9 +62,11 @@
}
dependencies {
- annotationProcessor("androidx.room:room-compiler:2.2.2")
- implementation("androidx.room:room-runtime:2.2.2")
- androidTestImplementation("androidx.room:room-testing:2.2.2")
+ annotationProcessor("androidx.room:room-compiler:2.2.3")
+ implementation("androidx.room:room-runtime:2.2.3")
+ androidTestImplementation("androidx.room:room-testing:2.2.3")
+ implementation("androidx.sqlite:sqlite:2.1.0-rc01")
+ implementation("androidx.sqlite:sqlite-framework:2.1.0-rc01")
api(GUAVA_LISTENABLE_FUTURE)
api("androidx.lifecycle:lifecycle-livedata:2.1.0")
implementation("androidx.core:core:1.1.0")
diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
index aa4c086..83a9ff9 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
@@ -36,6 +36,8 @@
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import androidx.sqlite.db.SupportSQLiteDatabase;
+import androidx.sqlite.db.SupportSQLiteOpenHelper;
+import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory;
import androidx.work.Data;
import androidx.work.impl.model.Dependency;
import androidx.work.impl.model.DependencyDao;
@@ -100,7 +102,7 @@
*/
@NonNull
public static WorkDatabase create(
- @NonNull Context context,
+ @NonNull final Context context,
@NonNull Executor queryExecutor,
boolean useTestDatabase) {
RoomDatabase.Builder<WorkDatabase> builder;
@@ -108,8 +110,23 @@
builder = Room.inMemoryDatabaseBuilder(context, WorkDatabase.class)
.allowMainThreadQueries();
} else {
- String path = WorkDatabasePathHelper.getDatabasePath(context).getPath();
- builder = Room.databaseBuilder(context, WorkDatabase.class, path);
+ String name = WorkDatabasePathHelper.getWorkDatabaseName();
+ builder = Room.databaseBuilder(context, WorkDatabase.class, name);
+ builder.openHelperFactory(new SupportSQLiteOpenHelper.Factory() {
+ @NonNull
+ @Override
+ public SupportSQLiteOpenHelper create(
+ @NonNull SupportSQLiteOpenHelper.Configuration configuration) {
+ SupportSQLiteOpenHelper.Configuration.Builder configBuilder =
+ SupportSQLiteOpenHelper.Configuration.builder(context);
+ configBuilder.name(configuration.name)
+ .callback(configuration.callback)
+ .noBackupDirectory(true);
+ FrameworkSQLiteOpenHelperFactory factory =
+ new FrameworkSQLiteOpenHelperFactory();
+ return factory.create(configBuilder.build());
+ }
+ });
}
return builder.setQueryExecutor(queryExecutor)
diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabasePathHelper.java b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabasePathHelper.java
index aafcb32..0b4bf2b 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabasePathHelper.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabasePathHelper.java
@@ -47,26 +47,11 @@
private static final String[] DATABASE_EXTRA_FILES = new String[]{"-journal", "-shm", "-wal"};
/**
- * @param context The application {@link Context}
- * @return The database path before migration to the no-backup directory.
+ * @return The name of the database.
*/
@NonNull
- public static File getDefaultDatabasePath(@NonNull Context context) {
- return context.getDatabasePath(WORK_DATABASE_NAME);
- }
-
- /**
- * @param context The application {@link Context}
- * @return The the migrated database path.
- */
- @NonNull
- public static File getDatabasePath(@NonNull Context context) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
- // No notion of a backup directory exists.
- return getDefaultDatabasePath(context);
- } else {
- return getNoBackupPath(context, WORK_DATABASE_NAME);
- }
+ public static String getWorkDatabaseName() {
+ return WORK_DATABASE_NAME;
}
/**
@@ -123,6 +108,31 @@
}
/**
+ * @param context The application {@link Context}
+ * @return The database path before migration to the no-backup directory.
+ */
+ @NonNull
+ @VisibleForTesting
+ public static File getDefaultDatabasePath(@NonNull Context context) {
+ return context.getDatabasePath(WORK_DATABASE_NAME);
+ }
+
+ /**
+ * @param context The application {@link Context}
+ * @return The the migrated database path.
+ */
+ @NonNull
+ @VisibleForTesting
+ public static File getDatabasePath(@NonNull Context context) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ // No notion of a backup directory exists.
+ return getDefaultDatabasePath(context);
+ } else {
+ return getNoBackupPath(context, WORK_DATABASE_NAME);
+ }
+ }
+
+ /**
* Return the path for a {@link File} path in the {@link Context#getNoBackupFilesDir()}
* identified by the {@link String} fragment.
*