Merge changes Id5d0db40,I5b32e636 into androidx-master-dev
* changes:
Parse selection slices in RowContent.
Rearrange selection subtypes/hints.
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/app/DrawerLayoutTest.java b/appcompat/src/androidTest/java/androidx/appcompat/app/DrawerLayoutTest.java
index 0be3dc9..855f747 100755
--- a/appcompat/src/androidTest/java/androidx/appcompat/app/DrawerLayoutTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/app/DrawerLayoutTest.java
@@ -191,8 +191,9 @@
}
}
- @Test
- @LargeTest
+ // Temporarily disabled due to b/77228907.
+ // @Test
+ // @LargeTest
public void testDrawerOpenCloseViaSwipes() {
assertFalse("Initial state", mDrawerLayout.isDrawerOpen(GravityCompat.START));
@@ -215,8 +216,9 @@
}
}
- @Test
- @LargeTest
+ // Temporarily disabled due to b/34178560.
+ // @Test
+ // @LargeTest
public void testDrawerOpenCloseWithRedundancyViaSwipes() {
assertFalse("Initial state", mDrawerLayout.isDrawerOpen(GravityCompat.START));
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java
index 533f425..7c98396 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/SearchView_CursorTest.java
@@ -168,7 +168,8 @@
verify(mockQueryTextListener, times(1)).onQueryTextChange("Di");
}
- @Test
+ // Temporarily disabled due to b/111852321
+ // @Test
public void testSuggestionSelection() throws Throwable {
final SearchView.OnSuggestionListener mockSuggestionListener =
spy(new MySuggestionListener());
diff --git a/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index de7ed44..66141c9 100644
--- a/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -2432,7 +2432,6 @@
frozenMenuState = null;
}
}
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
private static class SavedState implements Parcelable {
int featureId;
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/ActionMenuPresenter.java b/appcompat/src/main/java/androidx/appcompat/widget/ActionMenuPresenter.java
index dd08002..fdd4417 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/ActionMenuPresenter.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/ActionMenuPresenter.java
@@ -602,7 +602,6 @@
menuView.initialize(mMenu);
}
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
private static class SavedState implements Parcelable {
public int openSubMenuId;
diff --git a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
index 8e7961e..062c709 100644
--- a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
@@ -199,12 +199,6 @@
check(minSdkVersion >= DEFAULT_MIN_SDK_VERSION) {
"minSdkVersion $minSdkVersion lower than the default of $DEFAULT_MIN_SDK_VERSION"
}
- // Add our custom error-prone project as an annotation processor which causes our custom
- // rules to run as error-prone checks.
- if (project.name != "docs-fake" && !project.name.contains("demos")) {
- project.dependencies.add("annotationProcessor",
- project.project(":customerrorprone"))
- }
project.configurations.all { configuration ->
configuration.resolutionStrategy.eachDependency { dep ->
val target = dep.target
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index 1b74db7..013a8cc 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -36,7 +36,7 @@
val CAR_CLUSTER = Version("1.0.0-alpha5")
val CAR_MODERATOR = Version("1.0.0-alpha1")
val CARDVIEW = Version("1.0.0")
- val COLLECTION = Version("1.1.0-alpha01")
+ val COLLECTION = Version("1.1.0-alpha02")
val CONTENTPAGER = Version("1.0.0")
val COORDINATORLAYOUT = Version("1.1.0-alpha02")
val CORE = Version("1.1.0-alpha03")
@@ -75,7 +75,7 @@
val PREFERENCE = Version("1.1.0-alpha02")
val RECOMMENDATION = Version("1.0.0")
val RECYCLERVIEW = Version("1.1.0-alpha01")
- val REMOTECALLBACK = Version("1.0.0-alpha01")
+ val REMOTECALLBACK = Version("1.0.0-alpha02")
val ROOM = Version("2.1.0-alpha03")
val SAVEDSTATE = Version("1.0.0-alpha01")
val SHARETARGET = Version("1.0.0-alpha01")
@@ -84,8 +84,8 @@
val SLICE_BUILDERS_KTX = Version("1.0.0-alpha6")
val SLIDINGPANELAYOUT = Version("1.0.0")
val SWIPE_REFRESH_LAYOUT = Version("1.1.0-alpha01")
- val TEXTCLASSIFIER = Version("1.0.0-alpha01")
- val TRANSITION = Version("1.1.0-alpha01")
+ val TEXTCLASSIFIER = Version("1.0.0-alpha02")
+ val TRANSITION = Version("1.1.0-alpha02")
val TVPROVIDER = Version("1.0.0")
val VECTORDRAWABLE = Version("1.1.0-alpha01")
val VECTORDRAWABLE_ANIMATED = Version("1.1.0-alpha01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
index 76a0b30..0d98870 100644
--- a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
@@ -102,7 +102,7 @@
prebuilts(LibraryGroups.ARCH_CORE, "2.0.0")
prebuilts(LibraryGroups.PAGING, "2.1.0-beta01")
prebuilts(LibraryGroups.NAVIGATION, "1.0.0-alpha08")
- prebuilts(LibraryGroups.WORKMANAGER, "1.0.0-alpha12")
+ prebuilts(LibraryGroups.WORKMANAGER, "1.0.0-alpha13")
default(Ignore)
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
index cfbea70..339ec22 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
@@ -67,9 +67,6 @@
if (!FileUtils.contentEquals(publicApi1, publicApi2)) {
throw GradleException(publicApiFailureMessage);
}
- if (!FileUtils.contentEquals(restrictedApi1, restrictedApi2)) {
- throw GradleException(restrictedApiFailureMessage);
- }
}
}
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/Metalava.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/Metalava.kt
index 42c2150..064e7c918 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/Metalava.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/Metalava.kt
@@ -115,7 +115,7 @@
applyInputs(javaCompileInputs, generateApi)
val checkApi = project.tasks.create("checkApi", CheckApiEquivalenceTask::class.java) { task ->
- task.builtApi = libraryVersionApi
+ task.builtApi = generateApi.apiLocation
task.checkedInApis = outputApiLocations
task.dependsOn(generateApi)
}
diff --git a/car/core/api/1.0.0-alpha6.txt b/car/core/api/1.0.0-alpha6.txt
index 88cfd87..6e2e228 100644
--- a/car/core/api/1.0.0-alpha6.txt
+++ b/car/core/api/1.0.0-alpha6.txt
@@ -231,13 +231,13 @@
ctor public CarToolbar(android.content.Context!, android.util.AttributeSet!);
ctor public CarToolbar(android.content.Context!, android.util.AttributeSet!, int);
ctor public CarToolbar(android.content.Context!, android.util.AttributeSet!, int, int);
- method public CharSequence! getSubtitle();
+ method public CharSequence? getSubtitle();
method public CharSequence! getTitle();
method public void setNavigationIcon(android.graphics.drawable.Icon?);
method public void setNavigationIconContainerWidth(@Px int);
method public void setNavigationIconOnClickListener(android.view.View.OnClickListener?);
method public void setSubtitle(@StringRes int);
- method public void setSubtitle(CharSequence!);
+ method public void setSubtitle(CharSequence?);
method public void setSubtitleTextAppearance(@StyleRes int);
method public void setTitle(@StringRes int);
method public void setTitle(CharSequence!);
diff --git a/car/core/api/current.txt b/car/core/api/current.txt
index 88cfd87..6e2e228 100644
--- a/car/core/api/current.txt
+++ b/car/core/api/current.txt
@@ -231,13 +231,13 @@
ctor public CarToolbar(android.content.Context!, android.util.AttributeSet!);
ctor public CarToolbar(android.content.Context!, android.util.AttributeSet!, int);
ctor public CarToolbar(android.content.Context!, android.util.AttributeSet!, int, int);
- method public CharSequence! getSubtitle();
+ method public CharSequence? getSubtitle();
method public CharSequence! getTitle();
method public void setNavigationIcon(android.graphics.drawable.Icon?);
method public void setNavigationIconContainerWidth(@Px int);
method public void setNavigationIconOnClickListener(android.view.View.OnClickListener?);
method public void setSubtitle(@StringRes int);
- method public void setSubtitle(CharSequence!);
+ method public void setSubtitle(CharSequence?);
method public void setSubtitleTextAppearance(@StyleRes int);
method public void setTitle(@StringRes int);
method public void setTitle(CharSequence!);
diff --git a/collection/api/1.1.0-alpha02.txt b/collection/api/1.1.0-alpha02.txt
new file mode 100644
index 0000000..81bb5ce
--- /dev/null
+++ b/collection/api/1.1.0-alpha02.txt
@@ -0,0 +1,183 @@
+// Signature format: 2.0
+package androidx.collection {
+
+ public class ArrayMap<K, V> extends androidx.collection.SimpleArrayMap<K,V> implements java.util.Map<K,V> {
+ ctor public ArrayMap();
+ ctor public ArrayMap(int);
+ ctor public ArrayMap(androidx.collection.SimpleArrayMap!);
+ method public boolean containsAll(java.util.Collection<?>);
+ method public java.util.Set<java.util.Map.Entry<K,V>>! entrySet();
+ method public java.util.Set<K>! keySet();
+ method public void putAll(java.util.Map<? extends K,? extends V>!);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public java.util.Collection<V>! values();
+ }
+
+ public final class ArraySet<E> implements java.util.Collection<E> java.util.Set<E> {
+ ctor public ArraySet();
+ ctor public ArraySet(int);
+ ctor public ArraySet(androidx.collection.ArraySet<E>?);
+ ctor public ArraySet(java.util.Collection<E>?);
+ method public boolean add(E?);
+ method public void addAll(androidx.collection.ArraySet<? extends E>);
+ method public boolean addAll(java.util.Collection<? extends E>);
+ method public void clear();
+ method public boolean contains(Object?);
+ method public boolean containsAll(java.util.Collection<?>);
+ method public void ensureCapacity(int);
+ method public int indexOf(Object?);
+ method public boolean isEmpty();
+ method public java.util.Iterator<E>! iterator();
+ method public boolean remove(Object?);
+ method public boolean removeAll(androidx.collection.ArraySet<? extends E>);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public E! removeAt(int);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public int size();
+ method public Object[] toArray();
+ method public <T> T[] toArray(T[]);
+ method public E? valueAt(int);
+ }
+
+ public final class CircularArray<E> {
+ ctor public CircularArray();
+ ctor public CircularArray(int);
+ method public void addFirst(E!);
+ method public void addLast(E!);
+ method public void clear();
+ method public E! get(int);
+ method public E! getFirst();
+ method public E! getLast();
+ method public boolean isEmpty();
+ method public E! popFirst();
+ method public E! popLast();
+ method public void removeFromEnd(int);
+ method public void removeFromStart(int);
+ method public int size();
+ }
+
+ public final class CircularIntArray {
+ ctor public CircularIntArray();
+ ctor public CircularIntArray(int);
+ method public void addFirst(int);
+ method public void addLast(int);
+ method public void clear();
+ method public int get(int);
+ method public int getFirst();
+ method public int getLast();
+ method public boolean isEmpty();
+ method public int popFirst();
+ method public int popLast();
+ method public void removeFromEnd(int);
+ method public void removeFromStart(int);
+ method public int size();
+ }
+
+ public class LongSparseArray<E> implements java.lang.Cloneable {
+ ctor public LongSparseArray();
+ ctor public LongSparseArray(int);
+ method public void append(long, E!);
+ method public void clear();
+ method public androidx.collection.LongSparseArray<E>! clone();
+ method public boolean containsKey(long);
+ method public boolean containsValue(E!);
+ method public void delete(long);
+ method public E? get(long);
+ method public E! get(long, E!);
+ method public int indexOfKey(long);
+ method public int indexOfValue(E!);
+ method public boolean isEmpty();
+ method public long keyAt(int);
+ method public void put(long, E!);
+ method public void putAll(androidx.collection.LongSparseArray<? extends E>);
+ method public E? putIfAbsent(long, E!);
+ method public void remove(long);
+ method public boolean remove(long, Object!);
+ method public void removeAt(int);
+ method public E? replace(long, E!);
+ method public boolean replace(long, E!, E!);
+ method public void setValueAt(int, E!);
+ method public int size();
+ method public E! valueAt(int);
+ }
+
+ public class LruCache<K, V> {
+ ctor public LruCache(int);
+ method protected V? create(K);
+ method public final int createCount();
+ method protected void entryRemoved(boolean, K, V, V?);
+ method public final void evictAll();
+ method public final int evictionCount();
+ method public final V? get(K);
+ method public final int hitCount();
+ method public final int maxSize();
+ method public final int missCount();
+ method public final V? put(K, V);
+ method public final int putCount();
+ method public final V? remove(K);
+ method public void resize(int);
+ method public final int size();
+ method protected int sizeOf(K, V);
+ method public final java.util.Map<K,V>! snapshot();
+ method public final String toString();
+ method public void trimToSize(int);
+ }
+
+ public class SimpleArrayMap<K, V> {
+ ctor public SimpleArrayMap();
+ ctor public SimpleArrayMap(int);
+ ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<K,V>!);
+ method public void clear();
+ method public boolean containsKey(Object?);
+ method public boolean containsValue(Object!);
+ method public void ensureCapacity(int);
+ method public V? get(Object!);
+ method public V! getOrDefault(Object!, V!);
+ method public int indexOfKey(Object?);
+ method public boolean isEmpty();
+ method public K! keyAt(int);
+ method public V? put(K!, V!);
+ method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V>);
+ method public V? putIfAbsent(K!, V!);
+ method public V? remove(Object!);
+ method public boolean remove(Object!, Object!);
+ method public V! removeAt(int);
+ method public V? replace(K!, V!);
+ method public boolean replace(K!, V!, V!);
+ method public V! setValueAt(int, V!);
+ method public int size();
+ method public V! valueAt(int);
+ }
+
+ public class SparseArrayCompat<E> implements java.lang.Cloneable {
+ ctor public SparseArrayCompat();
+ ctor public SparseArrayCompat(int);
+ method public void append(int, E!);
+ method public void clear();
+ method public androidx.collection.SparseArrayCompat<E>! clone();
+ method public boolean containsKey(int);
+ method public boolean containsValue(E!);
+ method public void delete(int);
+ method public E? get(int);
+ method public E! get(int, E!);
+ method public int indexOfKey(int);
+ method public int indexOfValue(E!);
+ method public boolean isEmpty();
+ method public int keyAt(int);
+ method public void put(int, E!);
+ method public void putAll(androidx.collection.SparseArrayCompat<? extends E>);
+ method public E? putIfAbsent(int, E!);
+ method public void remove(int);
+ method public boolean remove(int, Object!);
+ method public void removeAt(int);
+ method public void removeAtRange(int, int);
+ method public E? replace(int, E!);
+ method public boolean replace(int, E!, E!);
+ method public void setValueAt(int, E!);
+ method public int size();
+ method public E! valueAt(int);
+ }
+
+}
+
diff --git a/collection/ktx/api/1.1.0-alpha02.txt b/collection/ktx/api/1.1.0-alpha02.txt
new file mode 100644
index 0000000..36ae63f
--- /dev/null
+++ b/collection/ktx/api/1.1.0-alpha02.txt
@@ -0,0 +1,52 @@
+// Signature format: 2.0
+package androidx.collection {
+
+ public final class ArrayMapKt {
+ ctor public ArrayMapKt();
+ method public static <K, V> androidx.collection.ArrayMap<K,V> arrayMapOf();
+ method public static <K, V> androidx.collection.ArrayMap<K,V> arrayMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+ }
+
+ public final class ArraySetKt {
+ ctor public ArraySetKt();
+ method public static <T> androidx.collection.ArraySet<T> arraySetOf();
+ method public static <T> androidx.collection.ArraySet<T> arraySetOf(T... values);
+ }
+
+ public final class LongSparseArrayKt {
+ ctor public LongSparseArrayKt();
+ method public static operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
+ method public static <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
+ method public static <T> T! getOrDefault(androidx.collection.LongSparseArray<T>, long key, T! defaultValue);
+ method public static <T> T! getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static <T> int getSize(androidx.collection.LongSparseArray<T>);
+ method public static <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
+ method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
+ method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
+ method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T! value);
+ method public static operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T! value);
+ method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
+ }
+
+ public final class LruCacheKt {
+ ctor public LruCacheKt();
+ method public static <K, V> androidx.collection.LruCache<K,V> lruCache(int maxSize, kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf = { _, _ -> 1 }, kotlin.jvm.functions.Function1<? super K,? extends V> create = { (V)null }, kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> _, _, _, _ -> });
+ }
+
+ public final class SparseArrayKt {
+ ctor public SparseArrayKt();
+ method public static operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
+ method public static <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
+ method public static <T> T! getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T! defaultValue);
+ method public static <T> T! getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static <T> int getSize(androidx.collection.SparseArrayCompat<T>);
+ method public static <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
+ method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
+ method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
+ method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T! value);
+ method public static operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T! value);
+ method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
+ }
+
+}
+
diff --git a/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java b/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java
index 639c5d8..c4d5a0f 100644
--- a/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java
+++ b/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java
@@ -69,7 +69,6 @@
mContext = InstrumentationRegistry.getContext();
}
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public static final class TestIntentItem implements Parcelable {
public static final int FLAG_WAIT = 1 << 0;
diff --git a/core/src/androidTest/java/androidx/core/app/PersonTest.java b/core/src/androidTest/java/androidx/core/app/PersonTest.java
index 935bb90..029ee4c 100644
--- a/core/src/androidTest/java/androidx/core/app/PersonTest.java
+++ b/core/src/androidTest/java/androidx/core/app/PersonTest.java
@@ -81,7 +81,7 @@
}
@Test
- @SdkSuppress(minSdkVersion = 21)
+ @SdkSuppress(minSdkVersion = 22)
public void persistableBundle() {
Person person = new Person.Builder()
.setImportant(TEST_IS_IMPORTANT)
@@ -104,7 +104,7 @@
}
@Test
- @SdkSuppress(minSdkVersion = 21)
+ @SdkSuppress(minSdkVersion = 22)
public void persistableBundle_defaultValues() {
Person person = new Person.Builder().build();
diff --git a/core/src/main/java/android/support/v4/os/ResultReceiver.java b/core/src/main/java/android/support/v4/os/ResultReceiver.java
index 7274914..ae233ca 100644
--- a/core/src/main/java/android/support/v4/os/ResultReceiver.java
+++ b/core/src/main/java/android/support/v4/os/ResultReceiver.java
@@ -42,7 +42,6 @@
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public class ResultReceiver implements Parcelable {
final boolean mLocal;
diff --git a/core/src/main/java/androidx/core/view/ViewCompat.java b/core/src/main/java/androidx/core/view/ViewCompat.java
index c17c539..866db9c 100644
--- a/core/src/main/java/androidx/core/view/ViewCompat.java
+++ b/core/src/main/java/androidx/core/view/ViewCompat.java
@@ -4009,7 +4009,6 @@
}
return null;
}
- @SuppressWarnings("BanUnlistedSDKVersionComparison")
private boolean frameworkAvailable() {
return Build.VERSION.SDK_INT >= mFrameworkMinimumSdk;
}
diff --git a/customerrorprone/build.gradle b/customerrorprone/build.gradle
deleted file mode 100644
index 4680b8f..0000000
--- a/customerrorprone/build.gradle
+++ /dev/null
@@ -1,15 +0,0 @@
-import static androidx.build.dependencies.DependenciesKt.*
-
-
-apply plugin:'java'
-
-dependencies {
-
- implementation project(':annotation')
-
- compileOnly 'com.google.errorprone:error_prone_core:2.3.1'
- compileOnly 'com.google.errorprone:error_prone_annotation:2.3.1'
-
- compileOnly 'com.google.auto.service:auto-service:1.0-rc4'
- annotationProcessor 'com.google.auto.service:auto-service:1.0-rc4'
-}
\ No newline at end of file
diff --git a/customerrorprone/src/main/java/androidx/customerrorprone/BanKeepAnnotation.java b/customerrorprone/src/main/java/androidx/customerrorprone/BanKeepAnnotation.java
deleted file mode 100644
index 8bb2363..0000000
--- a/customerrorprone/src/main/java/androidx/customerrorprone/BanKeepAnnotation.java
+++ /dev/null
@@ -1,58 +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 androidx.customerrorprone;
-
-import static com.google.errorprone.BugPattern.Category.ANDROID;
-import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
-import static com.google.errorprone.matchers.Description.NO_MATCH;
-import static com.google.errorprone.matchers.Matchers.hasAnnotation;
-
-import androidx.annotation.Keep;
-
-import com.google.auto.service.AutoService;
-import com.google.errorprone.BugPattern;
-import com.google.errorprone.VisitorState;
-import com.google.errorprone.bugpatterns.BugChecker;
-import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
-import com.google.errorprone.matchers.Description;
-import com.google.errorprone.matchers.Matcher;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-
-/**
- * Matches on existence of androidx.annotation.Keep annotation
- */
-@AutoService(BugChecker.class)
-@BugPattern(
- name = "BanKeepAnnotation",
- category = ANDROID,
- summary = "Use of Keep annotation is not allowed, , please use a conditional keep rule in"
- + " proguard-rules.pro.",
- severity = ERROR)
-public class BanKeepAnnotation extends BugChecker implements MethodTreeMatcher {
-
- private static final Matcher<Tree> HAS_KEEP_ANNOTATION =
- hasAnnotation(Keep.class.getCanonicalName());
-
- @Override
- public Description matchMethod(MethodTree tree, VisitorState state) {
- if (!HAS_KEEP_ANNOTATION.matches(tree, state)) {
- return NO_MATCH;
- }
- return describeMatch(tree);
- }
-}
diff --git a/customerrorprone/src/main/java/androidx/customerrorprone/BanParcelableUsage.java b/customerrorprone/src/main/java/androidx/customerrorprone/BanParcelableUsage.java
deleted file mode 100644
index ffe7bc6..0000000
--- a/customerrorprone/src/main/java/androidx/customerrorprone/BanParcelableUsage.java
+++ /dev/null
@@ -1,63 +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 androidx.customerrorprone;
-
-import static com.google.errorprone.matchers.Matchers.allOf;
-import static com.google.errorprone.matchers.Matchers.hasModifier;
-import static com.google.errorprone.matchers.Matchers.isDirectImplementationOf;
-import static com.google.errorprone.matchers.Matchers.not;
-
-import com.google.auto.service.AutoService;
-import com.google.errorprone.BugPattern;
-import com.google.errorprone.BugPattern.Category;
-import com.google.errorprone.BugPattern.SeverityLevel;
-import com.google.errorprone.VisitorState;
-import com.google.errorprone.bugpatterns.BugChecker;
-import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher;
-import com.google.errorprone.matchers.Description;
-import com.google.errorprone.matchers.Matcher;
-import com.sun.source.tree.ClassTree;
-
-import javax.lang.model.element.Modifier;
-
-/**
- * Bug Pattern that detects implementation of Parcelable and causes an error.
- */
-@AutoService(BugChecker.class)
-@BugPattern(
- name = "BanParcelableUsage",
- summary = "Use of Parcelable is no longer recommended,"
- + " please use VersionedParcelable instead.",
- category = Category.ANDROID,
- severity = SeverityLevel.ERROR)
-public class BanParcelableUsage extends BugChecker implements ClassTreeMatcher {
-
- /**
- * Matches if a non-public non-abstract class/interface is subtype of android.os.Parcelable
- */
- private static final Matcher<ClassTree> IMPLEMENTS_PARCELABLE =
- allOf(isDirectImplementationOf("android.os.Parcelable"),
- not(hasModifier(Modifier.ABSTRACT)));
-
- @Override
- public Description matchClass(ClassTree tree, VisitorState state) {
- if (!IMPLEMENTS_PARCELABLE.matches(tree, state)) {
- return Description.NO_MATCH;
- }
- return describeMatch(tree);
- }
-}
diff --git a/customerrorprone/src/main/java/androidx/customerrorprone/BanUnlistedSDKVersionComparison.java b/customerrorprone/src/main/java/androidx/customerrorprone/BanUnlistedSDKVersionComparison.java
deleted file mode 100644
index 9eded79..0000000
--- a/customerrorprone/src/main/java/androidx/customerrorprone/BanUnlistedSDKVersionComparison.java
+++ /dev/null
@@ -1,149 +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 androidx.customerrorprone;
-
-import static com.google.errorprone.BugPattern.Category.ANDROID;
-import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
-
-import com.google.errorprone.BugPattern;
-import com.google.errorprone.VisitorState;
-import com.google.errorprone.bugpatterns.BugChecker;
-import com.google.errorprone.bugpatterns.BugChecker.BinaryTreeMatcher;
-import com.google.errorprone.matchers.Description;
-import com.google.errorprone.util.ASTHelpers;
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.Tree.Kind;
-import com.sun.tools.javac.code.Symbol;
-
-import javax.lang.model.element.ElementKind;
-
-
-/**
- * Disallows direct comparison of SDK_INT to anything other than constants
- * in android.os.Build.VERSION_CODES
- */
-// @AutoService(BugChecker.class) TODO: decide whether we want to keep this rule and uncomment
-// the annotation or get rid of the class completely.
-@BugPattern(
- name = "BanUnlistedSDKVersionComparison",
- summary = "Comparison of SDK_INT to non listed version constants is not allowed, please"
- + " compare to versions listed in VERSION_CODES instead",
- category = ANDROID,
- severity = ERROR
-)
-public class BanUnlistedSDKVersionComparison extends BugChecker implements BinaryTreeMatcher {
-
- private static final String VERSION_CLASSNAME = "android.os.Build.VERSION";
- /**
- * {@code android.os.Build.VERSION.SDK_INT} checks above this version will be flagged.
- */
- private static final int MAXIMUM_ALLOWED_RAW_SDK_VERSION = 28;
-
- @Override
- public Description matchBinary(BinaryTree tree, VisitorState state) {
- ExpressionTree lhs = tree.getLeftOperand();
- ExpressionTree rhs = tree.getRightOperand();
-
- if (isSdkInt(lhs)) {
- return matchAssumingSdkIntIsLhs(tree, tree.getKind(), rhs);
- } else if (isSdkInt(rhs)) {
- return matchAssumingSdkIntIsLhs(tree, reverseBinop(tree.getKind()), lhs);
- } else {
- return Description.NO_MATCH;
- }
- }
-
- private Description matchAssumingSdkIntIsLhs(BinaryTree tree, Kind op, ExpressionTree rhs) {
- if (op == Kind.PLUS) {
- // Most likely being attached to a string, this is not a comparison, allow.
- return Description.NO_MATCH;
- } else if (!isVersionCode(rhs) && isAtLeast(rhs, minUnsafeRhs(op))) {
- return describeMatch(
- tree);
- }
- return Description.NO_MATCH;
- }
-
- private static boolean isAtLeast(ExpressionTree tree, long x) {
- Object value = ASTHelpers.constValue(tree);
- if (!(value instanceof Number)) {
- // Not a constant, most likely a variable
- // this should default to true to disallow its use.
- return true;
- }
- long actual = ((Number) value).longValue();
- return x <= actual;
- }
-
- private static boolean isVersionCode(ExpressionTree tree) {
- Symbol sym = ASTHelpers.getSymbol(tree);
- return sym instanceof Symbol.VarSymbol && ((Symbol.VarSymbol) sym).owner.enclClass()
- .getQualifiedName().contentEquals("android.os.Build.VERSION_CODES");
- }
-
- /**
- * Returns the operator op' such that (X op SDK_INT iff SDK_INT op' X) for the given op.
- * In other words, this method allows pretending that all SDK_INT comparisons have SDK_INT
- * as the lhs and a constant as the rhs.
- */
- private static Kind reverseBinop(Kind op) {
- switch (op) {
- case LESS_THAN:
- return Kind.GREATER_THAN;
- case LESS_THAN_EQUAL:
- return Kind.GREATER_THAN_EQUAL;
- case GREATER_THAN:
- return Kind.LESS_THAN;
- case GREATER_THAN_EQUAL:
- return Kind.LESS_THAN_EQUAL;
- case EQUAL_TO:
- case NOT_EQUAL_TO:
- default: // weird things like & | ^
- return op;
- }
- }
-
- /**
- * Returns the minimum X for which we want to flag a comparison SDK_INT op X for the given op.
- */
- private static int minUnsafeRhs(Kind op) {
- switch (op) {
- case LESS_THAN_EQUAL:
- case GREATER_THAN:
- return MAXIMUM_ALLOWED_RAW_SDK_VERSION;
- case LESS_THAN:
- case GREATER_THAN_EQUAL:
- case EQUAL_TO:
- case NOT_EQUAL_TO:
- default: // weird things like & | ^
- return MAXIMUM_ALLOWED_RAW_SDK_VERSION + 1;
- }
- }
-
- private static boolean isSdkInt(ExpressionTree tree) {
- Symbol symbol = ASTHelpers.getSymbol(tree);
- // Match symbol's owner to android.os.Build.VERSION separately because can't get fully
- // qualified "android.os.Build.VERSION.SDK_INT" out of symbol, just "SDK_INT"
- return symbol != null
- && symbol.owner != null
- && symbol.getKind() == ElementKind.FIELD
- && symbol.isStatic()
- && VERSION_CLASSNAME.contentEquals(symbol.owner.getQualifiedName())
- && "SDK_INT".contentEquals(symbol.name);
- }
-}
diff --git a/customview/src/main/java/androidx/customview/view/AbsSavedState.java b/customview/src/main/java/androidx/customview/view/AbsSavedState.java
index f66beaf..685a99f 100644
--- a/customview/src/main/java/androidx/customview/view/AbsSavedState.java
+++ b/customview/src/main/java/androidx/customview/view/AbsSavedState.java
@@ -27,7 +27,6 @@
* A {@link Parcelable} implementation that should be used by inheritance
* hierarchies to ensure the state of all classes along the chain is saved.
*/
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public abstract class AbsSavedState implements Parcelable {
public static final AbsSavedState EMPTY_STATE = new AbsSavedState() {};
diff --git a/development/importMaven/README.md b/development/importMaven/README.md
index 4b35ff6..d2a57e4 100644
--- a/development/importMaven/README.md
+++ b/development/importMaven/README.md
@@ -3,5 +3,5 @@
#### Using the script
```bash
-./gradlew -PartifactName=android.arch.work:work-runtime-ktx:1.0.0-alpha07
+./import_maven_artifacts.py --name=android.arch.work:work-runtime-ktx:1.0.0-alpha07
```
diff --git a/development/importMaven/build.gradle.kts b/development/importMaven/build.gradle.kts
index ee51f38..f43c955 100644
--- a/development/importMaven/build.gradle.kts
+++ b/development/importMaven/build.gradle.kts
@@ -252,7 +252,6 @@
val outputFile = File(parent, "${file.name}.${algorithm.toLowerCase()}")
outputFile.deleteOnExit()
outputFile.writeText(builder.toString())
- outputFile.deleteOnExit()
return outputFile
}
@@ -283,9 +282,6 @@
)
into(location)
}
- copy {
- into(location)
- }
// Copy supporting artifacts
for (supportingArtifact in supportingArtifacts) {
println("Copying $supportingArtifact to $location")
@@ -330,9 +326,6 @@
)
into(location)
}
- copy {
- into(location)
- }
}
tasks {
diff --git a/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java b/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java
index 6683eaf..7e9b155 100644
--- a/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java
+++ b/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java
@@ -97,7 +97,7 @@
anim.setStartValue(100).setStartVelocity(2000).start();
}
});
- verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
+ verify(listener, timeout(2000)).onAnimationEnd(eq(anim), eq(false), floatThat(
new GreaterThan(110f)), eq(0f));
}
@@ -120,7 +120,7 @@
anim.start();
}
});
- verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
+ verify(listener, timeout(2000)).onAnimationEnd(eq(anim), eq(false), floatThat(
new LessThan(-50f)), eq(0f));
}
diff --git a/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java b/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
index 962025c..84bd288 100644
--- a/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
+++ b/dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
@@ -346,7 +346,7 @@
}
});
- verify(mockListener, timeout(2000)).onAnimationEnd(springAnims[1], false, 0f, 0f);
+ verify(mockListener, timeout(4000)).onAnimationEnd(springAnims[1], false, 0f, 0f);
if (springAnims[0].isRunning()) {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
diff --git a/emoji/core/src/main/java/androidx/emoji/text/EmojiProcessor.java b/emoji/core/src/main/java/androidx/emoji/text/EmojiProcessor.java
index 574e10a..536eb9b 100644
--- a/emoji/core/src/main/java/androidx/emoji/text/EmojiProcessor.java
+++ b/emoji/core/src/main/java/androidx/emoji/text/EmojiProcessor.java
@@ -450,7 +450,6 @@
*
* @return {@code true} if the OS can render emoji, {@code false} otherwise
*/
- @SuppressWarnings("BanUnlistedSDKVersionComparison")
private boolean hasGlyph(final CharSequence charSequence, int start, final int end,
final EmojiMetadata metadata) {
// For pre M devices, heuristic in PaintCompat can result in false positives. we are
diff --git a/fragment/src/main/java/androidx/fragment/app/BackStackState.java b/fragment/src/main/java/androidx/fragment/app/BackStackState.java
index 3169521..d943b76 100644
--- a/fragment/src/main/java/androidx/fragment/app/BackStackState.java
+++ b/fragment/src/main/java/androidx/fragment/app/BackStackState.java
@@ -16,6 +16,7 @@
package androidx.fragment.app;
+import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -23,7 +24,7 @@
import java.util.ArrayList;
-@SuppressWarnings("BanParcelableUsage")
+@SuppressLint("BanParcelableUsage")
final class BackStackState implements Parcelable {
final int[] mOps;
final ArrayList<String> mFragmentWhos;
diff --git a/fragment/src/main/java/androidx/fragment/app/Fragment.java b/fragment/src/main/java/androidx/fragment/app/Fragment.java
index 688b118..c122d8f 100644
--- a/fragment/src/main/java/androidx/fragment/app/Fragment.java
+++ b/fragment/src/main/java/androidx/fragment/app/Fragment.java
@@ -337,7 +337,6 @@
* through {@link FragmentManager#saveFragmentInstanceState(Fragment)
* FragmentManager.saveFragmentInstanceState}.
*/
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public static class SavedState implements Parcelable {
final Bundle mState;
diff --git a/fragment/src/main/java/androidx/fragment/app/FragmentManagerState.java b/fragment/src/main/java/androidx/fragment/app/FragmentManagerState.java
index 7c13fd5..969c3bc 100644
--- a/fragment/src/main/java/androidx/fragment/app/FragmentManagerState.java
+++ b/fragment/src/main/java/androidx/fragment/app/FragmentManagerState.java
@@ -16,12 +16,13 @@
package androidx.fragment.app;
+import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
-@SuppressWarnings("BanParcelableUsage")
+@SuppressLint("BanParcelableUsage")
final class FragmentManagerState implements Parcelable {
ArrayList<FragmentState> mActive;
ArrayList<String> mAdded;
diff --git a/fragment/src/main/java/androidx/fragment/app/FragmentState.java b/fragment/src/main/java/androidx/fragment/app/FragmentState.java
index 90e7463..e63a4de 100644
--- a/fragment/src/main/java/androidx/fragment/app/FragmentState.java
+++ b/fragment/src/main/java/androidx/fragment/app/FragmentState.java
@@ -24,7 +24,6 @@
import androidx.annotation.NonNull;
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
final class FragmentState implements Parcelable {
final String mClassName;
diff --git a/leanback/src/androidTest/java/androidx/leanback/app/PhotoItem.java b/leanback/src/androidTest/java/androidx/leanback/app/PhotoItem.java
index 8e04727..55244c1 100644
--- a/leanback/src/androidTest/java/androidx/leanback/app/PhotoItem.java
+++ b/leanback/src/androidTest/java/androidx/leanback/app/PhotoItem.java
@@ -22,7 +22,6 @@
/**
* PhotoItem.
*/
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public class PhotoItem implements Parcelable {
private String mTitle;
diff --git a/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java b/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java
index 796df15..aa1f44d 100644
--- a/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java
+++ b/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java
@@ -4672,7 +4672,8 @@
assertEquals(1, mGridView.getSelectedPosition());
}
- @Test
+ // Temporarily disabled due to b/110377468
+ // @Test
public void testAccessibilityBug77292190() throws Throwable {
Intent intent = new Intent();
final int numItems = 1000;
@@ -4908,7 +4909,8 @@
assertEquals(1, mGridView.getSelectedPosition());
}
- @Test
+ // Temporarily disabled due to b/110377468
+ // @Test
public void testAccessibilityRespondToLeftRightInvisible() throws Throwable {
boolean isRTL = false;
boolean isHorizontal = true;
@@ -4917,7 +4919,8 @@
testScrollingAction(isRTL, isHorizontal);
}
- @Test
+ // Temporarily disabled due to b/110377468
+ // @Test
public void testAccessibilityRespondToLeftRightPartiallyVisible() throws Throwable {
boolean isRTL = false;
boolean isHorizontal = true;
@@ -4926,7 +4929,8 @@
testScrollingAction(isRTL, isHorizontal);
}
- @Test
+ // Temporarily disabled due to b/110377468
+ // @Test
public void testAccessibilityRespondToLeftRightRtlInvisible()
throws Throwable {
boolean isRTL = true;
@@ -4936,7 +4940,8 @@
testScrollingAction(isRTL, isHorizontal);
}
- @Test
+ // Temporarily disabled due to b/110377468
+ // @Test
public void testAccessibilityRespondToLeftRightRtlPartiallyVisible() throws Throwable {
boolean isRTL = true;
boolean isHorizontal = true;
@@ -4945,7 +4950,8 @@
testScrollingAction(isRTL, isHorizontal);
}
- @Test
+ // Temporarily disabled due to b/110377468
+ // @Test
public void testAccessibilityRespondToScrollUpDownActionInvisible() throws Throwable {
boolean isRTL = false;
boolean isHorizontal = false;
@@ -4954,7 +4960,8 @@
testScrollingAction(isRTL, isHorizontal);
}
- @Test
+ // Temporarily disabled due to b/110377468
+ // @Test
public void testAccessibilityRespondToScrollUpDownActionPartiallyVisible() throws Throwable {
boolean isRTL = false;
boolean isHorizontal = false;
diff --git a/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java b/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java
index bf1b207..ab6d125 100644
--- a/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java
+++ b/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java
@@ -3597,7 +3597,6 @@
}
}
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
final static class SavedState implements Parcelable {
diff --git a/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java b/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
index 7249fad..69cf852 100644
--- a/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
@@ -453,7 +453,6 @@
* MediaItems are application dependent so we cannot guarantee that they contain the
* right values.
*/
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public static class MediaItem implements Parcelable {
private final int mFlags;
diff --git a/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java b/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java
index b3f0cbb..4fe7886 100644
--- a/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java
+++ b/media/src/main/java/android/support/v4/media/MediaDescriptionCompat.java
@@ -36,7 +36,6 @@
* created using the Builder or retrieved from existing metadata using
* {@link MediaMetadataCompat#getDescription()}.
*/
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public final class MediaDescriptionCompat implements Parcelable {
/**
diff --git a/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java b/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java
index c85276f..f3d7e45 100644
--- a/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java
+++ b/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java
@@ -41,7 +41,6 @@
/**
* Contains metadata about an item, such as the title, artist, etc.
*/
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public final class MediaMetadataCompat implements Parcelable {
private static final String TAG = "MediaMetadata";
diff --git a/media/src/main/java/android/support/v4/media/RatingCompat.java b/media/src/main/java/android/support/v4/media/RatingCompat.java
index 8512fd0..6f8a0b1 100644
--- a/media/src/main/java/android/support/v4/media/RatingCompat.java
+++ b/media/src/main/java/android/support/v4/media/RatingCompat.java
@@ -39,7 +39,6 @@
* be defined as "unrated"), both of which are defined when the rating instance is constructed
* through one of the factory methods.
*/
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public final class RatingCompat implements Parcelable {
private final static String TAG = "Rating";
diff --git a/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java b/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
index 0175b75..a9188e8 100644
--- a/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -1653,7 +1653,7 @@
* owner to allow them to create a {@link MediaControllerCompat} to communicate with
* the session.
*/
- @SuppressWarnings("BanParcelableUsage")
+ @SuppressLint("BanParcelableUsage")
public static final class Token implements Parcelable {
private final Object mInner;
private IMediaSession mExtraBinder;
@@ -1859,7 +1859,6 @@
* A single item that is part of the play queue. It contains a description
* of the item and its id in the queue.
*/
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public static final class QueueItem implements Parcelable {
/**
@@ -2021,7 +2020,6 @@
* @hide
*/
@RestrictTo(LIBRARY)
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public static final class ResultReceiverWrapper implements Parcelable {
ResultReceiver mResultReceiver;
diff --git a/media/src/main/java/android/support/v4/media/session/ParcelableVolumeInfo.java b/media/src/main/java/android/support/v4/media/session/ParcelableVolumeInfo.java
index bb5251b..754552c 100644
--- a/media/src/main/java/android/support/v4/media/session/ParcelableVolumeInfo.java
+++ b/media/src/main/java/android/support/v4/media/session/ParcelableVolumeInfo.java
@@ -15,6 +15,7 @@
package android.support.v4.media.session;
+import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
@@ -22,7 +23,7 @@
* Convenience class for passing information about the audio configuration of a
* {@link MediaSessionCompat}.
*/
-@SuppressWarnings("BanParcelableUsage")
+@SuppressLint("BanParcelableUsage")
public class ParcelableVolumeInfo implements Parcelable {
public int volumeType;
public int audioStream;
diff --git a/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java b/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java
index ce92307..8e88f48 100644
--- a/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java
+++ b/media/src/main/java/android/support/v4/media/session/PlaybackStateCompat.java
@@ -42,7 +42,6 @@
* {@link PlaybackStateCompat#STATE_PLAYING}, the current playback position,
* and the current control capabilities.
*/
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public final class PlaybackStateCompat implements Parcelable {
@@ -880,7 +879,6 @@
* extend the capabilities of the standard transport controls by exposing
* app specific actions to {@link MediaControllerCompat Controllers}.
*/
- @SuppressWarnings("BanParcelableUsage")
public static final class CustomAction implements Parcelable {
private final String mAction;
private final CharSequence mName;
diff --git a/media/version-compat-tests/lib/src/main/java/androidx/media/test/lib/CustomParcelable.java b/media/version-compat-tests/lib/src/main/java/androidx/media/test/lib/CustomParcelable.java
index f23de9e..616eca4 100644
--- a/media/version-compat-tests/lib/src/main/java/androidx/media/test/lib/CustomParcelable.java
+++ b/media/version-compat-tests/lib/src/main/java/androidx/media/test/lib/CustomParcelable.java
@@ -23,7 +23,6 @@
/**
* Custom Parcelable class to test sending/receiving user parcelables between processes.
*/
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public class CustomParcelable implements Parcelable {
diff --git a/media2/src/androidTest/java/androidx/media2/MediaPlayer2StateTest.java b/media2/src/androidTest/java/androidx/media2/MediaPlayer2StateTest.java
index d5b4846..44527f7 100644
--- a/media2/src/androidTest/java/androidx/media2/MediaPlayer2StateTest.java
+++ b/media2/src/androidTest/java/androidx/media2/MediaPlayer2StateTest.java
@@ -904,8 +904,9 @@
{ sGetMetricsOperation, PLAYER_STATE_PLAYING, true },
{ sGetMetricsOperation, PLAYER_STATE_ERROR, false },
- { sSetPlaybackParamsOperation, MEDIAPLAYER2_STATE_IDLE_NO_DATA_SOURCE, true },
- { sSetPlaybackParamsOperation, PLAYER_STATE_IDLE, true },
+ // Temporarily disabled due to b/120095263
+ // { sSetPlaybackParamsOperation, MEDIAPLAYER2_STATE_IDLE_NO_DATA_SOURCE, true },
+ // { sSetPlaybackParamsOperation, PLAYER_STATE_IDLE, true },
{ sSetPlaybackParamsOperation, PLAYER_STATE_PREPARED, true },
{ sSetPlaybackParamsOperation, PLAYER_STATE_PAUSED, true },
{ sSetPlaybackParamsOperation, PLAYER_STATE_PLAYING, true },
@@ -918,8 +919,9 @@
{ sGetPlaybackParamsOperation, PLAYER_STATE_PLAYING, true },
{ sGetPlaybackParamsOperation, PLAYER_STATE_ERROR, false },
- { sGetTimestampOperation, MEDIAPLAYER2_STATE_IDLE_NO_DATA_SOURCE, true },
- { sGetTimestampOperation, PLAYER_STATE_IDLE, true },
+ // Temporarily disabled due to b/120095263
+ // { sGetTimestampOperation, MEDIAPLAYER2_STATE_IDLE_NO_DATA_SOURCE, true },
+ // { sGetTimestampOperation, PLAYER_STATE_IDLE, true },
{ sGetTimestampOperation, PLAYER_STATE_PREPARED, true },
{ sGetTimestampOperation, PLAYER_STATE_PAUSED, true },
{ sGetTimestampOperation, PLAYER_STATE_PLAYING, true },
diff --git a/media2/src/androidTest/java/androidx/media2/MediaPlayer2Test.java b/media2/src/androidTest/java/androidx/media2/MediaPlayer2Test.java
index edddfd3..48c63a0 100644
--- a/media2/src/androidTest/java/androidx/media2/MediaPlayer2Test.java
+++ b/media2/src/androidTest/java/androidx/media2/MediaPlayer2Test.java
@@ -2074,9 +2074,10 @@
* This test assumes the resources being tested are between 8 and 14 seconds long
* The ones being used here are 10 seconds long.
*/
- @Test
- @LargeTest
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+ // This test is disabled due to a framework issue. b/79754424
+ //@Test
+ //@LargeTest
+ //@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
public void testResumeAtEnd() throws Throwable {
int testsRun = testResumeAtEnd(R.raw.loudsoftmp3)
+ testResumeAtEnd(R.raw.loudsoftwav)
diff --git a/media2/src/main/java/androidx/media2/ParcelImplListSlice.java b/media2/src/main/java/androidx/media2/ParcelImplListSlice.java
index 210c461..3a22249 100644
--- a/media2/src/main/java/androidx/media2/ParcelImplListSlice.java
+++ b/media2/src/main/java/androidx/media2/ParcelImplListSlice.java
@@ -42,7 +42,6 @@
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public class ParcelImplListSlice implements Parcelable {
private static final String TAG = "ParcelImplListSlice";
diff --git a/navigation/common/api/1.0.0-alpha09.txt b/navigation/common/api/1.0.0-alpha09.txt
index d5e17ab..4ff23f9 100644
--- a/navigation/common/api/1.0.0-alpha09.txt
+++ b/navigation/common/api/1.0.0-alpha09.txt
@@ -4,18 +4,36 @@
public final class NavAction {
ctor public NavAction(@IdRes int);
ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?);
+ ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?, android.os.Bundle?);
+ method public android.os.Bundle? getDefaultArguments();
method public int getDestinationId();
method public androidx.navigation.NavOptions? getNavOptions();
+ method public void setDefaultArguments(android.os.Bundle?);
method public void setNavOptions(androidx.navigation.NavOptions?);
}
+ public final class NavArgument {
+ method public Object? getDefaultValue();
+ method public androidx.navigation.NavType<?> getType();
+ method public boolean isDefaultValuePresent();
+ method public boolean isNullable();
+ }
+
+ public static final class NavArgument.Builder {
+ ctor public NavArgument.Builder();
+ method public androidx.navigation.NavArgument build();
+ method public androidx.navigation.NavArgument.Builder setDefaultValue(Object?);
+ method public androidx.navigation.NavArgument.Builder setIsNullable(boolean);
+ method public androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<?>);
+ }
+
public class NavDestination {
ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>);
ctor public NavDestination(String);
+ method public final void addArgument(String, androidx.navigation.NavArgument);
method public final void addDeepLink(String);
- method public final void addDefaultArguments(android.os.Bundle);
method public final androidx.navigation.NavAction? getAction(@IdRes int);
- method public final android.os.Bundle getDefaultArguments();
+ method public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> getArguments();
method @IdRes public final int getId();
method public final CharSequence? getLabel();
method public final String getNavigatorName();
@@ -25,7 +43,7 @@
method public final void putAction(@IdRes int, @IdRes int);
method public final void putAction(@IdRes int, androidx.navigation.NavAction);
method public final void removeAction(@IdRes int);
- method public final void setDefaultArguments(android.os.Bundle?);
+ method public final void removeArgument(String);
method public final void setId(@IdRes int);
method public final void setLabel(CharSequence?);
}
@@ -83,6 +101,61 @@
method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int, boolean);
}
+ public abstract class NavType<T> {
+ method public static androidx.navigation.NavType<?> fromArgType(String?, String?);
+ method public abstract T? get(android.os.Bundle, String);
+ method public abstract String getName();
+ method public boolean isNullableAllowed();
+ method public abstract T parseValue(String);
+ method public abstract void put(android.os.Bundle, String, T?);
+ field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Boolean> BoolType;
+ field public static final androidx.navigation.NavType<float[]> FloatArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Float> FloatType;
+ field public static final androidx.navigation.NavType<int[]> IntArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Integer> IntType;
+ field public static final androidx.navigation.NavType<long[]> LongArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Long> LongType;
+ field public static final androidx.navigation.NavType<java.lang.String[]> StringArrayType;
+ field public static final androidx.navigation.NavType<java.lang.String> StringType;
+ }
+
+ public static final class NavType.EnumType<D extends java.lang.Enum> extends androidx.navigation.NavType.SerializableType<D> {
+ ctor public NavType.EnumType(Class<D>);
+ }
+
+ public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
+ ctor public NavType.ParcelableArrayType(Class<D>);
+ method public D[]? get(android.os.Bundle, String);
+ method public String getName();
+ method public D[] parseValue(String);
+ method public void put(android.os.Bundle, String, D[]?);
+ }
+
+ public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
+ ctor public NavType.ParcelableType(Class<D>);
+ method public D? get(android.os.Bundle, String);
+ method public String getName();
+ method public D parseValue(String);
+ method public void put(android.os.Bundle, String, D?);
+ }
+
+ public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
+ ctor public NavType.SerializableArrayType(Class<D>);
+ method public D[]? get(android.os.Bundle, String);
+ method public String getName();
+ method public D[] parseValue(String);
+ method public void put(android.os.Bundle, String, D[]?);
+ }
+
+ public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
+ ctor public NavType.SerializableType(Class<D>);
+ method public D? get(android.os.Bundle, String);
+ method public String getName();
+ method public D parseValue(String);
+ method public void put(android.os.Bundle, String, D?);
+ }
+
public abstract class Navigator<D extends androidx.navigation.NavDestination> {
ctor public Navigator();
method public abstract D createDestination();
diff --git a/navigation/common/api/current.txt b/navigation/common/api/current.txt
index d5e17ab..4ff23f9 100644
--- a/navigation/common/api/current.txt
+++ b/navigation/common/api/current.txt
@@ -4,18 +4,36 @@
public final class NavAction {
ctor public NavAction(@IdRes int);
ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?);
+ ctor public NavAction(@IdRes int, androidx.navigation.NavOptions?, android.os.Bundle?);
+ method public android.os.Bundle? getDefaultArguments();
method public int getDestinationId();
method public androidx.navigation.NavOptions? getNavOptions();
+ method public void setDefaultArguments(android.os.Bundle?);
method public void setNavOptions(androidx.navigation.NavOptions?);
}
+ public final class NavArgument {
+ method public Object? getDefaultValue();
+ method public androidx.navigation.NavType<?> getType();
+ method public boolean isDefaultValuePresent();
+ method public boolean isNullable();
+ }
+
+ public static final class NavArgument.Builder {
+ ctor public NavArgument.Builder();
+ method public androidx.navigation.NavArgument build();
+ method public androidx.navigation.NavArgument.Builder setDefaultValue(Object?);
+ method public androidx.navigation.NavArgument.Builder setIsNullable(boolean);
+ method public androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<?>);
+ }
+
public class NavDestination {
ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>);
ctor public NavDestination(String);
+ method public final void addArgument(String, androidx.navigation.NavArgument);
method public final void addDeepLink(String);
- method public final void addDefaultArguments(android.os.Bundle);
method public final androidx.navigation.NavAction? getAction(@IdRes int);
- method public final android.os.Bundle getDefaultArguments();
+ method public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> getArguments();
method @IdRes public final int getId();
method public final CharSequence? getLabel();
method public final String getNavigatorName();
@@ -25,7 +43,7 @@
method public final void putAction(@IdRes int, @IdRes int);
method public final void putAction(@IdRes int, androidx.navigation.NavAction);
method public final void removeAction(@IdRes int);
- method public final void setDefaultArguments(android.os.Bundle?);
+ method public final void removeArgument(String);
method public final void setId(@IdRes int);
method public final void setLabel(CharSequence?);
}
@@ -83,6 +101,61 @@
method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int, boolean);
}
+ public abstract class NavType<T> {
+ method public static androidx.navigation.NavType<?> fromArgType(String?, String?);
+ method public abstract T? get(android.os.Bundle, String);
+ method public abstract String getName();
+ method public boolean isNullableAllowed();
+ method public abstract T parseValue(String);
+ method public abstract void put(android.os.Bundle, String, T?);
+ field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Boolean> BoolType;
+ field public static final androidx.navigation.NavType<float[]> FloatArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Float> FloatType;
+ field public static final androidx.navigation.NavType<int[]> IntArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Integer> IntType;
+ field public static final androidx.navigation.NavType<long[]> LongArrayType;
+ field public static final androidx.navigation.NavType<java.lang.Long> LongType;
+ field public static final androidx.navigation.NavType<java.lang.String[]> StringArrayType;
+ field public static final androidx.navigation.NavType<java.lang.String> StringType;
+ }
+
+ public static final class NavType.EnumType<D extends java.lang.Enum> extends androidx.navigation.NavType.SerializableType<D> {
+ ctor public NavType.EnumType(Class<D>);
+ }
+
+ public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
+ ctor public NavType.ParcelableArrayType(Class<D>);
+ method public D[]? get(android.os.Bundle, String);
+ method public String getName();
+ method public D[] parseValue(String);
+ method public void put(android.os.Bundle, String, D[]?);
+ }
+
+ public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
+ ctor public NavType.ParcelableType(Class<D>);
+ method public D? get(android.os.Bundle, String);
+ method public String getName();
+ method public D parseValue(String);
+ method public void put(android.os.Bundle, String, D?);
+ }
+
+ public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
+ ctor public NavType.SerializableArrayType(Class<D>);
+ method public D[]? get(android.os.Bundle, String);
+ method public String getName();
+ method public D[] parseValue(String);
+ method public void put(android.os.Bundle, String, D[]?);
+ }
+
+ public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
+ ctor public NavType.SerializableType(Class<D>);
+ method public D? get(android.os.Bundle, String);
+ method public String getName();
+ method public D parseValue(String);
+ method public void put(android.os.Bundle, String, D?);
+ }
+
public abstract class Navigator<D extends androidx.navigation.NavDestination> {
ctor public Navigator();
method public abstract D createDestination();
diff --git a/navigation/common/ktx/api/1.0.0-alpha09.txt b/navigation/common/ktx/api/1.0.0-alpha09.txt
index 503aca4..931b33c 100644
--- a/navigation/common/ktx/api/1.0.0-alpha09.txt
+++ b/navigation/common/ktx/api/1.0.0-alpha09.txt
@@ -25,18 +25,30 @@
property public final int destinationId;
}
+ @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
+ ctor public NavArgumentBuilder();
+ method public androidx.navigation.NavArgument build();
+ method public Object? getDefaultValue();
+ method public boolean getNullable();
+ method public androidx.navigation.NavType<?> getType();
+ method public void setDefaultValue(Object? value);
+ method public void setNullable(boolean value);
+ method public void setType(androidx.navigation.NavType<?> value);
+ property public final Object? defaultValue;
+ property public final boolean nullable;
+ property public final androidx.navigation.NavType<?> type;
+ }
+
@androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
+ method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
method public D build();
method public final void deepLink(String uriPattern);
- method public final android.os.Bundle? getDefaultArguments();
method public final int getId();
method public final CharSequence? getLabel();
method protected final androidx.navigation.Navigator<? extends D> getNavigator();
- method public final void setDefaultArguments(android.os.Bundle? p);
method public final void setLabel(CharSequence? p);
- property public final android.os.Bundle? defaultArguments;
property public final CharSequence? label;
}
diff --git a/navigation/common/ktx/api/current.txt b/navigation/common/ktx/api/current.txt
index 503aca4..931b33c 100644
--- a/navigation/common/ktx/api/current.txt
+++ b/navigation/common/ktx/api/current.txt
@@ -25,18 +25,30 @@
property public final int destinationId;
}
+ @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
+ ctor public NavArgumentBuilder();
+ method public androidx.navigation.NavArgument build();
+ method public Object? getDefaultValue();
+ method public boolean getNullable();
+ method public androidx.navigation.NavType<?> getType();
+ method public void setDefaultValue(Object? value);
+ method public void setNullable(boolean value);
+ method public void setType(androidx.navigation.NavType<?> value);
+ property public final Object? defaultValue;
+ property public final boolean nullable;
+ property public final androidx.navigation.NavType<?> type;
+ }
+
@androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
+ method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
method public D build();
method public final void deepLink(String uriPattern);
- method public final android.os.Bundle? getDefaultArguments();
method public final int getId();
method public final CharSequence? getLabel();
method protected final androidx.navigation.Navigator<? extends D> getNavigator();
- method public final void setDefaultArguments(android.os.Bundle? p);
method public final void setLabel(CharSequence? p);
- property public final android.os.Bundle? defaultArguments;
property public final CharSequence? label;
}
diff --git a/navigation/common/ktx/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt b/navigation/common/ktx/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt
index 1ecc75f..3d30b42 100644
--- a/navigation/common/ktx/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt
+++ b/navigation/common/ktx/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt
@@ -16,7 +16,6 @@
package androidx.navigation
-import android.os.Bundle
import android.support.annotation.IdRes
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
@@ -52,13 +51,33 @@
@Test
fun navDestinationDefaultArguments() {
- val arguments = Bundle()
val destination = provider.navDestination(DESTINATION_ID) {
- defaultArguments = arguments
+ argument("testArg") {
+ defaultValue = "123"
+ type = NavType.StringType
+ }
+ argument("testArg2") {
+ type = NavType.StringType
+ }
}
assertWithMessage("NavDestination should have default arguments set")
- .that(destination.defaultArguments)
- .isEqualTo(arguments)
+ .that(destination.arguments.get("testArg")?.defaultValue)
+ .isEqualTo("123")
+ assertWithMessage("NavArgument shouldn't have a default value")
+ .that(destination.arguments.get("testArg2")?.isDefaultValuePresent)
+ .isFalse()
+ }
+
+ @Test
+ fun navDestinationDefaultArgumentsInferred() {
+ val destination = provider.navDestination(DESTINATION_ID) {
+ argument("testArg") {
+ defaultValue = 123
+ }
+ }
+ assertWithMessage("NavDestination should have default arguments set")
+ .that(destination.arguments.get("testArg")?.defaultValue)
+ .isEqualTo(123)
}
@Test
diff --git a/navigation/common/ktx/src/main/java/androidx/navigation/NavDestinationBuilder.kt b/navigation/common/ktx/src/main/java/androidx/navigation/NavDestinationBuilder.kt
index 9c96bbb..93723e69 100644
--- a/navigation/common/ktx/src/main/java/androidx/navigation/NavDestinationBuilder.kt
+++ b/navigation/common/ktx/src/main/java/androidx/navigation/NavDestinationBuilder.kt
@@ -16,8 +16,8 @@
package androidx.navigation
-import android.os.Bundle
import android.support.annotation.IdRes
+import java.lang.IllegalStateException
@DslMarker
annotation class NavDestinationDsl
@@ -35,10 +35,14 @@
*/
var label: CharSequence? = null
+ private var arguments = mutableMapOf<String, NavArgument>()
+
/**
- * The default arguments that should be passed to the destination
+ * Add a [NavArgument] to this destination.
*/
- var defaultArguments: Bundle? = null
+ fun argument(name: String, argumentBuilder: NavArgumentBuilder.() -> Unit) {
+ arguments[name] = NavArgumentBuilder().apply(argumentBuilder).build()
+ }
private var deepLinks = mutableListOf<String>()
@@ -79,7 +83,9 @@
return navigator.createDestination().also { destination ->
destination.id = id
destination.label = label
- destination.setDefaultArguments(defaultArguments)
+ arguments.forEach { (name, argument) ->
+ destination.addArgument(name, argument)
+ }
deepLinks.forEach { deepLink ->
destination.addDeepLink(deepLink)
}
@@ -111,3 +117,54 @@
internal fun build() = NavAction(destinationId, navOptions)
}
+
+/**
+ * DSL for constructing a new [NavArgument]
+ */
+@NavDestinationDsl
+class NavArgumentBuilder {
+ private val builder = NavArgument.Builder()
+ private var _type: NavType<*>? = null
+
+ /**
+ * Sets the NavType for this argument.
+ *
+ * If you don't set a type explicitly, it will be inferred
+ * from the default value of this argument.
+ */
+ var type: NavType<*>
+ set(value) {
+ _type = value
+ builder.setType(value)
+ }
+ get() {
+ return _type ?: throw IllegalStateException("NavType has not been set on this builder.")
+ }
+
+ /**
+ * Controls if this argument allows null values.
+ */
+ var nullable: Boolean = false
+ set(value) {
+ field = value
+ builder.setIsNullable(value)
+ }
+
+ /**
+ * An optional default value for this argument.
+ *
+ * Any object that you set here must be compatible with [type], if it was specified.
+ */
+ var defaultValue: Any? = null
+ set(value) {
+ field = value
+ builder.setDefaultValue(value)
+ }
+
+ /**
+ * Builds the NavArgument by calling [NavArgument.Builder.build].
+ */
+ fun build(): NavArgument {
+ return builder.build()
+ }
+}
\ No newline at end of file
diff --git a/navigation/common/src/androidTest/java/androidx/navigation/NavArgumentTest.kt b/navigation/common/src/androidTest/java/androidx/navigation/NavArgumentTest.kt
new file mode 100644
index 0000000..7cb8a30
--- /dev/null
+++ b/navigation/common/src/androidTest/java/androidx/navigation/NavArgumentTest.kt
@@ -0,0 +1,66 @@
+/*
+ * 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 androidx.navigation
+
+import android.os.Bundle
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+@SmallTest
+class NavArgumentTest {
+ @Test
+ fun putDefaultValue() {
+ val bundle = Bundle()
+ val argument = NavArgument.Builder()
+ .setDefaultValue("abc")
+ .setType(NavType.StringType)
+ .build()
+ argument.putDefaultValue("name", bundle)
+ assertThat(bundle.get("name"))
+ .isEqualTo("abc")
+ }
+
+ @Test
+ fun verify() {
+ val bundle = Bundle().apply {
+ putString("stringArg", "abc")
+ putInt("intArg", 123)
+ putIntArray("intArrayArg", null)
+ }
+
+ val stringArgument = NavArgument.Builder()
+ .setType(NavType.StringType)
+ .build()
+ val intArgument = NavArgument.Builder()
+ .setType(NavType.IntType)
+ .build()
+ val intArrArgument = NavArgument.Builder()
+ .setType(NavType.IntArrayType)
+ .setIsNullable(true)
+ .build()
+ val intArrNonNullArgument = NavArgument.Builder()
+ .setType(NavType.IntArrayType)
+ .setIsNullable(false)
+ .build()
+
+ assertThat(stringArgument.verify("stringArg", bundle)).isTrue()
+ assertThat(intArgument.verify("intArg", bundle)).isTrue()
+ assertThat(intArrArgument.verify("intArrayArg", bundle)).isTrue()
+ assertThat(intArrNonNullArgument.verify("intArrayArg", bundle)).isFalse()
+ }
+}
diff --git a/navigation/common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt b/navigation/common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt
new file mode 100644
index 0000000..7add5cf
--- /dev/null
+++ b/navigation/common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt
@@ -0,0 +1,65 @@
+/*
+ * 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 androidx.navigation
+
+import android.os.Bundle
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+@SmallTest
+class NavDestinationAndroidTest {
+ @Test
+ fun addInDefaultArgs() {
+ val destination = NoOpNavigator().createDestination()
+ val stringArgument = NavArgument.Builder()
+ .setType(NavType.StringType)
+ .setDefaultValue("aaa")
+ .build()
+ val intArgument = NavArgument.Builder()
+ .setType(NavType.IntType)
+ .setDefaultValue(123)
+ .build()
+ destination.addArgument("stringArg", stringArgument)
+ destination.addArgument("intArg", intArgument)
+
+ val bundle = destination.addInDefaultArgs(Bundle().apply {
+ putString("stringArg", "bbb")
+ })
+ assertThat(bundle?.getString("stringArg")).isEqualTo("bbb")
+ assertThat(bundle?.getInt("intArg")).isEqualTo(123)
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun addInDefaultArgsWrong() {
+ val destination = NoOpNavigator().createDestination()
+ val stringArgument = NavArgument.Builder()
+ .setType(NavType.StringType)
+ .setDefaultValue("aaa")
+ .build()
+ val intArgument = NavArgument.Builder()
+ .setType(NavType.IntType)
+ .setDefaultValue(123)
+ .build()
+ destination.addArgument("stringArg", stringArgument)
+ destination.addArgument("intArg", intArgument)
+
+ destination.addInDefaultArgs(Bundle().apply {
+ putInt("stringArg", 123)
+ })
+ }
+}
diff --git a/navigation/common/src/androidTest/java/androidx/navigation/NavTypeTest.kt b/navigation/common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
new file mode 100644
index 0000000..7243c4f
--- /dev/null
+++ b/navigation/common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
@@ -0,0 +1,224 @@
+/*
+ * 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 androidx.navigation
+
+import android.content.pm.ActivityInfo
+import android.graphics.Bitmap
+import android.os.Bundle
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import java.io.Serializable
+
+@SmallTest
+class NavTypeTest {
+
+ private class Person : Serializable {
+ var field: Int = 0
+ }
+
+ companion object {
+ private val i = 1
+ private val ints = intArrayOf(0, 1)
+ private val l = 1L
+ private val longs = longArrayOf(0L, 1L)
+ private val fl = 1.5f
+ private val floats = floatArrayOf(1f, 2.5f)
+ private val b = true
+ private val booleans = booleanArrayOf(b, false)
+ private val s = "a_string"
+ private val strings = arrayOf("aa", "bb")
+ private val parcelable = ActivityInfo()
+ private val parcelables = arrayOf(parcelable)
+ private val en = Bitmap.Config.ALPHA_8
+ private val serializable = Person()
+ private val serializables = arrayOf(Bitmap.Config.ALPHA_8)
+ private val parcelableNavType = NavType.ParcelableType(ActivityInfo::class.java)
+ private val parcelableArrayNavType =
+ NavType.ParcelableArrayType(ActivityInfo::class.java)
+ private val serializableNavType = NavType.SerializableType(Person::class.java)
+ private val enumNavType = NavType.EnumType(Bitmap.Config::class.java)
+ private val serializableArrayNavType =
+ NavType.SerializableArrayType(Bitmap.Config::class.java)
+ }
+
+ @Test
+ fun fromArgType() {
+ assertThat(NavType.fromArgType("integer", null))
+ .isEqualTo(NavType.IntType)
+ assertThat(NavType.fromArgType("integer[]", null))
+ .isEqualTo(NavType.IntArrayType)
+ assertThat(NavType.fromArgType("long", null))
+ .isEqualTo(NavType.LongType)
+ assertThat(NavType.fromArgType("long[]", null))
+ .isEqualTo(NavType.LongArrayType)
+ assertThat(NavType.fromArgType("float", null))
+ .isEqualTo(NavType.FloatType)
+ assertThat(NavType.fromArgType("float[]", null))
+ .isEqualTo(NavType.FloatArrayType)
+ assertThat(NavType.fromArgType("boolean", null))
+ .isEqualTo(NavType.BoolType)
+ assertThat(NavType.fromArgType("boolean[]", null))
+ .isEqualTo(NavType.BoolArrayType)
+ assertThat(NavType.fromArgType("string", null))
+ .isEqualTo(NavType.StringType)
+ assertThat(NavType.fromArgType("string[]", null))
+ .isEqualTo(NavType.StringArrayType)
+ assertThat(NavType.fromArgType("android.content.pm.ActivityInfo", null))
+ .isEqualTo(parcelableNavType)
+ assertThat(NavType.fromArgType("android.content.pm.ActivityInfo[]", null))
+ .isEqualTo(parcelableArrayNavType)
+ assertThat(NavType.fromArgType("androidx.navigation.NavTypeTest\$Person", null))
+ .isEqualTo(serializableNavType)
+ assertThat(NavType.fromArgType("android.graphics.Bitmap\$Config", null))
+ .isEqualTo(enumNavType)
+ assertThat(NavType.fromArgType("android.graphics.Bitmap\$Config[]", null))
+ .isEqualTo(serializableArrayNavType)
+ assertThat(NavType.fromArgType(null, null))
+ .isEqualTo(NavType.StringType)
+ }
+
+ @Test
+ fun inferFromValue() {
+ assertThat(NavType.inferFromValue("stringvalue"))
+ .isEqualTo(NavType.StringType)
+ assertThat(NavType.inferFromValue("123"))
+ .isEqualTo(NavType.IntType)
+ assertThat(NavType.inferFromValue("123L"))
+ .isEqualTo(NavType.LongType)
+ assertThat(NavType.inferFromValue("1.5"))
+ .isEqualTo(NavType.FloatType)
+ assertThat(NavType.inferFromValue("true"))
+ .isEqualTo(NavType.BoolType)
+ }
+
+ @Test
+ fun inferFromValueType() {
+ assertThat(NavType.inferFromValueType(i))
+ .isEqualTo(NavType.IntType)
+ assertThat(NavType.inferFromValueType(ints))
+ .isEqualTo(NavType.IntArrayType)
+ assertThat(NavType.inferFromValueType(l))
+ .isEqualTo(NavType.LongType)
+ assertThat(NavType.inferFromValueType(longs))
+ .isEqualTo(NavType.LongArrayType)
+ assertThat(NavType.inferFromValueType(fl))
+ .isEqualTo(NavType.FloatType)
+ assertThat(NavType.inferFromValueType(floats))
+ .isEqualTo(NavType.FloatArrayType)
+ assertThat(NavType.inferFromValueType(b))
+ .isEqualTo(NavType.BoolType)
+ assertThat(NavType.inferFromValueType(booleans))
+ .isEqualTo(NavType.BoolArrayType)
+ assertThat(NavType.inferFromValueType(s))
+ .isEqualTo(NavType.StringType)
+ assertThat(NavType.inferFromValueType(strings))
+ .isEqualTo(NavType.StringArrayType)
+ assertThat(NavType.inferFromValueType(parcelable))
+ .isEqualTo(parcelableNavType)
+ assertThat(NavType.inferFromValueType(parcelables))
+ .isEqualTo(parcelableArrayNavType)
+ assertThat(NavType.inferFromValueType(en))
+ .isEqualTo(enumNavType)
+ assertThat(NavType.inferFromValueType(serializable))
+ .isEqualTo(serializableNavType)
+ assertThat(NavType.inferFromValueType(serializables))
+ .isEqualTo(serializableArrayNavType)
+ assertThat(NavType.inferFromValueType(null))
+ .isEqualTo(NavType.StringType)
+ }
+
+ @Test
+ fun putAndGetFromBundle() {
+ val key = "key"
+ val bundle = Bundle()
+ NavType.IntType.put(bundle, key, i)
+ assertThat(NavType.IntType.get(bundle, key))
+ .isEqualTo(i)
+ bundle.clear()
+
+ NavType.IntArrayType.put(bundle, key, ints)
+ assertThat(NavType.IntArrayType.get(bundle, key))
+ .isEqualTo(ints)
+ bundle.clear()
+
+ NavType.LongType.put(bundle, key, l)
+ assertThat(NavType.LongType.get(bundle, key))
+ .isEqualTo(l)
+ bundle.clear()
+
+ NavType.LongArrayType.put(bundle, key, longs)
+ assertThat(NavType.LongArrayType.get(bundle, key))
+ .isEqualTo(longs)
+ bundle.clear()
+
+ NavType.FloatType.put(bundle, key, fl)
+ assertThat(NavType.FloatType.get(bundle, key))
+ .isEqualTo(fl)
+ bundle.clear()
+
+ NavType.FloatArrayType.put(bundle, key, floats)
+ assertThat(NavType.FloatArrayType.get(bundle, key))
+ .isEqualTo(floats)
+ bundle.clear()
+
+ NavType.BoolType.put(bundle, key, b)
+ assertThat(NavType.BoolType.get(bundle, key))
+ .isEqualTo(b)
+ bundle.clear()
+
+ NavType.BoolArrayType.put(bundle, key, booleans)
+ assertThat(NavType.BoolArrayType.get(bundle, key))
+ .isEqualTo(booleans)
+ bundle.clear()
+
+ NavType.StringType.put(bundle, key, s)
+ assertThat(NavType.StringType.get(bundle, key))
+ .isEqualTo(s)
+ bundle.clear()
+
+ NavType.StringArrayType.put(bundle, key, strings)
+ assertThat(NavType.StringArrayType.get(bundle, key))
+ .isEqualTo(strings)
+ bundle.clear()
+
+ parcelableNavType.put(bundle, key, parcelable)
+ assertThat(parcelableNavType.get(bundle, key))
+ .isEqualTo(parcelable)
+ bundle.clear()
+
+ parcelableArrayNavType.put(bundle, key, parcelables)
+ assertThat(parcelableArrayNavType.get(bundle, key))
+ .isEqualTo(parcelables)
+ bundle.clear()
+
+ enumNavType.put(bundle, key, en)
+ assertThat(enumNavType.get(bundle, key))
+ .isEqualTo(en)
+ bundle.clear()
+
+ serializableNavType.put(bundle, key, serializable)
+ assertThat(serializableNavType.get(bundle, key))
+ .isEqualTo(serializable)
+ bundle.clear()
+
+ serializableArrayNavType.put(bundle, key, serializables)
+ assertThat(serializableArrayNavType.get(bundle, key))
+ .isEqualTo(serializables)
+ bundle.clear()
+ }
+}
diff --git a/navigation/common/src/main/java/androidx/navigation/NavAction.java b/navigation/common/src/main/java/androidx/navigation/NavAction.java
index 009e586..795d78b 100644
--- a/navigation/common/src/main/java/androidx/navigation/NavAction.java
+++ b/navigation/common/src/main/java/androidx/navigation/NavAction.java
@@ -36,6 +36,7 @@
@IdRes
private final int mDestinationId;
private NavOptions mNavOptions;
+ private Bundle mDefaultArguments;
/**
* Creates a new NavAction for the given destination.
@@ -55,8 +56,23 @@
* @param navOptions special options for this action that should be used by default
*/
public NavAction(@IdRes int destinationId, @Nullable NavOptions navOptions) {
+ this(destinationId, navOptions, null);
+ }
+
+ /**
+ * Creates a new NavAction for the given destination.
+ *
+ * @param destinationId the ID of the destination that should be navigated to when this
+ * action is used.
+ * @param navOptions special options for this action that should be used by default
+ * @param defaultArgs argument bundle to be used by default
+ */
+ public NavAction(@IdRes int destinationId,
+ @Nullable NavOptions navOptions,
+ @Nullable Bundle defaultArgs) {
mDestinationId = destinationId;
mNavOptions = navOptions;
+ mDefaultArguments = defaultArgs;
}
/**
@@ -82,4 +98,22 @@
public NavOptions getNavOptions() {
return mNavOptions;
}
+
+ /**
+ * Gets the argument bundle to be used by default when navigating to this action.
+ * @return bundle of default argument values
+ */
+ @Nullable
+ public Bundle getDefaultArguments() {
+ return mDefaultArguments;
+ }
+
+ /**
+ * Sets the argument bundle to be used by default when navigating to this action.
+ *
+ * @param defaultArgs argument bundle that should be used by default
+ */
+ public void setDefaultArguments(@Nullable Bundle defaultArgs) {
+ mDefaultArguments = defaultArgs;
+ }
}
diff --git a/navigation/common/src/main/java/androidx/navigation/NavArgument.java b/navigation/common/src/main/java/androidx/navigation/NavArgument.java
new file mode 100644
index 0000000..6e7832a
--- /dev/null
+++ b/navigation/common/src/main/java/androidx/navigation/NavArgument.java
@@ -0,0 +1,198 @@
+/*
+ * 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 androidx.navigation;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+/**
+ * NavArgument denotes an argument that is supported by a {@link NavDestination}.
+ * <p>
+ * A NavArgument has a type and optionally a default value, that are used to read/write
+ * it in a Bundle. It can also be nullable if the type supports it.
+ */
+public final class NavArgument {
+ @NonNull
+ private final NavType mType;
+ private final boolean mIsNullable;
+ private final boolean mDefaultValuePresent;
+ @Nullable
+ private final Object mDefaultValue;
+
+ NavArgument(@NonNull NavType<?> type,
+ boolean isNullable,
+ @Nullable Object defaultValue,
+ boolean defaultValuePresent) {
+ if (!type.isNullableAllowed() && isNullable) {
+ throw new IllegalArgumentException(type.getName() + " does not allow nullable values");
+ }
+
+ if (!isNullable && defaultValuePresent && defaultValue == null) {
+ throw new IllegalArgumentException("Argument with type " + type.getName()
+ + " has null value but is not nullable.");
+ }
+
+ this.mType = type;
+ this.mIsNullable = isNullable;
+ this.mDefaultValue = defaultValue;
+ this.mDefaultValuePresent = defaultValuePresent;
+ }
+
+ /**
+ * This method can be used to distinguish between a default value of `null` and an argument
+ * without an explicit default value.
+ * @return true if this argument has a default value (even if that value is set to null),
+ * false otherwise
+ */
+ public boolean isDefaultValuePresent() {
+ return mDefaultValuePresent;
+ }
+
+ /**
+ * Get the type of this NavArgument.
+ * @return the NavType object denoting the type that can be help in this argument.
+ */
+ @NonNull
+ public NavType<?> getType() {
+ return mType;
+ }
+
+ /**
+ * Check if this argument allows passing a `null` value.
+ * @return true if `null` is allowed, false otherwise
+ */
+ public boolean isNullable() {
+ return mIsNullable;
+ }
+
+ /**
+ * Returns the default value of this argument or `null` if it doesn't have a default value.
+ * Use {@link #isDefaultValuePresent()} to distinguish between `null` and absence of a value.
+ * @return The deafult value assigned to this argument.
+ */
+ @Nullable
+ public Object getDefaultValue() {
+ return mDefaultValue;
+ }
+
+ @SuppressWarnings("unchecked")
+ void putDefaultValue(@NonNull String name, @NonNull Bundle bundle) {
+ if (mDefaultValuePresent) {
+ mType.put(bundle, name, mDefaultValue);
+ }
+ }
+
+ boolean verify(@NonNull String name, @NonNull Bundle bundle) {
+ if (!mIsNullable && bundle.containsKey(name) && bundle.get(name) == null) {
+ return false;
+ }
+ try {
+ mType.get(bundle, name);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ NavArgument that = (NavArgument) o;
+
+ if (mIsNullable != that.mIsNullable) return false;
+ if (mDefaultValuePresent != that.mDefaultValuePresent) return false;
+ if (!mType.equals(that.mType)) return false;
+ return mDefaultValue != null ? mDefaultValue.equals(that.mDefaultValue)
+ : that.mDefaultValue == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = mType.hashCode();
+ result = 31 * result + (mIsNullable ? 1 : 0);
+ result = 31 * result + (mDefaultValuePresent ? 1 : 0);
+ result = 31 * result + (mDefaultValue != null ? mDefaultValue.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * A builder for constructing {@link NavArgument} instances.
+ */
+ public static final class Builder {
+ @Nullable
+ private NavType<?> mType;
+ private boolean mIsNullable = false;
+ @Nullable
+ private Object mDefaultValue;
+ private boolean mDefaultValuePresent = false;
+
+ /**
+ * Set the type of the argument.
+ * @param type Type of the argument.
+ * @return This builder.
+ */
+ @NonNull
+ public Builder setType(@NonNull NavType<?> type) {
+ mType = type;
+ return this;
+ }
+
+ /**
+ * Specify if the argument is nullable.
+ * The NavType you set for this argument must allow nullable values.
+ * @param isNullable Argument will be nullable if true.
+ * @return This builder.
+ * @see NavType#isNullableAllowed()
+ */
+ @NonNull
+ public Builder setIsNullable(boolean isNullable) {
+ mIsNullable = isNullable;
+ return this;
+ }
+
+ /**
+ * Specify the default value for an argument. Calling this at least once will cause the
+ * argument to have a default value, even if it is set to null.
+ * @param defaultValue Default value for this argument.
+ * Must match NavType if it is specified.
+ * @return This builder.
+ */
+ @NonNull
+ public Builder setDefaultValue(@Nullable Object defaultValue) {
+ mDefaultValue = defaultValue;
+ mDefaultValuePresent = true;
+ return this;
+ }
+
+ /**
+ * Build the NavArgument specified by this builder.
+ * If the type is not set, the builder will infer the type from the default argument value.
+ * If there is no default value, the type will be unspecified.
+ * @return the newly constructed NavArgument.
+ */
+ @NonNull
+ public NavArgument build() {
+ if (mType == null) {
+ mType = NavType.inferFromValueType(mDefaultValue);
+ }
+ return new NavArgument(mType, mIsNullable, mDefaultValue, mDefaultValuePresent);
+ }
+ }
+}
diff --git a/navigation/common/src/main/java/androidx/navigation/NavDestination.java b/navigation/common/src/main/java/androidx/navigation/NavDestination.java
index 1955454..92c497b 100644
--- a/navigation/common/src/main/java/androidx/navigation/NavDestination.java
+++ b/navigation/common/src/main/java/androidx/navigation/NavDestination.java
@@ -39,7 +39,9 @@
import java.lang.annotation.Target;
import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Map;
/**
* NavDestination represents one node within an overall navigation graph.
@@ -135,9 +137,24 @@
private int mId;
private String mIdName;
private CharSequence mLabel;
- private Bundle mDefaultArgs;
private ArrayList<NavDeepLink> mDeepLinks;
private SparseArrayCompat<NavAction> mActions;
+ private HashMap<String, NavArgument> mArguments;
+
+ /**
+ * Get the arguments supported by this destination. Returns a read-only map of argument names
+ * to {@link NavArgument} objects that can be used to check the type, default value
+ * and nullability of the argument.
+ * <p>
+ * To add and remove arguments for this NavDestination
+ * use {@link #addArgument(String, NavArgument)} and {@link #removeArgument(String)}.
+ * @return Read-only map of argument names to arguments.
+ */
+ @NonNull
+ public final Map<String, NavArgument> getArguments() {
+ return mArguments == null ? Collections.<String, NavArgument>emptyMap()
+ : Collections.unmodifiableMap(mArguments);
+ }
/**
* NavDestinations should be created via {@link Navigator#createDestination}.
@@ -243,38 +260,6 @@
}
/**
- * Returns the destination's default arguments bundle.
- *
- * @return the default arguments bundle
- */
- @NonNull
- public final Bundle getDefaultArguments() {
- if (mDefaultArgs == null) {
- mDefaultArgs = new Bundle();
- }
- return mDefaultArgs;
- }
-
- /**
- * Sets the destination's default arguments bundle.
- *
- * @param args the new bundle to set
- */
- public final void setDefaultArguments(@Nullable Bundle args) {
- mDefaultArgs = args;
- }
-
- /**
- * Merges a bundle of arguments into the current default arguments for this destination.
- * New values with the same keys will replace old values with those keys.
- *
- * @param args arguments to add
- */
- public final void addDefaultArguments(@NonNull Bundle args) {
- getDefaultArguments().putAll(args);
- }
-
- /**
* Add a deep link to this destination. Matching Uris sent to
* {@link NavController#handleDeepLink(Intent)} will trigger navigating to this destination.
* <p>
@@ -422,21 +407,58 @@
}
/**
- * Combines the {@link #getDefaultArguments()} with the arguments provided
+ * Sets an argument type for an argument name
+ *
+ * @param argumentName argument object to associate with destination
+ */
+ public final void addArgument(@NonNull String argumentName, @NonNull NavArgument argument) {
+ if (mArguments == null) {
+ mArguments = new HashMap<>();
+ }
+ mArguments.put(argumentName, argument);
+ }
+
+ /**
+ * Unsets the argument type for an argument name.
+ *
+ * @param argumentName argument to remove
+ */
+ public final void removeArgument(@NonNull String argumentName) {
+ if (mArguments == null) {
+ return;
+ }
+ mArguments.remove(argumentName);
+ }
+
+ /**
+ * Combines the default arguments for this destination with the arguments provided
* to construct the final set of arguments that should be used to navigate
* to this destination.
*/
@Nullable
Bundle addInDefaultArgs(@Nullable Bundle args) {
- Bundle defaultArgs = getDefaultArguments();
+ Bundle defaultArgs = new Bundle();
+ if (mArguments != null) {
+ for (Map.Entry<String, NavArgument> argument : mArguments.entrySet()) {
+ argument.getValue().putDefaultValue(argument.getKey(), defaultArgs);
+ }
+ }
if (args == null && defaultArgs.isEmpty()) {
return null;
}
- Bundle finalArgs = new Bundle();
- finalArgs.putAll(defaultArgs);
if (args != null) {
- finalArgs.putAll(args);
+ defaultArgs.putAll(args);
+ if (mArguments != null) {
+ for (Map.Entry<String, NavArgument> argument : mArguments.entrySet()) {
+ if (!argument.getValue().verify(argument.getKey(), args)) {
+ throw new IllegalArgumentException(
+ "Wrong argument type for '" + argument.getKey()
+ + "' in argument bundle. "
+ + argument.getValue().getType().getName() + " expected.");
+ }
+ }
+ }
}
- return finalArgs;
+ return defaultArgs;
}
}
diff --git a/navigation/common/src/main/java/androidx/navigation/NavType.java b/navigation/common/src/main/java/androidx/navigation/NavType.java
new file mode 100644
index 0000000..58bbbcd
--- /dev/null
+++ b/navigation/common/src/main/java/androidx/navigation/NavType.java
@@ -0,0 +1,941 @@
+/*
+ * 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 androidx.navigation;
+
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.io.Serializable;
+import java.text.ParseException;
+
+/**
+ * NavType denotes the type that can be used in a {@link NavArgument}.
+ * <p>
+ * There are built-in NavTypes for primitive types, such as int, long, boolean, float, and
+ * strings, parcelable, and serializable classes (including Enums), as well as arrays of
+ * each supported type.
+ * <p>
+ * You should only use one of the static NavType instances and subclasses
+ * defined in this class.
+ *
+ * @param <T> the type of the data that is supported by this NavType
+ */
+public abstract class NavType<T> {
+ private final boolean mNullableAllowed;
+
+ NavType(boolean nullableAllowed) {
+ this.mNullableAllowed = nullableAllowed;
+ }
+
+ /**
+ * Check if an argument with this type can hold a null value.
+ * @return Returns true if this type allows null values, false otherwise.
+ */
+ public boolean isNullableAllowed() {
+ return mNullableAllowed;
+ }
+
+ /**
+ * Put a value of this type in he {@code bundle}
+ *
+ * @param bundle bundle to put value in
+ * @param key bundle key
+ * @param value value of this type
+ */
+ public abstract void put(@NonNull Bundle bundle, @NonNull String key, @Nullable T value);
+
+ /**
+ * Get a value of this type from the {@code bundle}
+ *
+ * @param bundle bundle to get value from
+ * @param key bundle key
+ * @return value of this type
+ */
+ @Nullable
+ public abstract T get(@NonNull Bundle bundle, @NonNull String key);
+
+ /**
+ * Parse a value of this type from a String.
+ *
+ * @param value string representation of a value of this type
+ * @return parsed value of the type represented by this NavType
+ * @throws IllegalArgumentException if value cannot be parsed into this type
+ */
+ @NonNull
+ public abstract T parseValue(@NonNull String value);
+
+ /**
+ * Parse a value of this type from a String and put it in a {@code bundle}
+ *
+ * @param bundle bundle to put value in
+ * @param key bundle key under which to put the value
+ * @param value parsed value
+ * @return parsed value of the type represented by this NavType
+ * @throws ParseException if value cannot be parsed into this type
+ */
+ @NonNull
+ T parseAndPut(@NonNull Bundle bundle, @NonNull String key, @NonNull String value) {
+ T parsedValue = parseValue(value);
+ put(bundle, key, parsedValue);
+ return parsedValue;
+ }
+
+ /**
+ * Returns the name of this type.
+ * <p>
+ * This is the same value that is used in Navigation XML <code>argType</code> attribute.
+ *
+ * @return name of this type
+ */
+ @NonNull
+ public abstract String getName();
+
+ @Override
+ @NonNull
+ public String toString() {
+ return getName();
+ }
+
+ /**
+ * Parse an argType string into a NavType.
+ *
+ * @param type argType string, usually parsed from the Navigation XML file
+ * @param packageName package name of the R file,
+ * used for parsing relative class names starting with a dot.
+ * @return a NavType representing the type indicated by the argType string.
+ * Defaults to StringType for null.
+ */
+ @SuppressWarnings("unchecked")
+ @NonNull
+ public static NavType<?> fromArgType(@Nullable String type, @Nullable String packageName) {
+ if (IntType.getName().equals(type) || "reference".equals(type)) {
+ return IntType;
+ } else if (IntArrayType.getName().equals(type)) {
+ return IntArrayType;
+ } else if (LongType.getName().equals(type)) {
+ return LongType;
+ } else if (LongArrayType.getName().equals(type)) {
+ return LongArrayType;
+ } else if (BoolType.getName().equals(type)) {
+ return BoolType;
+ } else if (BoolArrayType.getName().equals(type)) {
+ return BoolArrayType;
+ } else if (StringType.getName().equals(type)) {
+ return StringType;
+ } else if (StringArrayType.getName().equals(type)) {
+ return StringArrayType;
+ } else if (FloatType.getName().equals(type)) {
+ return FloatType;
+ } else if (FloatArrayType.getName().equals(type)) {
+ return FloatArrayType;
+ } else if (type != null && !type.isEmpty()) {
+ try {
+ String className;
+ if (type.startsWith(".") && packageName != null) {
+ className = packageName + type;
+ } else {
+ className = type;
+ }
+
+ if (type.endsWith("[]")) {
+ className = className.substring(0, className.length() - 2);
+ Class clazz = Class.forName(className);
+ if (Parcelable.class.isAssignableFrom(clazz)) {
+ return new ParcelableArrayType(clazz);
+ } else if (Serializable.class.isAssignableFrom(clazz)) {
+ return new SerializableArrayType(clazz);
+ }
+ } else {
+ Class clazz = Class.forName(className);
+ if (Parcelable.class.isAssignableFrom(clazz)) {
+ return new ParcelableType(clazz);
+ } else if (Enum.class.isAssignableFrom(clazz)) {
+ return new EnumType(clazz);
+ } else if (Serializable.class.isAssignableFrom(clazz)) {
+ return new SerializableType(clazz);
+ }
+ }
+ throw new IllegalArgumentException(className + " is not Serializable or "
+ + "Parcelable.");
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return StringType;
+ }
+
+ @NonNull
+ static NavType inferFromValue(@NonNull String value) {
+ //because we allow Long literals without the L suffix at runtime,
+ //the order of IntType and LongType parsing has to be reversed compared to Safe Args
+ try {
+ IntType.parseValue(value);
+ return IntType;
+ } catch (IllegalArgumentException e) {
+ //ignored, proceed to check next type
+ }
+ try {
+ LongType.parseValue(value);
+ return LongType;
+ } catch (IllegalArgumentException e) {
+ //ignored, proceed to check next type
+ }
+
+ try {
+ FloatType.parseValue(value);
+ return FloatType;
+ } catch (IllegalArgumentException e) {
+ //ignored, proceed to check next type
+ }
+
+ try {
+ BoolType.parseValue(value);
+ return BoolType;
+ } catch (IllegalArgumentException e) {
+ //ignored, proceed to check next type
+ }
+
+ return StringType;
+ }
+
+ @SuppressWarnings("unchecked")
+ @NonNull
+ static NavType inferFromValueType(@Nullable Object value) {
+ if (value instanceof Integer) {
+ return IntType;
+ } else if (value instanceof int[]) {
+ return IntArrayType;
+ } else if (value instanceof Long) {
+ return LongType;
+ } else if (value instanceof long[]) {
+ return LongArrayType;
+ } else if (value instanceof Float) {
+ return FloatType;
+ } else if (value instanceof float[]) {
+ return FloatArrayType;
+ } else if (value instanceof Boolean) {
+ return BoolType;
+ } else if (value instanceof boolean[]) {
+ return BoolArrayType;
+ } else if (value instanceof String || value == null) {
+ return StringType;
+ } else if (value instanceof String[]) {
+ return StringArrayType;
+ } else if (value.getClass().isArray() && (
+ Parcelable.class.isAssignableFrom(value.getClass().getComponentType()))) {
+ return new ParcelableArrayType(value.getClass().getComponentType());
+ } else if (value.getClass().isArray() && (
+ Serializable.class.isAssignableFrom(value.getClass().getComponentType()))) {
+ return new SerializableArrayType(value.getClass().getComponentType());
+ } else if (value instanceof Parcelable) {
+ return new ParcelableType(value.getClass());
+ } else if (value instanceof Enum) {
+ return new EnumType(value.getClass());
+ } else if (value instanceof Serializable) {
+ return new SerializableType(value.getClass());
+ } else {
+ throw new IllegalArgumentException("Object of type " + value.getClass().getName()
+ + " is not supported for navigation arguments.");
+ }
+ }
+
+ /**
+ * NavType for storing integer values,
+ * corresponding with the "integer" type in a Navigation XML file.
+ * <p>
+ * Null values are not supported.
+ */
+ @NonNull
+ public static final NavType<Integer> IntType = new NavType<Integer>(false) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Integer value) {
+ bundle.putInt(key, value);
+ }
+
+ @Override
+ public Integer get(@NonNull Bundle bundle, @NonNull String key) {
+ return (Integer) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public Integer parseValue(@NonNull String value) {
+ if (value.startsWith("0x")) {
+ return Integer.parseInt(value.substring(2), 16);
+ } else {
+ return Integer.parseInt(value);
+ }
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "integer";
+ }
+ };
+
+ /**
+ * NavType for storing integer arrays,
+ * corresponding with the "integer[]" type in a Navigation XML file.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ */
+ @NonNull
+ public static final NavType<int[]> IntArrayType = new NavType<int[]>(true) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable int[] value) {
+ bundle.putIntArray(key, value);
+ }
+
+ @Override
+ public int[] get(@NonNull Bundle bundle, @NonNull String key) {
+ return (int[]) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public int[] parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Arrays don't support default values.");
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "integer[]";
+ }
+ };
+
+ /**
+ * NavType for storing long values,
+ * corresponding with the "long" type in a Navigation XML file.
+ * <p>
+ * Null values are not supported.
+ * Default values for this type in Navigation XML files must always end with an 'L' suffix, e.g.
+ * `app:defaultValue="123L"`.
+ */
+ @NonNull
+ public static final NavType<Long> LongType = new NavType<Long>(false) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Long value) {
+ bundle.putLong(key, value);
+ }
+
+ @Override
+ public Long get(@NonNull Bundle bundle, @NonNull String key) {
+ return (Long) bundle.get(key);
+ }
+
+ @NonNull
+ public Long parseValue(@NonNull String value) {
+ //At runtime the L suffix is optional, contrary to the Safe Args plugin.
+ //This is in order to be able to parse long numbers passed as deep link URL parameters
+ if (value.endsWith("L")) {
+ value = value.substring(0, value.length() - 1);
+ }
+ if (value.startsWith("0x")) {
+ return Long.parseLong(value.substring(2), 16);
+ } else {
+ return Long.parseLong(value);
+ }
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "long";
+ }
+ };
+
+ /**
+ * NavType for storing long arrays,
+ * corresponding with the "long[]" type in a Navigation XML file.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ */
+ @NonNull
+ public static final NavType<long[]> LongArrayType = new NavType<long[]>(true) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable long[] value) {
+ bundle.putLongArray(key, value);
+ }
+
+ @Override
+ public long[] get(@NonNull Bundle bundle, @NonNull String key) {
+ return (long[]) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public long[] parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Arrays don't support default values.");
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "long[]";
+ }
+ };
+
+ /**
+ * NavType for storing float values,
+ * corresponding with the "float" type in a Navigation XML file.
+ * <p>
+ * Null values are not supported.
+ */
+ @NonNull
+ public static final NavType<Float> FloatType = new NavType<Float>(false) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Float value) {
+ bundle.putFloat(key, value);
+ }
+
+ @Override
+ public Float get(@NonNull Bundle bundle, @NonNull String key) {
+ return (Float) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public Float parseValue(@NonNull String value) {
+ return Float.parseFloat(value);
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "float";
+ }
+ };
+
+ /**
+ * NavType for storing float arrays,
+ * corresponding with the "float[]" type in a Navigation XML file.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ */
+ @NonNull
+ public static final NavType<float[]> FloatArrayType = new NavType<float[]>(true) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable float[] value) {
+ bundle.putFloatArray(key, value);
+ }
+
+ @Override
+ public float[] get(@NonNull Bundle bundle, @NonNull String key) {
+ return (float[]) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public float[] parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Arrays don't support default values.");
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "float[]";
+ }
+ };
+
+ /**
+ * NavType for storing boolean values,
+ * corresponding with the "boolean" type in a Navigation XML file.
+ * <p>
+ * Null values are not supported.
+ */
+ @NonNull
+ public static final NavType<Boolean> BoolType = new NavType<Boolean>(false) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Boolean value) {
+ bundle.putBoolean(key, value);
+ }
+
+ @Override
+ public Boolean get(@NonNull Bundle bundle, @NonNull String key) {
+ return (Boolean) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public Boolean parseValue(@NonNull String value) {
+ if ("true".equals(value)) {
+ return true;
+ } else if ("false".equals(value)) {
+ return false;
+ } else {
+ throw new IllegalArgumentException(
+ "A boolean NavType only accepts \"true\" or \"false\" values.");
+ }
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "boolean";
+ }
+ };
+
+ /**
+ * NavType for storing boolean arrays,
+ * corresponding with the "boolean[]" type in a Navigation XML file.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ */
+ @NonNull
+ public static final NavType<boolean[]> BoolArrayType = new NavType<boolean[]>(true) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable boolean[] value) {
+ bundle.putBooleanArray(key, value);
+ }
+
+ @Override
+ public boolean[] get(@NonNull Bundle bundle, @NonNull String key) {
+ return (boolean[]) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public boolean[] parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Arrays don't support default values.");
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "boolean[]";
+ }
+ };
+
+ /**
+ * NavType for storing String values,
+ * corresponding with the "string" type in a Navigation XML file.
+ * <p>
+ * Null values are supported.
+ */
+ @NonNull
+ public static final NavType<String> StringType = new NavType<String>(true) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable String value) {
+ bundle.putString(key, value);
+ }
+
+ @Override
+ public String get(@NonNull Bundle bundle, @NonNull String key) {
+ return (String) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public String parseValue(@NonNull String value) {
+ return value;
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "string";
+ }
+ };
+
+ /**
+ * NavType for storing String arrays,
+ * corresponding with the "string[]" type in a Navigation XML file.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ */
+ @NonNull
+ public static final NavType<String[]> StringArrayType = new NavType<String[]>(true) {
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable String[] value) {
+ bundle.putStringArray(key, value);
+ }
+
+ @Override
+ public String[] get(@NonNull Bundle bundle, @NonNull String key) {
+ return (String[]) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public String[] parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Arrays don't support default values.");
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "string[]";
+ }
+ };
+
+ /**
+ * ParcelableType is used for passing Parcelables in {@link NavArgument}s.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ *
+ * @param <D> the Parcelable class that is supported by this NavType
+ */
+ public static final class ParcelableType<D> extends NavType<D> {
+ @NonNull
+ private final Class<D> mType;
+
+ /**
+ * Constructs a NavType that supports a given Parcelable type.
+ * @param type class that is a subtype of Parcelable
+ */
+ public ParcelableType(@NonNull Class<D> type) {
+ super(true);
+ if (!Parcelable.class.isAssignableFrom(type)
+ && !Serializable.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(
+ type + " does not implement Parcelable or Serializable.");
+ }
+ this.mType = type;
+ }
+
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D value) {
+ mType.cast(value);
+ if (value == null || value instanceof Parcelable) {
+ bundle.putParcelable(key, (Parcelable) value);
+ } else if (value instanceof Serializable) {
+ bundle.putSerializable(key, (Serializable) value);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ @Nullable
+ public D get(@NonNull Bundle bundle, @NonNull String key) {
+ return (D) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public D parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Parcelables don't support default values.");
+ }
+
+ @Override
+ @NonNull
+ public String getName() {
+ return mType.getName();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ParcelableType<?> that = (ParcelableType<?>) o;
+
+ return mType.equals(that.mType);
+ }
+
+ @Override
+ public int hashCode() {
+ return mType.hashCode();
+ }
+ }
+
+ /**
+ * ParcelableArrayType is used for {@link NavArgument}s which hold arrays of Parcelables.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ *
+ * @param <D> the type of Parcelable component class of the array
+ */
+ public static final class ParcelableArrayType<D extends Parcelable> extends NavType<D[]> {
+ @NonNull
+ private final Class<D[]> mArrayType;
+
+ /**
+ * Constructs a NavType that supports arrays of a given Parcelable type.
+ * @param type class that is a subtype of Parcelable
+ */
+ @SuppressWarnings("unchecked")
+ public ParcelableArrayType(@NonNull Class<D> type) {
+ super(true);
+ if (!Parcelable.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(
+ type + " does not implement Parcelable.");
+ }
+
+ Class<D[]> arrayType;
+ try {
+ arrayType = (Class<D[]>) Class.forName("[L" + type.getName() + ";");
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e); //should never happen
+ }
+ this.mArrayType = arrayType;
+ }
+
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D[] value) {
+ mArrayType.cast(value);
+ bundle.putParcelableArray(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ @Nullable
+ public D[] get(@NonNull Bundle bundle, @NonNull String key) {
+ return (D[]) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public D[] parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Arrays don't support default values.");
+ }
+
+ @Override
+ @NonNull
+ public String getName() {
+ return mArrayType.getName();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ParcelableArrayType<?> that = (ParcelableArrayType<?>) o;
+
+ return mArrayType.equals(that.mArrayType);
+ }
+
+ @Override
+ public int hashCode() {
+ return mArrayType.hashCode();
+ }
+ }
+
+ /**
+ * SerializableType is used for Serializable {@link NavArgument}s.
+ * For handling Enums you must use {@link EnumType} instead.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ *
+ * @param <D> the Serializable class that is supported by this NavType
+ * @see EnumType
+ */
+ public static class SerializableType<D extends Serializable> extends NavType<D> {
+ @NonNull
+ private final Class<D> mType;
+
+ /**
+ * Constructs a NavType that supports a given Serializable type.
+ * @param type class that is a subtype of Serializable
+ */
+ public SerializableType(@NonNull Class<D> type) {
+ super(true);
+ if (!Serializable.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(
+ type + " does not implement Serializable.");
+ }
+ if (type.isEnum()) {
+ throw new IllegalArgumentException(
+ type + " is an Enum. You should use EnumType instead.");
+ }
+ this.mType = type;
+ }
+
+ SerializableType(boolean nullableAllowed, @NonNull Class<D> type) {
+ super(nullableAllowed);
+ if (!Serializable.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(
+ type + " does not implement Serializable.");
+ }
+ this.mType = type;
+ }
+
+
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D value) {
+ mType.cast(value);
+ bundle.putSerializable(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ @Nullable
+ public D get(@NonNull Bundle bundle, @NonNull String key) {
+ return (D) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public D parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Serializables don't support default values.");
+ }
+
+ @Override
+ @NonNull
+ public String getName() {
+ return mType.getName();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SerializableType<?> that = (SerializableType<?>) o;
+
+ return mType.equals(that.mType);
+ }
+
+ @Override
+ public int hashCode() {
+ return mType.hashCode();
+ }
+ }
+
+ /**
+ * EnumType is used for {@link NavArgument}s holding enum values.
+ * <p>
+ * Null values are not supported.
+ * To specify a default value in a Navigation XML file, simply use the enum constant
+ * without the class name, e.g. `app:defaultValue="MONDAY"`.
+ *
+ * @param <D> the Enum class that is supported by this NavType
+ */
+ public static final class EnumType<D extends Enum> extends SerializableType<D> {
+ @NonNull
+ private final Class<D> mType;
+
+ /**
+ * Constructs a NavType that supports a given Enum type.
+ * @param type class that is an Enum
+ */
+ public EnumType(@NonNull Class<D> type) {
+ super(false, type);
+ if (!type.isEnum()) {
+ throw new IllegalArgumentException(
+ type + " is not an Enum type.");
+ }
+ mType = type;
+ }
+
+ @SuppressWarnings("unchecked")
+ @NonNull
+ @Override
+ public D parseValue(@NonNull String value) {
+ for (Object constant : mType.getEnumConstants()) {
+ if (((Enum) constant).name().equals(value)) {
+ return (D) constant;
+ }
+ }
+ throw new IllegalArgumentException("Enum value " + value + " not found for type "
+ + mType.getName() + ".");
+ }
+
+ @Override
+ @NonNull
+ public String getName() {
+ return mType.getName();
+ }
+ }
+
+ /**
+ * SerializableArrayType is used for {@link NavArgument}s that hold arrays of Serializables.
+ * This type also supports arrays of Enums.
+ * <p>
+ * Null values are supported.
+ * Default values in Navigation XML files are not supported.
+ *
+ * @param <D> the Serializable component class of the array
+ */
+ public static final class SerializableArrayType<D extends Serializable> extends NavType<D[]> {
+ @NonNull
+ private final Class<D[]> mArrayType;
+
+ /**
+ * Constructs a NavType that supports arrays of a given Serializable type.
+ * @param type class that is a subtype of Serializable
+ */
+ @SuppressWarnings("unchecked")
+ public SerializableArrayType(@NonNull Class<D> type) {
+ super(true);
+ if (!Serializable.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(
+ type + " does not implement Serializable.");
+ }
+
+ Class<D[]> arrayType;
+ try {
+ arrayType = (Class<D[]>) Class.forName("[L" + type.getName() + ";");
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e); //should never happen
+ }
+ this.mArrayType = arrayType;
+ }
+
+ @Override
+ public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D[] value) {
+ mArrayType.cast(value);
+ bundle.putSerializable(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ @Nullable
+ public D[] get(@NonNull Bundle bundle, @NonNull String key) {
+ return (D[]) bundle.get(key);
+ }
+
+ @NonNull
+ @Override
+ public D[] parseValue(@NonNull String value) {
+ throw new UnsupportedOperationException("Arrays don't support default values.");
+ }
+
+ @Override
+ @NonNull
+ public String getName() {
+ return mArrayType.getName();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SerializableArrayType<?> that = (SerializableArrayType<?>) o;
+
+ return mArrayType.equals(that.mArrayType);
+ }
+
+ @Override
+ public int hashCode() {
+ return mArrayType.hashCode();
+ }
+ }
+}
diff --git a/navigation/common/src/test/java/androidx/navigation/NavDestinationTest.kt b/navigation/common/src/test/java/androidx/navigation/NavDestinationTest.kt
index 954a716..8817924 100644
--- a/navigation/common/src/test/java/androidx/navigation/NavDestinationTest.kt
+++ b/navigation/common/src/test/java/androidx/navigation/NavDestinationTest.kt
@@ -180,4 +180,30 @@
assertThat(destination.getAction(ACTION_ID)).isNull()
}
+
+ @Test
+ fun addArgument() {
+ val destination = NoOpNavigator().createDestination()
+ val stringArgument = NavArgument.Builder()
+ .setType(NavType.StringType)
+ .build()
+ destination.addArgument("stringArg", stringArgument)
+ assertThat(destination.arguments.size).isEqualTo(1)
+ assertThat(destination.arguments.get("stringArg")).isEqualTo(stringArgument)
+ }
+
+ @Test
+ fun removeArgument() {
+ val destination = NoOpNavigator().createDestination()
+ val stringArgument = NavArgument.Builder()
+ .setType(NavType.StringType)
+ .build()
+ destination.addArgument("stringArg", stringArgument)
+ assertThat(destination.arguments.size).isEqualTo(1)
+ assertThat(destination.arguments.get("stringArg")).isEqualTo(stringArgument)
+
+ destination.removeArgument("stringArg")
+ assertThat(destination.arguments.size).isEqualTo(0)
+ assertThat(destination.arguments.get("stringArg")).isNull()
+ }
}
diff --git a/navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt b/navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
index 5dda968..d3d08d5 100644
--- a/navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
+++ b/navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
@@ -44,7 +44,9 @@
private const val UNKNOWN_DESTINATION_ID = -1
private const val TEST_ARG = "test"
private const val TEST_ARG_VALUE = "value"
+ private const val TEST_ARG_VALUE_INT = 123
private const val TEST_OVERRIDDEN_VALUE_ARG = "test_overriden_value"
+ private const val TEST_ACTION_OVERRIDDEN_VALUE_ARG = "test_action_overriden_value"
private const val TEST_OVERRIDDEN_VALUE_ARG_VALUE = "override"
}
@@ -70,6 +72,15 @@
assertEquals(TEST_ARG_VALUE, foundArgs?.getString(TEST_ARG))
}
+ @Test(expected = IllegalArgumentException::class)
+ fun testStartDestinationWithWrongArgs() {
+ val navController = createNavController()
+ val args = Bundle().apply {
+ putInt(TEST_ARG, TEST_ARG_VALUE_INT)
+ }
+ navController.setGraph(R.navigation.nav_start_destination, args)
+ }
+
@Test
fun testStartDestinationWithArgsProgrammatic() {
val navController = createNavController()
@@ -501,6 +512,10 @@
// Test that default values can be overridden by programmatic values
assertEquals(TEST_OVERRIDDEN_VALUE_ARG_VALUE,
returnedArgs.getString(TEST_OVERRIDDEN_VALUE_ARG))
+ // Test that default values can be overridden by action default values
+ assertEquals(
+ TEST_OVERRIDDEN_VALUE_ARG_VALUE,
+ returnedArgs.getString(TEST_ACTION_OVERRIDDEN_VALUE_ARG))
}
@Test
diff --git a/navigation/runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt b/navigation/runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
index 8796eca..746871e 100644
--- a/navigation/runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
+++ b/navigation/runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
@@ -18,7 +18,6 @@
import android.app.Instrumentation
import android.net.Uri
-import android.os.Bundle
import androidx.navigation.test.R
import androidx.navigation.test.TestEnum
@@ -27,9 +26,8 @@
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import org.junit.Assert.assertEquals
-import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
-import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
@@ -74,7 +72,8 @@
fun testDefaultArgumentsInteger() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
- assertEquals(12, defaultArguments.getInt("test_int"))
+ assertEquals(12, defaultArguments.get("test_int")?.defaultValue)
+ assertEquals(NavType.IntType, defaultArguments.get("test_int")?.type)
}
@Test
@@ -83,75 +82,103 @@
val context = InstrumentationRegistry.getTargetContext()
val expectedValue = context.resources.getDimensionPixelSize(R.dimen.test_dimen_arg)
- assertEquals(expectedValue, defaultArguments.getInt("test_dimen"))
+ assertEquals(expectedValue, defaultArguments.get("test_dimen")?.defaultValue)
+ assertEquals(NavType.IntType, defaultArguments.get("test_dimen")?.type)
}
@Test
fun testDefaultArgumentsFloat() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
- assertEquals(3.14f, defaultArguments.getFloat("test_float"))
+ assertEquals(3.14f, defaultArguments.get("test_float")?.defaultValue)
+ assertEquals(NavType.FloatType, defaultArguments.get("test_float")?.type)
}
@Test
fun testDefaultArgumentsBoolean() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
- assertEquals(true, defaultArguments.getBoolean("test_boolean"))
- assertEquals(false, defaultArguments.getBoolean("test_boolean2"))
- assertEquals(true, defaultArguments.getBoolean("test_boolean3"))
- assertEquals(false, defaultArguments.getBoolean("test_boolean4"))
+ assertEquals(true, defaultArguments.get("test_boolean")?.defaultValue)
+ assertEquals(false, defaultArguments.get("test_boolean2")?.defaultValue)
+ assertEquals(true, defaultArguments.get("test_boolean3")?.defaultValue)
+ assertEquals(false, defaultArguments.get("test_boolean4")?.defaultValue)
+ assertEquals(NavType.BoolType, defaultArguments.get("test_boolean")?.type)
+ assertEquals(NavType.BoolType, defaultArguments.get("test_boolean2")?.type)
+ assertEquals(NavType.BoolType, defaultArguments.get("test_boolean3")?.type)
+ assertEquals(NavType.BoolType, defaultArguments.get("test_boolean4")?.type)
}
@Test
fun testDefaultArgumentsLong() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
- assertEquals(456789013456L, defaultArguments.getLong("test_long"))
- assertEquals(456789013456L, defaultArguments.getLong("test_long2"))
- assertEquals(123L, defaultArguments.getLong("test_long3"))
+ assertEquals(456789013456L, defaultArguments.get("test_long")?.defaultValue)
+ assertEquals(456789013456L, defaultArguments.get("test_long2")?.defaultValue)
+ assertEquals(123L, defaultArguments.get("test_long3")?.defaultValue)
+ assertEquals(NavType.LongType, defaultArguments.get("test_long")?.type)
+ assertEquals(NavType.LongType, defaultArguments.get("test_long2")?.type)
+ assertEquals(NavType.LongType, defaultArguments.get("test_long3")?.type)
}
@Test
fun testDefaultArgumentsEnum() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
- assertEquals(TestEnum.VALUE_ONE, defaultArguments.getSerializable("test_enum") as TestEnum)
- assertNull(defaultArguments.getSerializable("test_enum2"))
+ assertEquals(TestEnum.VALUE_ONE, defaultArguments.get("test_enum")?.defaultValue)
+ assertEquals(NavType.EnumType(TestEnum::class.java),
+ defaultArguments.get("test_enum")?.type)
}
@Test
fun testDefaultArgumentsString() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
- assertEquals("abc", defaultArguments.getString("test_string"))
- assertEquals("true", defaultArguments.getString("test_string2"))
- assertEquals("123L", defaultArguments.getString("test_string3"))
- assertEquals("123", defaultArguments.getString("test_string4"))
- assertFalse(defaultArguments.containsKey("test_string_no_default"))
+ assertEquals("abc", defaultArguments.get("test_string")?.defaultValue)
+ assertEquals("true", defaultArguments.get("test_string2")?.defaultValue)
+ assertEquals("123L", defaultArguments.get("test_string3")?.defaultValue)
+ assertEquals("123", defaultArguments.get("test_string4")?.defaultValue)
+ assertTrue(defaultArguments.containsKey("test_string_no_default"))
+ assertEquals(false, defaultArguments.get("test_string_no_default")?.isDefaultValuePresent)
+
+ assertEquals(NavType.StringType, defaultArguments.get("test_string")?.type)
+ assertEquals(NavType.StringType, defaultArguments.get("test_string2")?.type)
+ assertEquals(NavType.StringType, defaultArguments.get("test_string3")?.type)
+ assertEquals(NavType.StringType, defaultArguments.get("test_string4")?.type)
+ assertEquals(NavType.StringType, defaultArguments.get("test_string_no_default")?.type)
}
@Test
fun testDefaultArgumentsReference() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
- assertEquals(R.style.AppTheme, defaultArguments.getInt("test_reference"))
+ assertEquals(R.style.AppTheme, defaultArguments.get("test_reference")?.defaultValue)
+ assertEquals(NavType.IntType, defaultArguments.get("test_reference")?.type)
}
@Test
fun testRelativeClassName() {
val defaultArguments = inflateDefaultArgumentsFromGraph()
assertEquals(TestEnum.VALUE_TWO,
- defaultArguments.getSerializable("test_relative_classname"))
+ defaultArguments.get("test_relative_classname")?.defaultValue)
}
- private fun inflateDefaultArgumentsFromGraph(): Bundle {
+ @Test
+ fun testActionArguments() {
+ val context = InstrumentationRegistry.getTargetContext()
+ val navInflater = NavInflater(context, TestNavigatorProvider())
+ val graph = navInflater.inflate(R.navigation.nav_default_arguments)
+ val startDestination = graph.findNode(graph.startDestination)
+ val action = startDestination?.getAction(R.id.my_action)
+ assertEquals(123L, action?.defaultArguments?.get("test_action_arg"))
+ }
+
+ private fun inflateDefaultArgumentsFromGraph(): Map<String, NavArgument> {
val context = InstrumentationRegistry.getTargetContext()
val navInflater = NavInflater(context, TestNavigatorProvider())
val graph = navInflater.inflate(R.navigation.nav_default_arguments)
val startDestination = graph.findNode(graph.startDestination)
- val defaultArguments = startDestination?.defaultArguments
+ val defaultArguments = startDestination?.arguments
assertNotNull(defaultArguments)
return defaultArguments!!
diff --git a/navigation/runtime/src/androidTest/res/navigation/nav_arguments.xml b/navigation/runtime/src/androidTest/res/navigation/nav_arguments.xml
index c264db2..f786fc3 100644
--- a/navigation/runtime/src/androidTest/res/navigation/nav_arguments.xml
+++ b/navigation/runtime/src/androidTest/res/navigation/nav_arguments.xml
@@ -19,12 +19,16 @@
app:startDestination="@+id/start_test">
<test android:id="@+id/start_test">
- <action android:id="@+id/second" app:destination="@+id/second_test" />
+ <action android:id="@+id/second" app:destination="@+id/second_test">
+ <argument android:name="test_action_overriden_value"
+ android:defaultValue="override" />
+ </action>
</test>
<test android:id="@+id/second_test">
<argument android:name="test_no_default_value" />
<argument android:name="test_default_value" android:defaultValue="default" />
<argument android:name="test_overridden_value" android:defaultValue="default" />
+ <argument android:name="test_action_overriden_value" android:defaultValue="default" />
</test>
</navigation>
diff --git a/navigation/runtime/src/androidTest/res/navigation/nav_default_arguments.xml b/navigation/runtime/src/androidTest/res/navigation/nav_default_arguments.xml
index e07b2aa..e7bc58c 100644
--- a/navigation/runtime/src/androidTest/res/navigation/nav_default_arguments.xml
+++ b/navigation/runtime/src/androidTest/res/navigation/nav_default_arguments.xml
@@ -37,10 +37,10 @@
<argument android:name="test_long3" android:defaultValue="123L" />
<argument android:name="test_enum" app:argType="androidx.navigation.test.TestEnum"
android:defaultValue="VALUE_ONE"/>
- <argument android:name="test_enum2" app:argType="androidx.navigation.test.TestEnum"
- app:nullable="true" android:defaultValue="@null"/>
<argument android:name="test_relative_classname" app:argType=".TestEnum"
android:defaultValue="VALUE_TWO"/>
-
+ <action android:id="@+id/my_action" app:destination="@+id/start_test">
+ <argument android:name="test_action_arg" android:defaultValue="123L" />
+ </action>
</test>
</navigation>
diff --git a/navigation/runtime/src/androidTest/res/navigation/nav_start_destination.xml b/navigation/runtime/src/androidTest/res/navigation/nav_start_destination.xml
index 971ebb4..935ca93 100644
--- a/navigation/runtime/src/androidTest/res/navigation/nav_start_destination.xml
+++ b/navigation/runtime/src/androidTest/res/navigation/nav_start_destination.xml
@@ -18,5 +18,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@+id/start_test">
- <test android:id="@+id/start_test" />
+ <test android:id="@+id/start_test" >
+ <argument android:name="test" android:defaultValue="@null" app:argType="string"/>
+ </test>
</navigation>
diff --git a/navigation/runtime/src/main/java/androidx/navigation/NavController.java b/navigation/runtime/src/main/java/androidx/navigation/NavController.java
index 531ca8f..c3da06b 100644
--- a/navigation/runtime/src/main/java/androidx/navigation/NavController.java
+++ b/navigation/runtime/src/main/java/androidx/navigation/NavController.java
@@ -529,7 +529,27 @@
Pair<NavDestination, Bundle> matchingDeepLink = mGraph.matchDeepLink(intent.getData());
if (matchingDeepLink != null) {
deepLink = matchingDeepLink.first.buildDeepLinkIds();
- bundle.putAll(matchingDeepLink.second);
+ for (String argumentName: matchingDeepLink.second.keySet()) {
+ NavArgument argument = matchingDeepLink.first.getArguments().get(argumentName);
+ if (argument != null) {
+ NavType type = argument.getType();
+ try {
+ type.parseAndPut(bundle,
+ argumentName,
+ matchingDeepLink.second.getString(argumentName));
+ } catch (IllegalArgumentException e) {
+ Log.i(TAG, "Deep link parameter "
+ + argumentName
+ + " cannot be parsed into navigation argument of type "
+ + argument.getType()
+ + ".");
+ return false;
+ }
+ } else {
+ bundle.putString(argumentName,
+ matchingDeepLink.second.getString(argumentName));
+ }
+ }
}
}
if (deepLink == null || deepLink.length == 0) {
@@ -696,12 +716,26 @@
}
@IdRes int destId = resId;
final NavAction navAction = currentNode.getAction(resId);
+ Bundle combinedArgs = null;
if (navAction != null) {
if (navOptions == null) {
navOptions = navAction.getNavOptions();
}
destId = navAction.getDestinationId();
+ Bundle navActionArgs = navAction.getDefaultArguments();
+ if (navActionArgs != null) {
+ combinedArgs = new Bundle();
+ combinedArgs.putAll(navActionArgs);
+ }
}
+
+ if (args != null) {
+ if (combinedArgs == null) {
+ combinedArgs = new Bundle();
+ }
+ combinedArgs.putAll(args);
+ }
+
if (destId == 0 && navOptions != null && navOptions.getPopUpTo() != 0) {
popBackStack(navOptions.getPopUpTo(), navOptions.isPopUpToInclusive());
return;
@@ -721,7 +755,7 @@
: "")
+ " is unknown to this NavController");
}
- navigate(node, args, navOptions, navigatorExtras);
+ navigate(node, combinedArgs, navOptions, navigatorExtras);
}
private void navigate(@NonNull NavDestination node, @Nullable Bundle args,
diff --git a/navigation/runtime/src/main/java/androidx/navigation/NavInflater.java b/navigation/runtime/src/main/java/androidx/navigation/NavInflater.java
index 2f78672..befdc6e 100644
--- a/navigation/runtime/src/main/java/androidx/navigation/NavInflater.java
+++ b/navigation/runtime/src/main/java/androidx/navigation/NavInflater.java
@@ -21,9 +21,9 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.os.Bundle;
import android.support.annotation.NavigationRes;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -117,11 +117,11 @@
final String name = parser.getName();
if (TAG_ARGUMENT.equals(name)) {
- inflateArgument(res, dest, attrs, graphResId);
+ inflateArgumentForDestination(res, dest, attrs, graphResId);
} else if (TAG_DEEP_LINK.equals(name)) {
inflateDeepLink(res, dest, attrs);
} else if (TAG_ACTION.equals(name)) {
- inflateAction(res, dest, attrs);
+ inflateAction(res, dest, attrs, parser, graphResId);
} else if (TAG_INCLUDE.equals(name) && dest instanceof NavGraph) {
final TypedArray a = res.obtainAttributes(attrs, R.styleable.NavInclude);
final int id = a.getResourceId(R.styleable.NavInclude_graph, 0);
@@ -135,119 +135,115 @@
return dest;
}
- private void inflateArgument(@NonNull Resources res, @NonNull NavDestination dest,
+ private void inflateArgumentForDestination(@NonNull Resources res, @NonNull NavDestination dest,
@NonNull AttributeSet attrs, int graphResId) throws XmlPullParserException {
final TypedArray a = res.obtainAttributes(attrs, R.styleable.NavArgument);
String name = a.getString(R.styleable.NavArgument_android_name);
+ if (name == null) {
+ throw new XmlPullParserException("Arguments must have a name");
+ }
+ NavArgument argument = inflateArgument(a, res, graphResId);
+ dest.addArgument(name, argument);
+ a.recycle();
+ }
+
+ private void inflateArgumentForBundle(@NonNull Resources res, @NonNull Bundle bundle,
+ @NonNull AttributeSet attrs, int graphResId) throws XmlPullParserException {
+ final TypedArray a = res.obtainAttributes(attrs, R.styleable.NavArgument);
+ String name = a.getString(R.styleable.NavArgument_android_name);
+ if (name == null) {
+ throw new XmlPullParserException("Arguments must have a name");
+ }
+ NavArgument argument = inflateArgument(a, res, graphResId);
+ if (argument.isDefaultValuePresent()) {
+ argument.putDefaultValue(name, bundle);
+ }
+ a.recycle();
+ }
+
+ @SuppressWarnings("unchecked")
+ @NonNull
+ private NavArgument inflateArgument(@NonNull TypedArray a, @NonNull Resources res,
+ int graphResId) throws XmlPullParserException {
+ NavArgument.Builder argumentBuilder = new NavArgument.Builder();
+ argumentBuilder.setIsNullable(a.getBoolean(R.styleable.NavArgument_nullable, false));
TypedValue value = sTmpValue.get();
if (value == null) {
value = new TypedValue();
sTmpValue.set(value);
}
+
+ Object defaultValue = null;
+ NavType navType = null;
String argType = a.getString(R.styleable.NavArgument_argType);
+ if (argType != null) {
+ navType = NavType.fromArgType(argType, res.getResourcePackageName(graphResId));
+ }
+
if (a.getValue(R.styleable.NavArgument_android_defaultValue, value)) {
- if ("string".equals(argType)) {
- dest.getDefaultArguments()
- .putString(name, a.getString(R.styleable.NavArgument_android_defaultValue));
+ if (navType == NavType.StringType) {
+ defaultValue = a.getString(R.styleable.NavArgument_android_defaultValue);
} else {
switch (value.type) {
case TypedValue.TYPE_STRING:
String stringValue = value.string.toString();
- if (argType == null) {
- Long longValue = parseLongValue(stringValue);
- if (longValue != null) {
- dest.getDefaultArguments().putLong(name, longValue);
- break;
- }
- } else if ("long".equals(argType)) {
- Long longValue = parseLongValue(stringValue);
- if (longValue != null) {
- dest.getDefaultArguments().putLong(name, longValue);
- break;
- }
- throw new XmlPullParserException(
- "unsupported long value " + value.string);
- } else { //this might be an Enum
- Class<?> cls = null;
- String className;
- if (argType.startsWith(".")) {
- className = res.getResourcePackageName(graphResId) + argType;
- } else {
- className = argType;
- }
- try {
- cls = Class.forName(className);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- if (cls != null && cls.isEnum()) {
- boolean found = false;
- for (Object constant : cls.getEnumConstants()) {
- if (((Enum) constant).name().equals(stringValue)) {
- dest.getDefaultArguments()
- .putSerializable(name, (Enum) constant);
- found = true;
- break;
- }
- }
- if (!found) {
- throw new XmlPullParserException(
- "Cannot find Enum value '" + stringValue + "' for "
- + "'" + className + "'");
- }
- break; //from switch statement
- } else {
- throw new XmlPullParserException(
- "Unsupported argument type '" + argType + "' with "
- + "non-null defaultValue. Class '" + className
- + " does not exist or is not an Enum.");
- }
+ if (navType == null) {
+ navType = NavType.inferFromValue(stringValue);
}
- dest.getDefaultArguments().putString(name, stringValue);
+ defaultValue = navType.parseValue(stringValue);
break;
case TypedValue.TYPE_DIMENSION:
- dest.getDefaultArguments().putInt(name,
- (int) value.getDimension(res.getDisplayMetrics()));
+ navType = checkNavType(value, navType, NavType.IntType,
+ argType, "dimension");
+ defaultValue = (int) value.getDimension(res.getDisplayMetrics());
break;
case TypedValue.TYPE_FLOAT:
- dest.getDefaultArguments().putFloat(name, value.getFloat());
+ navType = checkNavType(value, navType, NavType.FloatType,
+ argType, "float");
+ defaultValue = value.getFloat();
break;
case TypedValue.TYPE_REFERENCE:
- dest.getDefaultArguments().putInt(name, value.data);
+ navType = checkNavType(value, navType, NavType.IntType,
+ argType, "reference");
+ defaultValue = value.data;
+ break;
+ case TypedValue.TYPE_INT_BOOLEAN:
+ navType = checkNavType(value, navType, NavType.BoolType,
+ argType, "boolean");
+ defaultValue = value.data != 0;
break;
default:
if (value.type >= TypedValue.TYPE_FIRST_INT
&& value.type <= TypedValue.TYPE_LAST_INT) {
- if (value.type == TypedValue.TYPE_INT_BOOLEAN) {
- dest.getDefaultArguments().putBoolean(name, value.data != 0);
- } else {
- dest.getDefaultArguments().putInt(name, value.data);
- }
+ navType = checkNavType(value, navType, NavType.IntType,
+ argType, "integer");
+ defaultValue = value.data;
} else {
throw new XmlPullParserException(
- "Unsupported argument type " + value.type);
+ "unsupported argument type " + value.type);
}
}
}
}
- a.recycle();
+
+ if (defaultValue != null) {
+ argumentBuilder.setDefaultValue(defaultValue);
+ }
+ if (navType != null) {
+ argumentBuilder.setType(navType);
+ }
+ return argumentBuilder.build();
}
- private @Nullable Long parseLongValue(String value) {
- if (!value.endsWith("L")) {
- return null;
+ private static NavType checkNavType(TypedValue value, NavType navType,
+ NavType expectedNavType, String argType, String foundType)
+ throws XmlPullParserException {
+ if (navType != null && navType != expectedNavType) {
+ throw new XmlPullParserException(
+ "Type is " + argType + " but found " + foundType + ": " + value.data);
}
- try {
- value = value.substring(0, value.length() - 1);
- if (value.startsWith("0x")) {
- return Long.parseLong(value.substring(2), 16);
- } else {
- return Long.parseLong(value);
- }
- } catch (NumberFormatException ex) {
- return null;
- }
+ return navType != null ? navType : expectedNavType;
}
private void inflateDeepLink(@NonNull Resources res, @NonNull NavDestination dest,
@@ -264,7 +260,8 @@
}
private void inflateAction(@NonNull Resources res, @NonNull NavDestination dest,
- @NonNull AttributeSet attrs) {
+ @NonNull AttributeSet attrs, XmlResourceParser parser, int graphResId)
+ throws IOException, XmlPullParserException {
final TypedArray a = res.obtainAttributes(attrs, R.styleable.NavAction);
final int id = a.getResourceId(R.styleable.NavAction_android_id, 0);
final int destId = a.getResourceId(R.styleable.NavAction_destination, 0);
@@ -280,6 +277,28 @@
builder.setPopExitAnim(a.getResourceId(R.styleable.NavAction_popExitAnim, -1));
action.setNavOptions(builder.build());
+ Bundle args = new Bundle();
+ final int innerDepth = parser.getDepth() + 1;
+ int type;
+ int depth;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && ((depth = parser.getDepth()) >= innerDepth
+ || type != XmlPullParser.END_TAG)) {
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ if (depth > innerDepth) {
+ continue;
+ }
+ final String name = parser.getName();
+ if (TAG_ARGUMENT.equals(name)) {
+ inflateArgumentForBundle(res, args, attrs, graphResId);
+ }
+ }
+ if (!args.isEmpty()) {
+ action.setDefaultArguments(args);
+ }
dest.putAction(id, action);
a.recycle();
}
diff --git a/preference/build.gradle b/preference/build.gradle
index 350fb4f..9dde886 100644
--- a/preference/build.gradle
+++ b/preference/build.gradle
@@ -25,7 +25,7 @@
dependencies {
api("androidx.core:core:1.1.0-alpha01")
api("androidx.collection:collection:1.0.0")
- api("androidx.fragment:fragment:1.1.0-alpha01")
+ api("androidx.fragment:fragment:1.1.0-alpha02")
api("androidx.appcompat:appcompat:1.0.0")
api("androidx.recyclerview:recyclerview:1.0.0")
diff --git a/preference/ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt b/preference/ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt
index d86dffd..83f97b8 100644
--- a/preference/ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt
+++ b/preference/ktx/src/androidTest/java/androidx/preference/PreferenceGroupTest.kt
@@ -121,7 +121,9 @@
assertTrue(preferenceGroup.isNotEmpty())
}
- @Test fun forEach() {
+ // Temporarily disabled due to b/113042342
+ // @Test
+ fun forEach() {
preferenceGroup.forEach {
fail("Empty preference group should not invoke lambda")
}
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerBaseConfigSetTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerBaseConfigSetTest.java
index eb970e9..70d87ff 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerBaseConfigSetTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerBaseConfigSetTest.java
@@ -77,8 +77,11 @@
// try scrolling towards head, should not affect anything
Map<Item, Rect> before = mLayoutManager.collectChildCoordinates();
if (config.mStackFromEnd) {
- scrollToPositionWithOffset(mTestAdapter.getItemCount() - 1,
- mLayoutManager.mOrientationHelper.getEnd() - 500);
+ scrollToPositionWithOffset(
+ mTestAdapter.getItemCount() - 1,
+ mLayoutManager.mOrientationHelper.getEnd()
+ - mRecyclerView.getChildAt(0).getWidth()
+ - 20);
} else {
scrollToPositionWithOffset(0, 20);
}
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java
index c1e40c7..f91a4b2 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java
@@ -696,7 +696,6 @@
}
}
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
static class LayoutManagerSavedState implements Parcelable {
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/LinearLayoutManager.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/LinearLayoutManager.java
index 00cc638..61d2407 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/LinearLayoutManager.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/LinearLayoutManager.java
@@ -2305,7 +2305,6 @@
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public static class SavedState implements Parcelable {
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/StaggeredGridLayoutManager.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/StaggeredGridLayoutManager.java
index 7561cef..17e4293 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/StaggeredGridLayoutManager.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/StaggeredGridLayoutManager.java
@@ -3072,7 +3072,6 @@
/**
* We keep information about full span items because they may create gaps in the UI.
*/
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
static class FullSpanItem implements Parcelable {
@@ -3149,7 +3148,6 @@
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
- @SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public static class SavedState implements Parcelable {
diff --git a/remotecallback/api/1.0.0-alpha02.txt b/remotecallback/api/1.0.0-alpha02.txt
new file mode 100644
index 0000000..ce29789
--- /dev/null
+++ b/remotecallback/api/1.0.0-alpha02.txt
@@ -0,0 +1,57 @@
+// Signature format: 2.0
+package androidx.remotecallback {
+
+ public class AppWidgetProviderWithCallbacks<T extends androidx.remotecallback.CallbackReceiver> extends android.appwidget.AppWidgetProvider implements androidx.remotecallback.CallbackReceiver<T> {
+ ctor public AppWidgetProviderWithCallbacks();
+ method public T! createRemoteCallback(android.content.Context!);
+ }
+
+ public abstract class BroadcastReceiverWithCallbacks<T extends androidx.remotecallback.CallbackReceiver> extends android.content.BroadcastReceiver implements androidx.remotecallback.CallbackReceiver<T> {
+ ctor public BroadcastReceiverWithCallbacks();
+ method public T! createRemoteCallback(android.content.Context!);
+ method public void onReceive(android.content.Context!, android.content.Intent!);
+ field public static final String ACTION_BROADCAST_CALLBACK = "androidx.remotecallback.action.BROADCAST_CALLBACK";
+ }
+
+ public class CallbackHandlerRegistry {
+ ctor public CallbackHandlerRegistry();
+ method public <T extends androidx.remotecallback.CallbackReceiver> void invokeCallback(android.content.Context!, T!, android.content.Intent!);
+ method public <T extends androidx.remotecallback.CallbackReceiver> void invokeCallback(android.content.Context!, T!, android.os.Bundle!);
+ method public static <T extends androidx.remotecallback.CallbackReceiver> void registerCallbackHandler(Class<T>!, String!, androidx.remotecallback.CallbackHandlerRegistry.CallbackHandler<T>!);
+ method public static androidx.remotecallback.RemoteCallback! stubToRemoteCallback(androidx.remotecallback.CallbackReceiver!, Class<? extends androidx.remotecallback.CallbackReceiver>!, android.os.Bundle!, String!);
+ }
+
+ public static interface CallbackHandlerRegistry.CallbackHandler<T extends androidx.remotecallback.CallbackReceiver> {
+ method public void executeCallback(android.content.Context!, T!, android.os.Bundle!);
+ }
+
+ public interface CallbackReceiver<T> {
+ method public T! createRemoteCallback(android.content.Context!);
+ }
+
+ public abstract class ContentProviderWithCallbacks<T extends androidx.remotecallback.ContentProviderWithCallbacks> extends android.content.ContentProvider implements androidx.remotecallback.CallbackReceiver<T> {
+ ctor public ContentProviderWithCallbacks();
+ method public T! createRemoteCallback(android.content.Context!);
+ }
+
+ @java.lang.annotation.Target(java.lang.annotation.ElementType.PARAMETER) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public @interface ExternalInput {
+ method public abstract String value();
+ }
+
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface RemoteCallable {
+ }
+
+ public class RemoteCallback {
+ method public static <T extends androidx.remotecallback.CallbackReceiver> T! create(Class<T>!, android.content.Context!);
+ method public android.os.Bundle! getArgumentBundle();
+ method public String! getMethodName();
+ method public String getReceiverClass();
+ method public int getType();
+ method public android.app.PendingIntent! toPendingIntent();
+ field public static final androidx.remotecallback.RemoteCallback! LOCAL;
+ field public static final int TYPE_PROVIDER = 1; // 0x1
+ field public static final int TYPE_RECEIVER = 0; // 0x0
+ }
+
+}
+
diff --git a/remotecallback/api/res-1.0.0-alpha02.txt b/remotecallback/api/res-1.0.0-alpha02.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/remotecallback/api/res-1.0.0-alpha02.txt
diff --git a/room/integration-tests/autovaluetestapp/src/androidTest/java/androidx/room/integration/autovaluetestapp/vo/ParcelableEntity.java b/room/integration-tests/autovaluetestapp/src/androidTest/java/androidx/room/integration/autovaluetestapp/vo/ParcelableEntity.java
index 0899a2ca..2de7e2d 100644
--- a/room/integration-tests/autovaluetestapp/src/androidTest/java/androidx/room/integration/autovaluetestapp/vo/ParcelableEntity.java
+++ b/room/integration-tests/autovaluetestapp/src/androidTest/java/androidx/room/integration/autovaluetestapp/vo/ParcelableEntity.java
@@ -28,7 +28,6 @@
@AutoValue
@Entity(tableName = "parcelable_entity")
-@SuppressWarnings("BanParcelableUsage")
@SuppressLint("BanParcelableUsage")
public abstract class ParcelableEntity implements Parcelable {
@CopyAnnotations
diff --git a/settings.gradle b/settings.gradle
index c88f91f..39045d3 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -60,7 +60,6 @@
includeProject(":core", "core")
includeProject(":core-ktx", "core/ktx")
includeProject(":cursoradapter", "cursoradapter")
-includeProject(":customerrorprone", "customerrorprone")
includeProject(":customview", "customview")
includeProject(":documentfile", "documentfile")
includeProject(":drawerlayout", "drawerlayout")
diff --git a/slices/builders/ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt b/slices/builders/ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt
index e5e10ab..97a0cf8 100644
--- a/slices/builders/ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt
+++ b/slices/builders/ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt
@@ -67,7 +67,8 @@
assertEquals(sliceKtx.toString(), slice.toString())
}
- @Test
+ // Temporarily disabled due to b/116146018.
+ // @Test
fun allBuildersTogether() {
val pendingIntent = pendingIntentToTestActivity()
val tapAction = tapSliceAction(
@@ -94,7 +95,8 @@
assertEquals(slice.toString(), sliceKtx.toString())
}
- @Test
+ // Temporarily disabled due to b/116146018.
+ // @Test
fun sanity_withGridRow() {
val tapAction = tapSliceAction(
pendingIntentToTestActivity(),
diff --git a/slices/view/api/1.1.0-alpha01.txt b/slices/view/api/1.1.0-alpha01.txt
index e58221c..b6a9671 100644
--- a/slices/view/api/1.1.0-alpha01.txt
+++ b/slices/view/api/1.1.0-alpha01.txt
@@ -150,6 +150,7 @@
method public void setSliceActions(java.util.List<androidx.slice.core.SliceAction>?);
method public void showActionDividers(boolean);
method public void showHeaderDivider(boolean);
+ method public void showTitleItems(boolean);
field public static final int MODE_LARGE = 2; // 0x2
field public static final int MODE_SHORTCUT = 3; // 0x3
field public static final int MODE_SMALL = 1; // 0x1
diff --git a/slices/view/api/current.txt b/slices/view/api/current.txt
index e58221c..b6a9671 100644
--- a/slices/view/api/current.txt
+++ b/slices/view/api/current.txt
@@ -150,6 +150,7 @@
method public void setSliceActions(java.util.List<androidx.slice.core.SliceAction>?);
method public void showActionDividers(boolean);
method public void showHeaderDivider(boolean);
+ method public void showTitleItems(boolean);
field public static final int MODE_LARGE = 2; // 0x2
field public static final int MODE_SHORTCUT = 3; // 0x3
field public static final int MODE_SMALL = 1; // 0x1
diff --git a/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java b/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
index 56f21a4..2ba7661 100644
--- a/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
+++ b/slices/view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
@@ -16,11 +16,11 @@
package androidx.slice.widget;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import android.app.PendingIntent;
import android.content.Context;
@@ -389,6 +389,48 @@
}
@Test
+ public void testDefaultHideTitleItems() {
+ Uri uri = Uri.parse("content://pkg/slice");
+ ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
+ lb.addRow(new ListBuilder.RowBuilder()
+ .setTitleItem(getAction("Action"))
+ .setTitle("Title")
+ .setSubtitle("Subtitle")
+ .setPrimaryAction(getAction("Action")));
+ Slice s = lb.build();
+
+ mSliceView.setSlice(s);
+
+ RowContent row = (RowContent) mSliceView.mListContent.getRowItems().get(0);
+ assertFalse(row.hasTitleItems());
+ assertNull(row.getStartItem());
+ }
+
+ @Test
+ public void testShowTitleItems() {
+ Uri uri = Uri.parse("content://pkg/slice");
+ ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
+ lb.addRow(new ListBuilder.RowBuilder()
+ .setTitleItem(getAction("Action"))
+ .setTitle("Title")
+ .setSubtitle("Subtitle")
+ .setPrimaryAction(getAction("Action")));
+ Slice s = lb.build();
+
+ mSliceView.setSlice(s);
+ mSliceView.showTitleItems(true);
+
+ RowContent row = (RowContent) mSliceView.mListContent.getRowItems().get(0);
+ assertTrue(row.hasTitleItems());
+ assertNotNull(row.getStartItem());
+
+ mSliceView.showTitleItems(false);
+
+ assertFalse(row.hasTitleItems());
+ assertNull(row.getStartItem());
+ }
+
+ @Test
public void testHideHeaderDividerWhenOnlyOneRow() {
Uri uri = Uri.parse("content://pkg/slice");
ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
@@ -425,6 +467,22 @@
}
@Test
+ public void testDefaultHideActionDividers() {
+ Uri uri = Uri.parse("content://pkg/slice");
+ ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
+ lb.addRow(new ListBuilder.RowBuilder()
+ .setTitle("Title")
+ .setSubtitle("Subtitle")
+ .setPrimaryAction(getAction("Action")));
+ Slice s = lb.build();
+
+ mSliceView.setSlice(s);
+
+ RowContent row = (RowContent) mSliceView.mListContent.getRowItems().get(0);
+ assertFalse(row.hasActionDivider());
+ }
+
+ @Test
public void testShowActionDividers() {
Uri uri = Uri.parse("content://pkg/slice");
ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
diff --git a/slices/view/src/main/java/androidx/slice/widget/ListContent.java b/slices/view/src/main/java/androidx/slice/widget/ListContent.java
index 12e27e92..15d307b 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ListContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ListContent.java
@@ -191,6 +191,15 @@
}
/**
+ * Whether the first row should show title items on the start.
+ */
+ public void showTitleItems(boolean enabled) {
+ if (mHeaderContent != null) {
+ mHeaderContent.showTitleItems(enabled);
+ }
+ }
+
+ /**
* Whether the header row should show the bottom divider.
*/
public void showHeaderDivider(boolean enabled) {
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowContent.java b/slices/view/src/main/java/androidx/slice/widget/RowContent.java
index e5c5bd2..6544d31 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowContent.java
@@ -74,6 +74,7 @@
private ArrayList<SliceItem> mSelectionOptions = new ArrayList<>();
private boolean mIsHeader;
private int mLineCount = 0;
+ private boolean mShowTitleItems;
private boolean mShowBottomDivider;
private boolean mShowActionDivider;
@@ -274,7 +275,7 @@
*/
@Nullable
public SliceItem getStartItem() {
- return mIsHeader ? null : mStartItem;
+ return mIsHeader && !mShowTitleItems ? null : mStartItem;
}
/**
@@ -334,6 +335,20 @@
}
/**
+ * Set whether this row content needs to show the title items on the start.
+ */
+ public void showTitleItems(boolean enabled) {
+ mShowTitleItems = enabled;
+ }
+
+ /**
+ * @return whether this row content needs to show the title items on the start.
+ */
+ public boolean hasTitleItems() {
+ return mShowTitleItems;
+ }
+
+ /**
* Set whether this row content needs to show the bottom divider.
*/
public void showBottomDivider(boolean enabled) {
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowView.java b/slices/view/src/main/java/androidx/slice/widget/RowView.java
index 37e7dfb..bc7a6ac 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowView.java
@@ -328,7 +328,7 @@
mContent.setContentDescription(contentDescr);
}
mStartItem = mRowContent.getStartItem();
- boolean showStart = mStartItem != null && mRowIndex > 0;
+ boolean showStart = mStartItem != null && (mRowIndex > 0 || mRowContent.hasTitleItems());
if (showStart) {
showStart = addItem(mStartItem, mTintColor, true /* isStart */);
}
@@ -403,8 +403,10 @@
// Use these if we have them instead
endItems = mHeaderActions;
}
- // Add start item to end of row for the top row if end items are empty.
- if (mRowIndex == 0 && mStartItem != null && endItems.isEmpty()) {
+ // Add start item to end of row for the top row if end items are empty and presenter
+ // doesn't show title items.
+ if (mRowIndex == 0 && mStartItem != null && endItems.isEmpty()
+ && !mRowContent.hasTitleItems()) {
endItems.add(mStartItem);
}
diff --git a/slices/view/src/main/java/androidx/slice/widget/SliceView.java b/slices/view/src/main/java/androidx/slice/widget/SliceView.java
index dbe0251..4f37908 100644
--- a/slices/view/src/main/java/androidx/slice/widget/SliceView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/SliceView.java
@@ -160,6 +160,7 @@
private boolean mShowActions = false;
private boolean mShowLastUpdated = true;
private boolean mCurrentSliceLoggedVisible = false;
+ private boolean mShowTitleItems = false;
private boolean mShowHeaderDivider = false;
private boolean mShowActionDividers = false;
@@ -469,6 +470,9 @@
mCurrentView.resetView();
}
mListContent = mSliceMetadata != null ? mSliceMetadata.getListContent() : null;
+ if (mShowTitleItems) {
+ showTitleItems(true);
+ }
if (mShowHeaderDivider) {
showHeaderDivider(true);
}
@@ -634,6 +638,17 @@
}
/**
+ * Whether this view should show title items on the first row of the slice.
+ * Title items appear at the start of the row.
+ */
+ public void showTitleItems(boolean enabled) {
+ mShowTitleItems = enabled;
+ if (mListContent != null) {
+ mListContent.showTitleItems(enabled);
+ }
+ }
+
+ /**
* Whether this view should show the header divider.
*/
public void showHeaderDivider(boolean enabled) {
diff --git a/textclassifier/api/1.0.0-alpha02.txt b/textclassifier/api/1.0.0-alpha02.txt
new file mode 100644
index 0000000..2d0c5d9
--- /dev/null
+++ b/textclassifier/api/1.0.0-alpha02.txt
@@ -0,0 +1,240 @@
+// Signature format: 2.0
+package androidx.textclassifier {
+
+ public final class TextClassification {
+ method public static androidx.textclassifier.TextClassification createFromBundle(android.os.Bundle);
+ method public java.util.List<androidx.core.app.RemoteActionCompat> getActions();
+ method @FloatRange(from=0.0, to=1.0) public float getConfidenceScore(String!);
+ method public String getEntityType(int);
+ method @IntRange(from=0) public int getEntityTypeCount();
+ method public android.os.Bundle getExtras();
+ method public String? getId();
+ method public CharSequence? getText();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static final class TextClassification.Builder {
+ ctor public TextClassification.Builder();
+ method public androidx.textclassifier.TextClassification.Builder addAction(androidx.core.app.RemoteActionCompat);
+ method public androidx.textclassifier.TextClassification build();
+ method public androidx.textclassifier.TextClassification.Builder! setEntityType(String, @FloatRange(from=0.0, to=1.0) float);
+ method public androidx.textclassifier.TextClassification.Builder setExtras(android.os.Bundle?);
+ method public androidx.textclassifier.TextClassification.Builder setId(String?);
+ method public androidx.textclassifier.TextClassification.Builder! setText(CharSequence?);
+ }
+
+ public static final class TextClassification.Request {
+ method public static androidx.textclassifier.TextClassification.Request! createFromBundle(android.os.Bundle);
+ method public androidx.core.os.LocaleListCompat? getDefaultLocales();
+ method @IntRange(from=0) public int getEndIndex();
+ method public android.os.Bundle getExtras();
+ method public Long? getReferenceTime();
+ method @IntRange(from=0) public int getStartIndex();
+ method public CharSequence getText();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static final class TextClassification.Request.Builder {
+ ctor public TextClassification.Request.Builder(CharSequence, @IntRange(from=0) int, @IntRange(from=0) int);
+ method public androidx.textclassifier.TextClassification.Request build();
+ method public androidx.textclassifier.TextClassification.Request.Builder setDefaultLocales(androidx.core.os.LocaleListCompat?);
+ method public androidx.textclassifier.TextClassification.Request.Builder setExtras(android.os.Bundle?);
+ method public androidx.textclassifier.TextClassification.Request.Builder setReferenceTime(Long?);
+ }
+
+ public final class TextClassificationContext {
+ method public static androidx.textclassifier.TextClassificationContext createFromBundle(android.os.Bundle);
+ method public String getPackageName();
+ method public String getWidgetType();
+ method public String? getWidgetVersion();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static final class TextClassificationContext.Builder {
+ ctor public TextClassificationContext.Builder(String, String);
+ method public androidx.textclassifier.TextClassificationContext build();
+ method public androidx.textclassifier.TextClassificationContext.Builder! setWidgetVersion(String?);
+ }
+
+ public final class TextClassificationManager {
+ method public androidx.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public androidx.textclassifier.TextClassifier getTextClassifier();
+ method public static androidx.textclassifier.TextClassificationManager! of(android.content.Context);
+ method public void setTextClassifier(androidx.textclassifier.TextClassifier?);
+ }
+
+ public final class TextClassificationSessionId {
+ method public static androidx.textclassifier.TextClassificationSessionId createFromBundle(android.os.Bundle);
+ method public android.os.Bundle toBundle();
+ }
+
+ public abstract class TextClassifier {
+ ctor public TextClassifier();
+ method @WorkerThread public androidx.textclassifier.TextClassification classifyText(androidx.textclassifier.TextClassification.Request);
+ method @WorkerThread public androidx.textclassifier.TextLinks generateLinks(androidx.textclassifier.TextLinks.Request);
+ method public int getMaxGenerateLinksTextLength();
+ method @WorkerThread public androidx.textclassifier.TextSelection suggestSelection(androidx.textclassifier.TextSelection.Request);
+ field public static final String HINT_TEXT_IS_EDITABLE = "android.text_is_editable";
+ field public static final String HINT_TEXT_IS_NOT_EDITABLE = "android.text_is_not_editable";
+ field public static final androidx.textclassifier.TextClassifier! NO_OP;
+ field public static final String TYPE_ADDRESS = "address";
+ field public static final String TYPE_DATE = "date";
+ field public static final String TYPE_DATE_TIME = "datetime";
+ field public static final String TYPE_EMAIL = "email";
+ field public static final String TYPE_FLIGHT_NUMBER = "flight";
+ field public static final String TYPE_OTHER = "other";
+ field public static final String TYPE_PHONE = "phone";
+ field public static final String TYPE_UNKNOWN = "";
+ field public static final String TYPE_URL = "url";
+ field public static final String WIDGET_TYPE_CUSTOM_EDITTEXT = "customedit";
+ field public static final String WIDGET_TYPE_CUSTOM_TEXTVIEW = "customview";
+ field public static final String WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW = "nosel-customview";
+ field public static final String WIDGET_TYPE_EDITTEXT = "edittext";
+ field public static final String WIDGET_TYPE_EDIT_WEBVIEW = "edit-webview";
+ field public static final String WIDGET_TYPE_TEXTVIEW = "textview";
+ field public static final String WIDGET_TYPE_UNKNOWN = "unknown";
+ field public static final String WIDGET_TYPE_UNSELECTABLE_TEXTVIEW = "nosel-textview";
+ field public static final String WIDGET_TYPE_WEBVIEW = "webview";
+ }
+
+ public static final class TextClassifier.EntityConfig {
+ method public static androidx.textclassifier.TextClassifier.EntityConfig createFromBundle(android.os.Bundle);
+ method public java.util.Collection<java.lang.String> getHints();
+ method public java.util.Collection<java.lang.String>! resolveEntityTypes(java.util.Collection<java.lang.String>?);
+ method public boolean shouldIncludeDefaultEntityTypes();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static final class TextClassifier.EntityConfig.Builder {
+ ctor public TextClassifier.EntityConfig.Builder();
+ method public androidx.textclassifier.TextClassifier.EntityConfig build();
+ method public androidx.textclassifier.TextClassifier.EntityConfig.Builder! setExcludedEntityTypes(java.util.Collection<java.lang.String>?);
+ method public androidx.textclassifier.TextClassifier.EntityConfig.Builder! setHints(java.util.Collection<java.lang.String>?);
+ method public androidx.textclassifier.TextClassifier.EntityConfig.Builder! setIncludeDefaultEntityTypes(boolean);
+ method public androidx.textclassifier.TextClassifier.EntityConfig.Builder! setIncludedEntityTypes(java.util.Collection<java.lang.String>?);
+ }
+
+ public final class TextLinks {
+ method public int apply(android.text.Spannable, androidx.textclassifier.TextClassifier, androidx.textclassifier.TextLinksParams);
+ method public static androidx.textclassifier.TextLinks createFromBundle(android.os.Bundle);
+ method public android.os.Bundle getExtras();
+ method public java.util.Collection<androidx.textclassifier.TextLinks.TextLink> getLinks();
+ method public android.os.Bundle toBundle();
+ field public static final int APPLY_STRATEGY_IGNORE = 0; // 0x0
+ field public static final int APPLY_STRATEGY_REPLACE = 1; // 0x1
+ field public static final int STATUS_DIFFERENT_TEXT = 3; // 0x3
+ field public static final int STATUS_LINKS_APPLIED = 0; // 0x0
+ field public static final int STATUS_NO_LINKS_APPLIED = 2; // 0x2
+ field public static final int STATUS_NO_LINKS_FOUND = 1; // 0x1
+ field public static final int STATUS_UNKNOWN = -1; // 0xffffffff
+ }
+
+ public static final class TextLinks.Builder {
+ ctor public TextLinks.Builder(CharSequence);
+ method public androidx.textclassifier.TextLinks.Builder addLink(int, int, java.util.Map<java.lang.String,java.lang.Float>);
+ method public androidx.textclassifier.TextLinks build();
+ method public androidx.textclassifier.TextLinks.Builder clearTextLinks();
+ method public androidx.textclassifier.TextLinks.Builder setExtras(android.os.Bundle?);
+ }
+
+ public static class TextLinks.DefaultTextLinkSpan extends androidx.textclassifier.TextLinks.TextLinkSpan {
+ ctor public TextLinks.DefaultTextLinkSpan(androidx.textclassifier.TextLinks.TextLinkSpanData);
+ method @CallSuper public void onClick(android.view.View);
+ method @UiThread public void onTextClassificationResult(android.widget.TextView, androidx.textclassifier.TextClassification);
+ }
+
+ public static final class TextLinks.Request {
+ method public static androidx.textclassifier.TextLinks.Request createFromBundle(android.os.Bundle);
+ method public androidx.core.os.LocaleListCompat? getDefaultLocales();
+ method public androidx.textclassifier.TextClassifier.EntityConfig getEntityConfig();
+ method public android.os.Bundle getExtras();
+ method public Long? getReferenceTime();
+ method public CharSequence getText();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static final class TextLinks.Request.Builder {
+ ctor public TextLinks.Request.Builder(CharSequence);
+ method public androidx.textclassifier.TextLinks.Request build();
+ method public androidx.textclassifier.TextLinks.Request.Builder setDefaultLocales(androidx.core.os.LocaleListCompat?);
+ method public androidx.textclassifier.TextLinks.Request.Builder setEntityConfig(androidx.textclassifier.TextClassifier.EntityConfig?);
+ method public androidx.textclassifier.TextLinks.Request.Builder setExtras(android.os.Bundle?);
+ method public androidx.textclassifier.TextLinks.Request.Builder setReferenceTime(Long?);
+ }
+
+ public static interface TextLinks.SpanFactory {
+ method public androidx.textclassifier.TextLinks.TextLinkSpan! createSpan(androidx.textclassifier.TextLinks.TextLinkSpanData);
+ }
+
+ public static final class TextLinks.TextLink {
+ method public static androidx.textclassifier.TextLinks.TextLink createFromBundle(android.os.Bundle);
+ method @FloatRange(from=0.0, to=1.0) public float getConfidenceScore(String!);
+ method public int getEnd();
+ method public String getEntity(int);
+ method public int getEntityCount();
+ method public int getStart();
+ method public android.os.Bundle toBundle();
+ }
+
+ public abstract static class TextLinks.TextLinkSpan extends android.text.style.ClickableSpan {
+ ctor public TextLinks.TextLinkSpan(androidx.textclassifier.TextLinks.TextLinkSpanData);
+ method public final androidx.textclassifier.TextLinks.TextLinkSpanData getTextLinkSpanData();
+ }
+
+ public static class TextLinks.TextLinkSpanData {
+ method public androidx.textclassifier.TextLinks.TextLink getTextLink();
+ }
+
+ public final class TextLinksParams {
+ field public static final androidx.textclassifier.TextLinksParams! DEFAULT_PARAMS;
+ }
+
+ public static final class TextLinksParams.Builder {
+ ctor public TextLinksParams.Builder();
+ method public androidx.textclassifier.TextLinksParams build();
+ method public androidx.textclassifier.TextLinksParams.Builder setApplyStrategy(int);
+ method public androidx.textclassifier.TextLinksParams.Builder setDefaultLocales(androidx.core.os.LocaleListCompat?);
+ method public androidx.textclassifier.TextLinksParams.Builder setEntityConfig(androidx.textclassifier.TextClassifier.EntityConfig?);
+ method public androidx.textclassifier.TextLinksParams.Builder setReferenceTime(Long?);
+ method public androidx.textclassifier.TextLinksParams.Builder setSpanFactory(androidx.textclassifier.TextLinks.SpanFactory?);
+ }
+
+ public final class TextSelection {
+ method public static androidx.textclassifier.TextSelection createFromBundle(android.os.Bundle);
+ method @FloatRange(from=0.0, to=1.0) public float getConfidenceScore(String!);
+ method public String getEntity(int);
+ method @IntRange(from=0) public int getEntityCount();
+ method public android.os.Bundle getExtras();
+ method public String? getId();
+ method public int getSelectionEndIndex();
+ method public int getSelectionStartIndex();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static final class TextSelection.Builder {
+ ctor public TextSelection.Builder(@IntRange(from=0) int, @IntRange(from=0) int);
+ method public androidx.textclassifier.TextSelection build();
+ method public androidx.textclassifier.TextSelection.Builder setEntityType(String, @FloatRange(from=0.0, to=1.0) float);
+ method public androidx.textclassifier.TextSelection.Builder setExtras(android.os.Bundle?);
+ method public androidx.textclassifier.TextSelection.Builder setId(String?);
+ }
+
+ public static final class TextSelection.Request {
+ method public static androidx.textclassifier.TextSelection.Request createFromBundle(android.os.Bundle);
+ method public androidx.core.os.LocaleListCompat? getDefaultLocales();
+ method @IntRange(from=0) public int getEndIndex();
+ method public android.os.Bundle getExtras();
+ method @IntRange(from=0) public int getStartIndex();
+ method public CharSequence getText();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static final class TextSelection.Request.Builder {
+ ctor public TextSelection.Request.Builder(CharSequence, @IntRange(from=0) int, @IntRange(from=0) int);
+ method public androidx.textclassifier.TextSelection.Request build();
+ method public androidx.textclassifier.TextSelection.Request.Builder setDefaultLocales(androidx.core.os.LocaleListCompat?);
+ method public androidx.textclassifier.TextSelection.Request.Builder setExtras(android.os.Bundle?);
+ }
+
+}
+
diff --git a/textclassifier/api/res-1.0.0-alpha02.txt b/textclassifier/api/res-1.0.0-alpha02.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/textclassifier/api/res-1.0.0-alpha02.txt
diff --git a/transition/api/1.1.0-alpha02.txt b/transition/api/1.1.0-alpha02.txt
new file mode 100644
index 0000000..62fcf63
--- /dev/null
+++ b/transition/api/1.1.0-alpha02.txt
@@ -0,0 +1,283 @@
+// Signature format: 2.0
+package androidx.transition {
+
+ public class ArcMotion extends androidx.transition.PathMotion {
+ ctor public ArcMotion();
+ ctor public ArcMotion(android.content.Context!, android.util.AttributeSet!);
+ method public float getMaximumAngle();
+ method public float getMinimumHorizontalAngle();
+ method public float getMinimumVerticalAngle();
+ method public android.graphics.Path! getPath(float, float, float, float);
+ method public void setMaximumAngle(float);
+ method public void setMinimumHorizontalAngle(float);
+ method public void setMinimumVerticalAngle(float);
+ }
+
+ public class AutoTransition extends androidx.transition.TransitionSet {
+ ctor public AutoTransition();
+ ctor public AutoTransition(android.content.Context!, android.util.AttributeSet!);
+ }
+
+ public class ChangeBounds extends androidx.transition.Transition {
+ ctor public ChangeBounds();
+ ctor public ChangeBounds(android.content.Context!, android.util.AttributeSet!);
+ method public void captureEndValues(androidx.transition.TransitionValues);
+ method public void captureStartValues(androidx.transition.TransitionValues);
+ method public boolean getResizeClip();
+ method public void setResizeClip(boolean);
+ }
+
+ public class ChangeClipBounds extends androidx.transition.Transition {
+ ctor public ChangeClipBounds();
+ ctor public ChangeClipBounds(android.content.Context!, android.util.AttributeSet!);
+ method public void captureEndValues(androidx.transition.TransitionValues);
+ method public void captureStartValues(androidx.transition.TransitionValues);
+ }
+
+ public class ChangeImageTransform extends androidx.transition.Transition {
+ ctor public ChangeImageTransform();
+ ctor public ChangeImageTransform(android.content.Context!, android.util.AttributeSet!);
+ method public void captureEndValues(androidx.transition.TransitionValues);
+ method public void captureStartValues(androidx.transition.TransitionValues);
+ }
+
+ public class ChangeScroll extends androidx.transition.Transition {
+ ctor public ChangeScroll();
+ ctor public ChangeScroll(android.content.Context!, android.util.AttributeSet!);
+ method public void captureEndValues(androidx.transition.TransitionValues);
+ method public void captureStartValues(androidx.transition.TransitionValues);
+ }
+
+ public class ChangeTransform extends androidx.transition.Transition {
+ ctor public ChangeTransform();
+ ctor public ChangeTransform(android.content.Context!, android.util.AttributeSet!);
+ method public void captureEndValues(androidx.transition.TransitionValues);
+ method public void captureStartValues(androidx.transition.TransitionValues);
+ method public boolean getReparent();
+ method public boolean getReparentWithOverlay();
+ method public void setReparent(boolean);
+ method public void setReparentWithOverlay(boolean);
+ }
+
+ public class CircularPropagation extends androidx.transition.VisibilityPropagation {
+ ctor public CircularPropagation();
+ method public long getStartDelay(android.view.ViewGroup!, androidx.transition.Transition!, androidx.transition.TransitionValues!, androidx.transition.TransitionValues!);
+ method public void setPropagationSpeed(float);
+ }
+
+ public class Explode extends androidx.transition.Visibility {
+ ctor public Explode();
+ ctor public Explode(android.content.Context!, android.util.AttributeSet!);
+ }
+
+ public class Fade extends androidx.transition.Visibility {
+ ctor public Fade(int);
+ ctor public Fade();
+ ctor public Fade(android.content.Context!, android.util.AttributeSet!);
+ field public static final int IN = 1; // 0x1
+ field public static final int OUT = 2; // 0x2
+ }
+
+ public abstract class PathMotion {
+ ctor public PathMotion();
+ ctor public PathMotion(android.content.Context!, android.util.AttributeSet!);
+ method public abstract android.graphics.Path! getPath(float, float, float, float);
+ }
+
+ public class PatternPathMotion extends androidx.transition.PathMotion {
+ ctor public PatternPathMotion();
+ ctor public PatternPathMotion(android.content.Context!, android.util.AttributeSet!);
+ ctor public PatternPathMotion(android.graphics.Path!);
+ method public android.graphics.Path! getPath(float, float, float, float);
+ method public android.graphics.Path! getPatternPath();
+ method public void setPatternPath(android.graphics.Path!);
+ }
+
+ public class Scene {
+ ctor public Scene(android.view.ViewGroup);
+ ctor public Scene(android.view.ViewGroup, android.view.View);
+ method public void enter();
+ method public void exit();
+ method public static androidx.transition.Scene? getCurrentScene(android.view.View);
+ method public static androidx.transition.Scene getSceneForLayout(android.view.ViewGroup, @LayoutRes int, android.content.Context);
+ method public android.view.ViewGroup getSceneRoot();
+ method public void setEnterAction(Runnable?);
+ method public void setExitAction(Runnable?);
+ }
+
+ public class SidePropagation extends androidx.transition.VisibilityPropagation {
+ ctor public SidePropagation();
+ method public long getStartDelay(android.view.ViewGroup!, androidx.transition.Transition!, androidx.transition.TransitionValues!, androidx.transition.TransitionValues!);
+ method public void setPropagationSpeed(float);
+ method public void setSide(int);
+ }
+
+ public class Slide extends androidx.transition.Visibility {
+ ctor public Slide();
+ ctor public Slide(int);
+ ctor public Slide(android.content.Context!, android.util.AttributeSet!);
+ method public int getSlideEdge();
+ method public void setSlideEdge(int);
+ }
+
+ public abstract class Transition implements java.lang.Cloneable {
+ ctor public Transition();
+ ctor public Transition(android.content.Context!, android.util.AttributeSet!);
+ method public androidx.transition.Transition addListener(androidx.transition.Transition.TransitionListener);
+ method public androidx.transition.Transition addTarget(android.view.View);
+ method public androidx.transition.Transition addTarget(@IdRes int);
+ method public androidx.transition.Transition addTarget(String);
+ method public androidx.transition.Transition addTarget(Class);
+ method public abstract void captureEndValues(androidx.transition.TransitionValues);
+ method public abstract void captureStartValues(androidx.transition.TransitionValues);
+ method public androidx.transition.Transition! clone();
+ method public android.animation.Animator? createAnimator(android.view.ViewGroup, androidx.transition.TransitionValues?, androidx.transition.TransitionValues?);
+ method public androidx.transition.Transition excludeChildren(android.view.View, boolean);
+ method public androidx.transition.Transition excludeChildren(@IdRes int, boolean);
+ method public androidx.transition.Transition excludeChildren(Class, boolean);
+ method public androidx.transition.Transition excludeTarget(android.view.View, boolean);
+ method public androidx.transition.Transition excludeTarget(@IdRes int, boolean);
+ method public androidx.transition.Transition excludeTarget(String, boolean);
+ method public androidx.transition.Transition excludeTarget(Class, boolean);
+ method public long getDuration();
+ method public android.graphics.Rect? getEpicenter();
+ method public androidx.transition.Transition.EpicenterCallback? getEpicenterCallback();
+ method public android.animation.TimeInterpolator? getInterpolator();
+ method public String getName();
+ method public androidx.transition.PathMotion getPathMotion();
+ method public androidx.transition.TransitionPropagation? getPropagation();
+ method public long getStartDelay();
+ method public java.util.List<java.lang.Integer> getTargetIds();
+ method public java.util.List<java.lang.String>? getTargetNames();
+ method public java.util.List<java.lang.Class>? getTargetTypes();
+ method public java.util.List<android.view.View> getTargets();
+ method public String[]? getTransitionProperties();
+ method public androidx.transition.TransitionValues? getTransitionValues(android.view.View, boolean);
+ method public boolean isTransitionRequired(androidx.transition.TransitionValues?, androidx.transition.TransitionValues?);
+ method public androidx.transition.Transition removeListener(androidx.transition.Transition.TransitionListener);
+ method public androidx.transition.Transition removeTarget(android.view.View);
+ method public androidx.transition.Transition removeTarget(@IdRes int);
+ method public androidx.transition.Transition removeTarget(String);
+ method public androidx.transition.Transition removeTarget(Class);
+ method public androidx.transition.Transition setDuration(long);
+ method public void setEpicenterCallback(androidx.transition.Transition.EpicenterCallback?);
+ method public androidx.transition.Transition setInterpolator(android.animation.TimeInterpolator?);
+ method public void setMatchOrder(int...!);
+ method public void setPathMotion(androidx.transition.PathMotion?);
+ method public void setPropagation(androidx.transition.TransitionPropagation?);
+ method public androidx.transition.Transition setStartDelay(long);
+ field public static final int MATCH_ID = 3; // 0x3
+ field public static final int MATCH_INSTANCE = 1; // 0x1
+ field public static final int MATCH_ITEM_ID = 4; // 0x4
+ field public static final int MATCH_NAME = 2; // 0x2
+ }
+
+ public abstract static class Transition.EpicenterCallback {
+ ctor public Transition.EpicenterCallback();
+ method public abstract android.graphics.Rect! onGetEpicenter(androidx.transition.Transition);
+ }
+
+ public static interface Transition.TransitionListener {
+ method public void onTransitionCancel(androidx.transition.Transition);
+ method public void onTransitionEnd(androidx.transition.Transition);
+ method public void onTransitionPause(androidx.transition.Transition);
+ method public void onTransitionResume(androidx.transition.Transition);
+ method public void onTransitionStart(androidx.transition.Transition);
+ }
+
+ public class TransitionInflater {
+ method public static androidx.transition.TransitionInflater! from(android.content.Context!);
+ method public androidx.transition.Transition! inflateTransition(int);
+ method public androidx.transition.TransitionManager! inflateTransitionManager(int, android.view.ViewGroup!);
+ }
+
+ public class TransitionListenerAdapter implements androidx.transition.Transition.TransitionListener {
+ ctor public TransitionListenerAdapter();
+ method public void onTransitionCancel(androidx.transition.Transition);
+ method public void onTransitionEnd(androidx.transition.Transition);
+ method public void onTransitionPause(androidx.transition.Transition);
+ method public void onTransitionResume(androidx.transition.Transition);
+ method public void onTransitionStart(androidx.transition.Transition);
+ }
+
+ public class TransitionManager {
+ ctor public TransitionManager();
+ method public static void beginDelayedTransition(android.view.ViewGroup);
+ method public static void beginDelayedTransition(android.view.ViewGroup, androidx.transition.Transition?);
+ method public static void endTransitions(android.view.ViewGroup!);
+ method public static void go(androidx.transition.Scene);
+ method public static void go(androidx.transition.Scene, androidx.transition.Transition?);
+ method public void setTransition(androidx.transition.Scene, androidx.transition.Transition?);
+ method public void setTransition(androidx.transition.Scene, androidx.transition.Scene, androidx.transition.Transition?);
+ method public void transitionTo(androidx.transition.Scene);
+ }
+
+ public abstract class TransitionPropagation {
+ ctor public TransitionPropagation();
+ method public abstract void captureValues(androidx.transition.TransitionValues!);
+ method public abstract String[]! getPropagationProperties();
+ method public abstract long getStartDelay(android.view.ViewGroup!, androidx.transition.Transition!, androidx.transition.TransitionValues!, androidx.transition.TransitionValues!);
+ }
+
+ public class TransitionSet extends androidx.transition.Transition {
+ ctor public TransitionSet();
+ ctor public TransitionSet(android.content.Context!, android.util.AttributeSet!);
+ method public androidx.transition.TransitionSet addListener(androidx.transition.Transition.TransitionListener);
+ method public androidx.transition.TransitionSet addTarget(android.view.View);
+ method public androidx.transition.TransitionSet addTarget(@IdRes int);
+ method public androidx.transition.TransitionSet addTarget(String);
+ method public androidx.transition.TransitionSet addTarget(Class);
+ method public androidx.transition.TransitionSet addTransition(androidx.transition.Transition);
+ method public void captureEndValues(androidx.transition.TransitionValues);
+ method public void captureStartValues(androidx.transition.TransitionValues);
+ method public int getOrdering();
+ method public androidx.transition.Transition? getTransitionAt(int);
+ method public int getTransitionCount();
+ method public androidx.transition.TransitionSet removeListener(androidx.transition.Transition.TransitionListener);
+ method public androidx.transition.TransitionSet removeTarget(@IdRes int);
+ method public androidx.transition.TransitionSet removeTarget(android.view.View);
+ method public androidx.transition.TransitionSet removeTarget(Class);
+ method public androidx.transition.TransitionSet removeTarget(String);
+ method public androidx.transition.TransitionSet removeTransition(androidx.transition.Transition);
+ method public androidx.transition.TransitionSet setDuration(long);
+ method public androidx.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator?);
+ method public androidx.transition.TransitionSet setOrdering(int);
+ method public androidx.transition.TransitionSet setStartDelay(long);
+ field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
+ field public static final int ORDERING_TOGETHER = 0; // 0x0
+ }
+
+ public class TransitionValues {
+ ctor @Deprecated public TransitionValues();
+ ctor public TransitionValues(android.view.View);
+ field public final java.util.Map<java.lang.String,java.lang.Object>! values;
+ field public android.view.View! view;
+ }
+
+ public abstract class Visibility extends androidx.transition.Transition {
+ ctor public Visibility();
+ ctor public Visibility(android.content.Context!, android.util.AttributeSet!);
+ method public void captureEndValues(androidx.transition.TransitionValues);
+ method public void captureStartValues(androidx.transition.TransitionValues);
+ method public int getMode();
+ method public boolean isVisible(androidx.transition.TransitionValues!);
+ method public android.animation.Animator! onAppear(android.view.ViewGroup!, androidx.transition.TransitionValues!, int, androidx.transition.TransitionValues!, int);
+ method public android.animation.Animator! onAppear(android.view.ViewGroup!, android.view.View!, androidx.transition.TransitionValues!, androidx.transition.TransitionValues!);
+ method public android.animation.Animator! onDisappear(android.view.ViewGroup!, androidx.transition.TransitionValues!, int, androidx.transition.TransitionValues!, int);
+ method public android.animation.Animator! onDisappear(android.view.ViewGroup!, android.view.View!, androidx.transition.TransitionValues!, androidx.transition.TransitionValues!);
+ method public void setMode(int);
+ field public static final int MODE_IN = 1; // 0x1
+ field public static final int MODE_OUT = 2; // 0x2
+ }
+
+ public abstract class VisibilityPropagation extends androidx.transition.TransitionPropagation {
+ ctor public VisibilityPropagation();
+ method public void captureValues(androidx.transition.TransitionValues!);
+ method public String[]! getPropagationProperties();
+ method public int getViewVisibility(androidx.transition.TransitionValues!);
+ method public int getViewX(androidx.transition.TransitionValues!);
+ method public int getViewY(androidx.transition.TransitionValues!);
+ }
+
+}
+
diff --git a/transition/api/res-1.1.0-alpha02.txt b/transition/api/res-1.1.0-alpha02.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/transition/api/res-1.1.0-alpha02.txt
diff --git a/transition/src/androidTest/java/androidx/transition/ExplodeTest.java b/transition/src/androidTest/java/androidx/transition/ExplodeTest.java
index 575f583..cc1edd2 100644
--- a/transition/src/androidTest/java/androidx/transition/ExplodeTest.java
+++ b/transition/src/androidTest/java/androidx/transition/ExplodeTest.java
@@ -81,7 +81,8 @@
});
}
- @Test
+ // Temporarily disabled due to b/118137165.
+ // @Test
public void testExplode() throws Throwable {
rule.runOnUiThread(new Runnable() {
@Override
@@ -115,7 +116,8 @@
assertEquals(View.INVISIBLE, mYellowSquare.getVisibility());
}
- @Test
+ // Temporarily disabled due to b/112005299.
+ // @Test
public void testImplode() throws Throwable {
rule.runOnUiThread(new Runnable() {
@Override
diff --git a/versionedparcelable/src/main/java/androidx/versionedparcelable/ParcelImpl.java b/versionedparcelable/src/main/java/androidx/versionedparcelable/ParcelImpl.java
index 40ff1e7..a4bcb20 100644
--- a/versionedparcelable/src/main/java/androidx/versionedparcelable/ParcelImpl.java
+++ b/versionedparcelable/src/main/java/androidx/versionedparcelable/ParcelImpl.java
@@ -27,7 +27,6 @@
*/
@RestrictTo(RestrictTo.Scope.LIBRARY)
@SuppressLint("BanParcelableUsage")
-@SuppressWarnings("BanParcelableUsage")
public class ParcelImpl implements Parcelable {
private final VersionedParcelable mParcel;
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
index 8f858d3..adf171f 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
@@ -327,7 +327,6 @@
* Return whether this {@link WebViewFeatureInternal} is supported by the framework of the
* current device.
*/
- @SuppressWarnings("BanUnlistedSDKVersionComparison")
public boolean isSupportedByFramework() {
if (mOsVersion == NOT_SUPPORTED_BY_FRAMEWORK) {
return false;
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
index 5655583..07dd976 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
@@ -30,6 +30,7 @@
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.isOneOf;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
@@ -452,6 +453,43 @@
@Test
@SmallTest
+ public void testDependencies_enqueuesBlockedDependentsOnSuccess() {
+ OneTimeWorkRequest prerequisiteWork =
+ new OneTimeWorkRequest.Builder(TestWorker.class).build();
+ OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
+ .setInitialState(BLOCKED)
+ .build();
+ OneTimeWorkRequest cancelledWork = new OneTimeWorkRequest.Builder(TestWorker.class)
+ .setInitialState(CANCELLED)
+ .build();
+ Dependency dependency1 = new Dependency(work.getStringId(), prerequisiteWork.getStringId());
+ Dependency dependency2 =
+ new Dependency(cancelledWork.getStringId(), prerequisiteWork.getStringId());
+
+ mDatabase.beginTransaction();
+ try {
+ insertWork(prerequisiteWork);
+ insertWork(work);
+ insertWork(cancelledWork);
+ mDependencyDao.insertDependency(dependency1);
+ mDependencyDao.insertDependency(dependency2);
+ mDatabase.setTransactionSuccessful();
+ } finally {
+ mDatabase.endTransaction();
+ }
+
+ createBuilder(prerequisiteWork.getStringId())
+ .build()
+ .run();
+
+ assertThat(mWorkSpecDao.getState(prerequisiteWork.getStringId()), is(SUCCEEDED));
+ assertThat(mWorkSpecDao.getState(work.getStringId()),
+ isOneOf(ENQUEUED, RUNNING, SUCCEEDED));
+ assertThat(mWorkSpecDao.getState(cancelledWork.getStringId()), is(CANCELLED));
+ }
+
+ @Test
+ @SmallTest
public void testDependencies_failsUncancelledDependentsOnFailure() {
OneTimeWorkRequest prerequisiteWork =
new OneTimeWorkRequest.Builder(FailureWorker.class).build();
diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkerWrapper.java b/work/workmanager/src/main/java/androidx/work/impl/WorkerWrapper.java
index 913b493..f39a658 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/WorkerWrapper.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/WorkerWrapper.java
@@ -16,6 +16,7 @@
package androidx.work.impl;
+import static androidx.work.WorkInfo.State.BLOCKED;
import static androidx.work.WorkInfo.State.CANCELLED;
import static androidx.work.WorkInfo.State.ENQUEUED;
import static androidx.work.WorkInfo.State.FAILED;
@@ -529,7 +530,8 @@
long currentTimeMillis = System.currentTimeMillis();
List<String> dependentWorkIds = mDependencyDao.getDependentWorkIds(mWorkSpecId);
for (String dependentWorkId : dependentWorkIds) {
- if (mDependencyDao.hasCompletedAllPrerequisites(dependentWorkId)) {
+ if (mWorkSpecDao.getState(dependentWorkId) == BLOCKED
+ && mDependencyDao.hasCompletedAllPrerequisites(dependentWorkId)) {
Logger.get().info(TAG,
String.format("Setting status to enqueued for %s", dependentWorkId));
mWorkSpecDao.setState(ENQUEUED, dependentWorkId);