Merge "Enforcing a NON NULL constraint on the PrimaryKey" into oc-mr1-dev
diff --git a/app-toolkit/core-testing/build.gradle b/app-toolkit/core-testing/build.gradle
index 710ccbe..44d5ff0 100644
--- a/app-toolkit/core-testing/build.gradle
+++ b/app-toolkit/core-testing/build.gradle
@@ -39,7 +39,6 @@
dependencies {
compile project(":arch:runtime")
compile libs.support.annotations
- compile libs.support.core_utils
compile(libs.junit) {
exclude module: 'hamcrest-core'
}
diff --git a/app-toolkit/dependencies.gradle b/app-toolkit/dependencies.gradle
index 755c3d0..083325b 100644
--- a/app-toolkit/dependencies.gradle
+++ b/app-toolkit/dependencies.gradle
@@ -26,7 +26,7 @@
ffVersions.auto_common = "0.6"
ffVersions.javapoet = "1.8.0"
ffVersions.compile_testing = "0.11"
-ffVersions.support_lib = "26.0.0"
+ffVersions.support_lib = "26.1.0"
ffVersions.intellij_annotations = "12.0"
ffVersions.rxjava2 = "2.0.6"
ffVersions.reactivestreams = "1.0.0"
@@ -69,6 +69,11 @@
recyclerview : getSupportLib(':recyclerview-v7', ffVersions.support_lib)
]
+ffLibs.support_exclude_config = {
+ exclude group: 'android.arch.core'
+ exclude group: 'android.arch.lifecycle'
+}
+
ffLibs.javapoet = "com.squareup:javapoet:$ffVersions.javapoet"
ffLibs.antlr = "org.antlr:antlr4:$ffVersions.antlr"
ffLibs.xerial = "org.xerial:sqlite-jdbc:$ffVersions.xerial"
diff --git a/app-toolkit/init.gradle b/app-toolkit/init.gradle
index aeb9718..8f60355 100644
--- a/app-toolkit/init.gradle
+++ b/app-toolkit/init.gradle
@@ -94,6 +94,7 @@
rootProject.ext.flatfootProjectGroups = [
"room" : "android.arch.persistence.room",
+ "persistence" : "android.arch.persistence",
"lifecycle" : "android.arch.lifecycle",
"arch" : "android.arch.core",
"paging" : "android.arch.paging",
diff --git a/app-toolkit/settings.gradle b/app-toolkit/settings.gradle
index 0977dc6..31fc0e1 100644
--- a/app-toolkit/settings.gradle
+++ b/app-toolkit/settings.gradle
@@ -75,11 +75,11 @@
include ':room:migration'
project(':room:migration').projectDir = new File(supportRoot, "room/migration")
-include ':room:db'
-project(':room:db').projectDir = new File(supportRoot, "room/db")
+include ':persistence:db'
+project(':persistence:db').projectDir = new File(supportRoot, "persistence/db")
-include ":room:db-impl"
-project(':room:db-impl').projectDir = new File(supportRoot, "room/db-impl")
+include ":persistence:db-framework"
+project(':persistence:db-framework').projectDir = new File(supportRoot, "persistence/db-framework")
include ":room:testing"
project(':room:testing').projectDir = new File(supportRoot, "room/testing")
diff --git a/buildSrc/src/main/groovy/android/support/SupportKotlinLibraryPlugin.groovy b/buildSrc/src/main/groovy/android/support/SupportKotlinLibraryPlugin.groovy
new file mode 100644
index 0000000..237aa97
--- /dev/null
+++ b/buildSrc/src/main/groovy/android/support/SupportKotlinLibraryPlugin.groovy
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support
+
+import com.google.common.collect.ImmutableMap
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+/**
+ * Support kotlin library specific plugin that sets common configurations needed for
+ * support library modules.
+ */
+class SupportKotlinLibraryPlugin implements Plugin<Project> {
+ @Override
+ public void apply(Project project) {
+ SupportLibraryExtension supportLibraryExtension =
+ project.extensions.create("supportLibrary", SupportLibraryExtension, project);
+ SupportLibraryMavenUploader.apply(project, supportLibraryExtension);
+
+ project.apply(ImmutableMap.of("plugin", "kotlin"));
+ project.apply(ImmutableMap.of("plugin", "kotlin-kapt"));
+
+ project.compileJava {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ }
+}
\ No newline at end of file
diff --git a/compat/api/current.txt b/compat/api/current.txt
index 8dea70f..c4e7fd3 100644
--- a/compat/api/current.txt
+++ b/compat/api/current.txt
@@ -838,7 +838,7 @@
method public static deprecated boolean isAtLeastN();
method public static deprecated boolean isAtLeastNMR1();
method public static deprecated boolean isAtLeastO();
- method public static boolean isAtLeastOMR1();
+ method public static deprecated boolean isAtLeastOMR1();
method public static boolean isAtLeastP();
}
@@ -1651,7 +1651,7 @@
method public static void setBackground(android.view.View, android.graphics.drawable.Drawable);
method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList);
method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode);
- method public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup, boolean);
+ method public static deprecated void setChildrenDrawingOrderEnabled(android.view.ViewGroup, boolean);
method public static void setClipBounds(android.view.View, android.graphics.Rect);
method public static void setElevation(android.view.View, float);
method public static deprecated void setFitsSystemWindows(android.view.View, boolean);
diff --git a/compat/java/android/support/v4/os/BuildCompat.java b/compat/java/android/support/v4/os/BuildCompat.java
index 9a48c5f..586557d 100644
--- a/compat/java/android/support/v4/os/BuildCompat.java
+++ b/compat/java/android/support/v4/os/BuildCompat.java
@@ -60,6 +60,7 @@
* be removed in a future release of the Support Library. Instead use
* {@code Build.SDK_INT >= Build.VERSION_CODES#O}.
*/
+ @Deprecated
public static boolean isAtLeastO() {
return VERSION.SDK_INT >= 26;
}
@@ -68,7 +69,11 @@
* Checks if the device is running on a pre-release version of Android O MR1 or newer.
* <p>
* @return {@code true} if O MR1 APIs are available for use, {@code false} otherwise
+ * @deprecated Android O MR1 is a finalized release and this method is no longer necessary. It
+ * will be removed in a future release of the Support Library. Instead, use
+ * {@code Build.SDK_INT >= Build.VERSION_CODES#O_MR1}.
*/
+ @Deprecated
public static boolean isAtLeastOMR1() {
return VERSION.SDK_INT >= 27;
}
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index e7443d7..34a198a 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -3029,7 +3029,10 @@
* {@link ViewGroup#getChildDrawingOrder(int, int)}, false otherwise
*
* <p>Prior to API 7 this will have no effect.</p>
+ *
+ * @deprecated Use {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean)} directly.
*/
+ @Deprecated
public static void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
IMPL.setChildrenDrawingOrderEnabled(viewGroup, enabled);
}
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
index f9329fa..327be01 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -1863,7 +1863,7 @@
}
/**
- * Sets whether this node is visible to the user.
+ * Gets whether this node is visible to the user.
*
* @return Whether the node is visible to the user.
*/
diff --git a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
index d36ae22..2181bab 100644
--- a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -341,7 +341,7 @@
mCircleDiameter = (int) (CIRCLE_DIAMETER * metrics.density);
createProgressView();
- ViewCompat.setChildrenDrawingOrderEnabled(this, true);
+ setChildrenDrawingOrderEnabled(true);
// the absolute offset has to take into account that the circle starts at an offset
mSpinnerOffsetEnd = (int) (DEFAULT_CIRCLE_TARGET * metrics.density);
mTotalDragDistance = mSpinnerOffsetEnd;
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 20e8d9e..6e6caa0 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -1594,6 +1594,8 @@
private void animateRemoveFragment(@NonNull final Fragment fragment,
@NonNull AnimationOrAnimator anim, final int newState) {
final View viewToAnimate = fragment.mView;
+ final ViewGroup container = fragment.mContainer;
+ container.startViewTransition(viewToAnimate);
fragment.setStateAfterAnimating(newState);
if (anim.animation != null) {
Animation animation = anim.animation;
@@ -1603,6 +1605,8 @@
@Override
public void onAnimationEnd(Animation animation) {
super.onAnimationEnd(animation);
+ container.endViewTransition(viewToAnimate);
+
if (fragment.getAnimatingAway() != null) {
fragment.setAnimatingAway(null);
moveToState(fragment, fragment.getStateAfterAnimating(), 0, 0, false);
@@ -1612,25 +1616,18 @@
setHWLayerAnimListenerIfAlpha(viewToAnimate, anim);
fragment.mView.startAnimation(animation);
} else {
- final Animator animator = anim.animator;
+ Animator animator = anim.animator;
fragment.setAnimator(anim.animator);
- final ViewGroup container = fragment.mContainer;
- if (container != null) {
- container.startViewTransition(viewToAnimate);
- }
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator anim) {
- // AnimatorSet in API 26 (only) can end() during start(), so delay by posting
- if (container == null || container.indexOfChild(viewToAnimate) < 0) {
- finishAnimatedFragmentRemoval(fragment, container, viewToAnimate);
- } else {
- viewToAnimate.post(new Runnable() {
- @Override
- public void run() {
- finishAnimatedFragmentRemoval(fragment, container, viewToAnimate);
- }
- });
+ container.endViewTransition(viewToAnimate);
+ // If an animator ends immediately, we can just pretend there is no animation.
+ // When that happens the the fragment's view won't have been removed yet.
+ Animator animator = fragment.getAnimator();
+ fragment.setAnimator(null);
+ if (animator != null && container.indexOfChild(viewToAnimate) < 0) {
+ moveToState(fragment, fragment.getStateAfterAnimating(), 0, 0, false);
}
}
});
@@ -1640,17 +1637,6 @@
}
}
- void finishAnimatedFragmentRemoval(Fragment fragment, ViewGroup container, View view) {
- if (container != null) {
- container.endViewTransition(view);
- }
- if (fragment.getAnimator() != null) {
- fragment.setAnimator(null);
- moveToState(fragment, fragment.getStateAfterAnimating(), 0, 0,
- false);
- }
- }
-
void moveToState(Fragment f) {
moveToState(f, mCurState, 0, 0, false);
}
@@ -2646,7 +2632,6 @@
// Give up waiting for the animation and just end it.
final int stateAfterAnimating = fragment.getStateAfterAnimating();
final View animatingAway = fragment.getAnimatingAway();
- fragment.setAnimatingAway(null);
Animation animation = animatingAway.getAnimation();
if (animation != null) {
animation.cancel();
@@ -2654,6 +2639,7 @@
// and will instead cause the animation to infinitely loop
animatingAway.clearAnimation();
}
+ fragment.setAnimatingAway(null);
moveToState(fragment, stateAfterAnimating, 0, 0, false);
} else if (fragment.getAnimator() != null) {
fragment.getAnimator().end();
diff --git a/lifecycle/compiler/build.gradle b/lifecycle/compiler/build.gradle
index b1477f5..44bf15d 100644
--- a/lifecycle/compiler/build.gradle
+++ b/lifecycle/compiler/build.gradle
@@ -1,8 +1,6 @@
import android.support.LibraryVersions
-
-apply plugin: 'kotlin'
-apply plugin: 'maven'
-apply plugin: 'checkstyle'
+import android.support.SupportLibraryExtension
+apply plugin: android.support.SupportKotlinLibraryPlugin
sourceSets {
test.java.srcDirs += 'src/tests/kotlin'
@@ -27,3 +25,11 @@
version = LibraryVersions.LIFECYCLES_EXT.toString()
createKotlinCheckstyle(project)
+
+supportLibrary {
+ name 'Android Lifecycles Compiler'
+ publish true
+ inceptionYear '2017'
+ description "Android Lifecycles annotation processor"
+ url SupportLibraryExtension.ARCHITECTURE_URL
+}
diff --git a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt
index dca78d5..4f12ff4 100644
--- a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt
+++ b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt
@@ -30,6 +30,7 @@
import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
+import javax.tools.StandardLocation
fun writeModels(infos: List<AdapterClass>, processingEnv: ProcessingEnvironment) {
infos.forEach({ writeAdapter(it, processingEnv) })
@@ -116,6 +117,8 @@
JavaFile.builder(adapter.type.getPackageQName(), adapterTypeSpecBuilder.build())
.build().writeTo(processingEnv.filer)
+
+ generateKeepRule(adapter.type, processingEnv)
}
private fun addGeneratedAnnotationIfAvailable(adapterTypeSpecBuilder: TypeSpec.Builder,
@@ -133,6 +136,25 @@
}
}
+private fun generateKeepRule(type: TypeElement, processingEnv: ProcessingEnvironment) {
+ val adapterClass = type.getPackageQName() + "." + getAdapterName(type)
+ val observerClass = type.toString()
+ val keepRule = """# Generated keep rule for Lifecycle observer adapter.
+ |-keep class $adapterClass {
+ | ifused class $observerClass {
+ | <init>(...);
+ | };
+ |}
+ |""".trimMargin()
+
+ // Write the keep rule to the META-INF/proguard directory of the Jar file. The file name
+ // contains the fully qualified observer name so that file names are unique. This will allow any
+ // jar file merging to not overwrite keep rule files.
+ val path = "META-INF/proguard/$observerClass.pro"
+ val out = processingEnv.filer.createResource(StandardLocation.CLASS_OUTPUT, "", path)
+ out.openWriter().use { it.write(keepRule) }
+}
+
private fun MethodSpec.Builder.writeMethodCalls(eventParam: ParameterSpec,
calls: List<EventMethodCall>,
ownerParam: ParameterSpec,
diff --git a/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt b/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt
index 66429a2..247d416 100644
--- a/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt
+++ b/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt
@@ -18,9 +18,11 @@
import android.arch.lifecycle.utils.load
import android.arch.lifecycle.utils.processClass
+import com.google.testing.compile.CompileTester
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import javax.tools.StandardLocation
@RunWith(JUnit4::class)
class ValidCasesTest {
@@ -33,7 +35,7 @@
fun testOnAny() {
processClass("foo.OnAnyMethod").compilesWithoutError().and().generatesSources(
load("foo.OnAnyMethod_LifecycleAdapter", "expected")
- )
+ ).and().generatesProGuardRule("foo.OnAnyMethod.pro")
}
@Test
@@ -47,6 +49,8 @@
load("foo.InheritanceOk2Base_LifecycleAdapter", "expected"),
load("foo.InheritanceOk2Derived_LifecycleAdapter", "expected")
)
+ .and().generatesProGuardRule("foo.InheritanceOk2Base.pro")
+ .and().generatesProGuardRule("foo.InheritanceOk2Derived.pro")
}
@Test
@@ -55,6 +59,8 @@
load("foo.InheritanceOk3Base_LifecycleAdapter", "expected"),
load("foo.InheritanceOk3Derived_LifecycleAdapter", "expected")
)
+ .and().generatesProGuardRule("foo.InheritanceOk3Base.pro")
+ .and().generatesProGuardRule("foo.InheritanceOk3Derived.pro")
}
@Test
@@ -74,6 +80,9 @@
load("foo.InterfaceOk2Derived_LifecycleAdapter", "expected"),
load("foo.InterfaceOk2Interface_LifecycleAdapter", "expected")
)
+ .and().generatesProGuardRule("foo.InterfaceOk2Base.pro")
+ .and().generatesProGuardRule("foo.InterfaceOk2Derived.pro")
+ .and().generatesProGuardRule("foo.InterfaceOk2Interface.pro")
}
@Test
@@ -83,6 +92,8 @@
load("foo.DifferentPackagesBase1_LifecycleAdapter", "expected"),
load("bar.DifferentPackagesDerived1_LifecycleAdapter", "expected")
)
+ .and().generatesProGuardRule("foo.DifferentPackagesBase1.pro")
+ .and().generatesProGuardRule("bar.DifferentPackagesDerived1.pro")
}
@Test
@@ -92,5 +103,13 @@
load("foo.DifferentPackagesBase2_LifecycleAdapter", "expected"),
load("bar.DifferentPackagesDerived2_LifecycleAdapter", "expected")
)
+ .and().generatesProGuardRule("foo.DifferentPackagesPreBase2.pro")
+ .and().generatesProGuardRule("foo.DifferentPackagesBase2.pro")
+ .and().generatesProGuardRule("bar.DifferentPackagesDerived2.pro")
+ }
+
+ private fun <T> CompileTester.GeneratedPredicateClause<T>.generatesProGuardRule(name: String):
+ CompileTester.SuccessfulFileClause<T> {
+ return generatesFileNamed(StandardLocation.CLASS_OUTPUT, "", "META-INF/proguard/$name")
}
}
diff --git a/lifecycle/extensions/build.gradle b/lifecycle/extensions/build.gradle
index 9f61b73..241e99a 100644
--- a/lifecycle/extensions/build.gradle
+++ b/lifecycle/extensions/build.gradle
@@ -43,7 +43,7 @@
compile project(":lifecycle:runtime")
compile project(":arch:common")
compile project(":arch:runtime")
- compile libs.support.fragments
+ compile libs.support.fragments, libs.support_exclude_config
annotationProcessor project(":lifecycle:compiler")
@@ -53,7 +53,7 @@
androidTestImplementation libs.test_runner, { exclude module: 'support-annotations' }
androidTestImplementation libs.espresso_core, { exclude module: 'support-annotations' }
- androidTestImplementation libs.support.app_compat
+ androidTestImplementation libs.support.app_compat, libs.support_exclude_config
}
createAndroidCheckstyle(project)
diff --git a/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleActivity.java b/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleActivity.java
index 196a8d7..26bd508 100644
--- a/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleActivity.java
+++ b/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleActivity.java
@@ -19,17 +19,8 @@
import android.support.v4.app.FragmentActivity;
/**
- * Activity that implements {@link LifecycleOwner}.
- * <p>
- * This class is a temporary implementation detail until Lifecycles are integrated with support
- * library.
+ * @deprecated Use {@code android.support.v7.app.AppCompatActivity} instead of this class.
*/
-public class LifecycleActivity extends FragmentActivity implements LifecycleRegistryOwner {
-
- private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
-
- @Override
- public LifecycleRegistry getLifecycle() {
- return mRegistry;
- }
+@Deprecated
+public class LifecycleActivity extends FragmentActivity {
}
diff --git a/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleFragment.java b/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleFragment.java
index d8dbf38..c0da66b 100644
--- a/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleFragment.java
+++ b/lifecycle/extensions/src/main/java/android/arch/lifecycle/LifecycleFragment.java
@@ -19,17 +19,8 @@
import android.support.v4.app.Fragment;
/**
- * A fragment that is also a {@link LifecycleOwner}.
- * <p>
- * This class is a temporary implementation detail until Lifecycles are integrated with support
- * library.
+ * @deprecated Use {@link Fragment} instead of it.
*/
-// This class will be removed once we integrate with Fragment library.
-public class LifecycleFragment extends Fragment implements LifecycleRegistryOwner {
- LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
-
- @Override
- public LifecycleRegistry getLifecycle() {
- return mLifecycleRegistry;
- }
+@Deprecated
+public class LifecycleFragment extends Fragment {
}
diff --git a/lifecycle/integration-tests/testapp/build.gradle b/lifecycle/integration-tests/testapp/build.gradle
index b0da333..dca413b 100644
--- a/lifecycle/integration-tests/testapp/build.gradle
+++ b/lifecycle/integration-tests/testapp/build.gradle
@@ -52,7 +52,6 @@
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
// IJ canont figure out transitive dependencies so need to declare them.
compile project(":lifecycle:common")
compile project(":lifecycle:runtime")
diff --git a/lifecycle/reactivestreams/build.gradle b/lifecycle/reactivestreams/build.gradle
index f973e0e..bd64a32 100644
--- a/lifecycle/reactivestreams/build.gradle
+++ b/lifecycle/reactivestreams/build.gradle
@@ -50,7 +50,7 @@
testCompile(libs.test_runner) {
exclude module: 'support-annotations'
}
- androidTestCompile libs.support.app_compat
+ androidTestCompile libs.support.app_compat, libs.support_exclude_config
}
}
diff --git a/lifecycle/runtime/api/1.0.0.txt b/lifecycle/runtime/api/1.0.0.txt
index 93a55fc..2b900b0 100644
--- a/lifecycle/runtime/api/1.0.0.txt
+++ b/lifecycle/runtime/api/1.0.0.txt
@@ -10,7 +10,7 @@
method public void removeObserver(android.arch.lifecycle.LifecycleObserver);
}
- public abstract interface LifecycleRegistryOwner implements android.arch.lifecycle.LifecycleOwner {
+ public abstract deprecated interface LifecycleRegistryOwner implements android.arch.lifecycle.LifecycleOwner {
method public abstract android.arch.lifecycle.LifecycleRegistry getLifecycle();
}
diff --git a/lifecycle/runtime/src/main/java/android/arch/lifecycle/LifecycleRegistryOwner.java b/lifecycle/runtime/src/main/java/android/arch/lifecycle/LifecycleRegistryOwner.java
index 634cfc3..38eeb6d 100644
--- a/lifecycle/runtime/src/main/java/android/arch/lifecycle/LifecycleRegistryOwner.java
+++ b/lifecycle/runtime/src/main/java/android/arch/lifecycle/LifecycleRegistryOwner.java
@@ -17,14 +17,11 @@
package android.arch.lifecycle;
/**
- * Specialization of {@link LifecycleOwner} that explicitly returns {@link LifecycleRegistry}.
- * <p>
- * This method may be used if an object which updates state of {@link Lifecycle} doesn't own it.
- * <p>
- * This class is a temporary implementation detail until Lifecycles are integrated with support
- * library.
+ * @deprecated Use {@code android.support.v7.app.AppCompatActivity}
+ * which extends {@link LifecycleOwner}, so there are no use cases for this class.
*/
@SuppressWarnings({"WeakerAccess", "unused"})
+@Deprecated
public interface LifecycleRegistryOwner extends LifecycleOwner {
@Override
LifecycleRegistry getLifecycle();
diff --git a/lifecycle/runtime/src/main/java/android/arch/lifecycle/ReportFragment.java b/lifecycle/runtime/src/main/java/android/arch/lifecycle/ReportFragment.java
index 490028c..3e4ece8 100644
--- a/lifecycle/runtime/src/main/java/android/arch/lifecycle/ReportFragment.java
+++ b/lifecycle/runtime/src/main/java/android/arch/lifecycle/ReportFragment.java
@@ -110,8 +110,17 @@
}
private void dispatch(Lifecycle.Event event) {
- if (getActivity() instanceof LifecycleRegistryOwner) {
- ((LifecycleRegistryOwner) getActivity()).getLifecycle().handleLifecycleEvent(event);
+ Activity activity = getActivity();
+ if (activity instanceof LifecycleRegistryOwner) {
+ ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
+ return;
+ }
+
+ if (activity instanceof LifecycleOwner) {
+ Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
+ if (lifecycle instanceof LifecycleRegistry) {
+ ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
+ }
}
}
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
index 8175aae..53b111a 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -550,7 +550,7 @@
/**
* All the info about a connection.
*/
- private static class ConnectionRecord {
+ private class ConnectionRecord implements IBinder.DeathRecipient {
String pkg;
Bundle rootHints;
ServiceCallbacks callbacks;
@@ -559,6 +559,16 @@
ConnectionRecord() {
}
+
+ @Override
+ public void binderDied() {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mConnections.remove(callbacks.asBinder());
+ }
+ });
+ }
}
/**
@@ -747,6 +757,7 @@
} else {
try {
mConnections.put(b, connection);
+ b.linkToDeath(connection, 0);
if (mSession != null) {
callbacks.onConnect(connection.root.getRootId(),
mSession, connection.root.getExtras());
@@ -771,6 +782,7 @@
final ConnectionRecord old = mConnections.remove(b);
if (old != null) {
// TODO
+ old.callbacks.asBinder().unlinkToDeath(old, 0);
}
}
});
@@ -852,6 +864,11 @@
connection.callbacks = callbacks;
connection.rootHints = rootHints;
mConnections.put(b, connection);
+ try {
+ b.linkToDeath(connection, 0);
+ } catch (RemoteException e) {
+ Log.w(TAG, "IBinder is already dead.");
+ }
}
});
}
@@ -862,7 +879,10 @@
@Override
public void run() {
final IBinder b = callbacks.asBinder();
- mConnections.remove(b);
+ ConnectionRecord old = mConnections.remove(b);
+ if (old != null) {
+ b.unlinkToDeath(old, 0);
+ }
}
});
}
diff --git a/paging/common/build.gradle b/paging/common/build.gradle
index 78e12ba..bb9ad6b 100644
--- a/paging/common/build.gradle
+++ b/paging/common/build.gradle
@@ -28,7 +28,6 @@
testCompile libs.mockito_core
compile libs.support.annotations
compile project(path: ':arch:common')
- compile libs.junit
testCompile libs.kotlin.stdlib
}
diff --git a/paging/integration-tests/testapp/build.gradle b/paging/integration-tests/testapp/build.gradle
index 5356dd4..47f45d1 100644
--- a/paging/integration-tests/testapp/build.gradle
+++ b/paging/integration-tests/testapp/build.gradle
@@ -46,8 +46,8 @@
compile project(':paging:runtime')
compile 'com.android.support:multidex:1.0.1'
- compile libs.support.recyclerview
- compile libs.support.app_compat
+ compile libs.support.recyclerview, libs.support_exclude_config
+ compile libs.support.app_compat, libs.support_exclude_config
}
createAndroidCheckstyle(project)
diff --git a/paging/integration-tests/testapp/src/main/java/android/arch/paging/integration/testapp/PagedListSampleActivity.java b/paging/integration-tests/testapp/src/main/java/android/arch/paging/integration/testapp/PagedListSampleActivity.java
index f002218..5d0117d 100644
--- a/paging/integration-tests/testapp/src/main/java/android/arch/paging/integration/testapp/PagedListSampleActivity.java
+++ b/paging/integration-tests/testapp/src/main/java/android/arch/paging/integration/testapp/PagedListSampleActivity.java
@@ -17,7 +17,6 @@
package android.arch.paging.integration.testapp;
import android.arch.lifecycle.LifecycleRegistry;
-import android.arch.lifecycle.LifecycleRegistryOwner;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
@@ -31,7 +30,7 @@
/**
* Sample NullPaddedList activity with artificial data source.
*/
-public class PagedListSampleActivity extends AppCompatActivity implements LifecycleRegistryOwner {
+public class PagedListSampleActivity extends AppCompatActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
diff --git a/paging/runtime/build.gradle b/paging/runtime/build.gradle
index 990e140..0ee0c77 100644
--- a/paging/runtime/build.gradle
+++ b/paging/runtime/build.gradle
@@ -42,7 +42,7 @@
compile project(":lifecycle:runtime")
compile project(':lifecycle:extensions')
- compile libs.support.recyclerview
+ compile libs.support.recyclerview, libs.support_exclude_config
androidTestImplementation libs.junit
androidTestImplementation libs.mockito_core, { exclude group: 'net.bytebuddy' } // DexMaker has it"s own MockMaker
diff --git a/paging/runtime/src/androidTest/java/android/arch/paging/ListDataSource.java b/paging/runtime/src/androidTest/java/android/arch/paging/ListDataSource.java
index 241c8f0..f3e83d0 100644
--- a/paging/runtime/src/androidTest/java/android/arch/paging/ListDataSource.java
+++ b/paging/runtime/src/androidTest/java/android/arch/paging/ListDataSource.java
@@ -26,7 +26,7 @@
}
@Override
- public int loadCount() {
+ public int countItems() {
return mList.size();
}
diff --git a/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java b/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java
index 821eac2..6304b29 100644
--- a/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java
+++ b/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java
@@ -28,8 +28,16 @@
* Return type for data-loading system of an application or library to produce a
* {@code LiveData<PagedList>}, while leaving the details of the paging mechanism up to the
* consumer.
+ * <p>
+ * If you're using Room, it can generate a LivePagedListProvider from a query:
+ * <pre>
+ * {@literal @}Dao
+ * interface UserDao {
+ * {@literal @}Query("SELECT * FROM user ORDER BY lastName ASC")
+ * public abstract LivePagedListProvider<Integer, User> usersByLastName();
+ * }</pre>
*
- * @param <Key> Tyep of input valued used to load data from the DataSource. Must be integer if
+ * @param <Key> Type of input valued used to load data from the DataSource. Must be integer if
* you're using TiledDataSource.
* @param <Value> Data type produced by the DataSource, and held by the PagedLists.
*
diff --git a/paging/runtime/src/main/java/android/arch/paging/PagedListAdapter.java b/paging/runtime/src/main/java/android/arch/paging/PagedListAdapter.java
index 73c1b64..19a0c55 100644
--- a/paging/runtime/src/main/java/android/arch/paging/PagedListAdapter.java
+++ b/paging/runtime/src/main/java/android/arch/paging/PagedListAdapter.java
@@ -44,7 +44,7 @@
* {@literal @}Dao
* interface UserDao {
* {@literal @}Query("SELECT * FROM user ORDER BY lastName ASC")
- * public abstract LivePagedListProvider<User> usersByLastName();
+ * public abstract LivePagedListProvider<Integer, User> usersByLastName();
* }
*
* class MyViewModel extends ViewModel {
@@ -58,7 +58,7 @@
* }
* }
*
- * class MyActivity extends Activity implements LifecycleRegistryOwner {
+ * class MyActivity extends AppCompatActivity {
* {@literal @}Override
* public void onCreate(Bundle savedState) {
* super.onCreate(savedState);
diff --git a/paging/runtime/src/main/java/android/arch/paging/PagedListAdapterHelper.java b/paging/runtime/src/main/java/android/arch/paging/PagedListAdapterHelper.java
index 7d7a922..4bff5fc 100644
--- a/paging/runtime/src/main/java/android/arch/paging/PagedListAdapterHelper.java
+++ b/paging/runtime/src/main/java/android/arch/paging/PagedListAdapterHelper.java
@@ -50,7 +50,7 @@
* {@literal @}Dao
* interface UserDao {
* {@literal @}Query("SELECT * FROM user ORDER BY lastName ASC")
- * public abstract LivePagedListProvider<User> usersByLastName();
+ * public abstract LivePagedListProvider<Integer, User> usersByLastName();
* }
*
* class MyViewModel extends ViewModel {
@@ -64,7 +64,7 @@
* }
* }
*
- * class MyActivity extends Activity implements LifecycleRegistryOwner {
+ * class MyActivity extends AppCompatActivity {
* {@literal @}Override
* public void onCreate(Bundle savedState) {
* super.onCreate(savedState);
diff --git a/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapter.java b/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapter.java
index 8035a27..e08cb53 100644
--- a/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapter.java
+++ b/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapter.java
@@ -46,7 +46,7 @@
* }
* }
*
- * class MyActivity extends Activity implements LifecycleRegistryOwner {
+ * class MyActivity extends AppCompatActivity {
* {@literal @}Override
* public void onCreate(Bundle savedState) {
* super.onCreate(savedState);
diff --git a/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapterHelper.java b/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapterHelper.java
index e4a53fd..b47b833 100644
--- a/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapterHelper.java
+++ b/paging/runtime/src/main/java/android/support/v7/recyclerview/extensions/ListAdapterHelper.java
@@ -55,7 +55,7 @@
* }
* }
*
- * class MyActivity extends Activity implements LifecycleRegistryOwner {
+ * class MyActivity extends AppCompatActivity {
* {@literal @}Override
* public void onCreate(Bundle savedState) {
* super.onCreate(savedState);
diff --git a/room/db-impl/.gitignore b/persistence/db-framework/.gitignore
similarity index 100%
rename from room/db-impl/.gitignore
rename to persistence/db-framework/.gitignore
diff --git a/room/db-impl/build.gradle b/persistence/db-framework/build.gradle
similarity index 90%
rename from room/db-impl/build.gradle
rename to persistence/db-framework/build.gradle
index a5da1f1..0961ba5 100644
--- a/room/db-impl/build.gradle
+++ b/persistence/db-framework/build.gradle
@@ -42,7 +42,7 @@
dependencies {
compile libs.support.annotations
- compile project(":room:db")
+ compile project(":persistence:db")
}
createAndroidCheckstyle(project)
@@ -58,9 +58,9 @@
version = LibraryVersions.ROOM.toString()
supportLibrary {
- name 'Android DB-Impl'
+ name 'Android Support SQLite - Framework Implementation'
publish true
inceptionYear '2017'
- description "Android DB-Impl"
+ description "The implementation of Support SQLite library using the framework code."
url SupportLibraryExtension.ARCHITECTURE_URL
}
\ No newline at end of file
diff --git a/room/db-impl/src/main/AndroidManifest.xml b/persistence/db-framework/src/main/AndroidManifest.xml
similarity index 100%
rename from room/db-impl/src/main/AndroidManifest.xml
rename to persistence/db-framework/src/main/AndroidManifest.xml
diff --git a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteDatabase.java b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteDatabase.java
similarity index 98%
rename from room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteDatabase.java
rename to persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteDatabase.java
index 92a5820..e9c2b74 100644
--- a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteDatabase.java
+++ b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteDatabase.java
@@ -53,8 +53,7 @@
*
* @param delegate The delegate to receive all calls.
*/
- @SuppressWarnings("WeakerAccess")
- public FrameworkSQLiteDatabase(SQLiteDatabase delegate) {
+ FrameworkSQLiteDatabase(SQLiteDatabase delegate) {
mDelegate = delegate;
}
diff --git a/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper.java b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper.java
new file mode 100644
index 0000000..a1690f4
--- /dev/null
+++ b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2016 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 android.arch.persistence.db.framework;
+
+import android.arch.persistence.db.SupportSQLiteDatabase;
+import android.arch.persistence.db.SupportSQLiteOpenHelper;
+import android.content.Context;
+import android.database.DatabaseErrorHandler;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+
+class FrameworkSQLiteOpenHelper implements SupportSQLiteOpenHelper {
+ private final OpenHelper mDelegate;
+
+ FrameworkSQLiteOpenHelper(Context context, String name,
+ Callback callback) {
+ mDelegate = createDelegate(context, name, callback);
+ }
+
+ private OpenHelper createDelegate(Context context, String name, Callback callback) {
+ final FrameworkSQLiteDatabase[] dbRef = new FrameworkSQLiteDatabase[1];
+ return new OpenHelper(context, name, dbRef, callback);
+ }
+
+ @Override
+ public String getDatabaseName() {
+ return mDelegate.getDatabaseName();
+ }
+
+ @Override
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
+ public void setWriteAheadLoggingEnabled(boolean enabled) {
+ mDelegate.setWriteAheadLoggingEnabled(enabled);
+ }
+
+ @Override
+ public SupportSQLiteDatabase getWritableDatabase() {
+ return mDelegate.getWritableSupportDatabase();
+ }
+
+ @Override
+ public SupportSQLiteDatabase getReadableDatabase() {
+ return mDelegate.getReadableSupportDatabase();
+ }
+
+ @Override
+ public void close() {
+ mDelegate.close();
+ }
+
+ static class OpenHelper extends SQLiteOpenHelper {
+ /**
+ * This is used as an Object reference so that we can access the wrapped database inside
+ * the constructor. SQLiteOpenHelper requires the error handler to be passed in the
+ * constructor.
+ */
+ final FrameworkSQLiteDatabase[] mDbRef;
+ final Callback mCallback;
+
+ OpenHelper(Context context, String name, final FrameworkSQLiteDatabase[] dbRef,
+ final Callback callback) {
+ super(context, name, null, callback.version,
+ new DatabaseErrorHandler() {
+ @Override
+ public void onCorruption(SQLiteDatabase dbObj) {
+ FrameworkSQLiteDatabase db = dbRef[0];
+ if (db != null) {
+ callback.onCorruption(db);
+ }
+ }
+ });
+ mCallback = callback;
+ mDbRef = dbRef;
+ }
+
+ SupportSQLiteDatabase getWritableSupportDatabase() {
+ SQLiteDatabase db = super.getWritableDatabase();
+ return getWrappedDb(db);
+ }
+
+ SupportSQLiteDatabase getReadableSupportDatabase() {
+ SQLiteDatabase db = super.getReadableDatabase();
+ return getWrappedDb(db);
+ }
+
+ FrameworkSQLiteDatabase getWrappedDb(SQLiteDatabase sqLiteDatabase) {
+ FrameworkSQLiteDatabase dbRef = mDbRef[0];
+ if (dbRef == null) {
+ dbRef = new FrameworkSQLiteDatabase(sqLiteDatabase);
+ mDbRef[0] = dbRef;
+ }
+ return mDbRef[0];
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase sqLiteDatabase) {
+ mCallback.onCreate(getWrappedDb(sqLiteDatabase));
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
+ mCallback.onUpgrade(getWrappedDb(sqLiteDatabase), oldVersion, newVersion);
+ }
+
+ @Override
+ public void onConfigure(SQLiteDatabase db) {
+ mCallback.onConfigure(getWrappedDb(db));
+ }
+
+ @Override
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ mCallback.onDowngrade(getWrappedDb(db), oldVersion, newVersion);
+ }
+
+ @Override
+ public void onOpen(SQLiteDatabase db) {
+ mCallback.onOpen(getWrappedDb(db));
+ }
+
+ @Override
+ public synchronized void close() {
+ super.close();
+ mDbRef[0] = null;
+ }
+ }
+}
diff --git a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory.java b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory.java
similarity index 80%
rename from room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory.java
rename to persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory.java
index 7b4245b..ab11d49 100644
--- a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory.java
+++ b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory.java
@@ -23,12 +23,10 @@
* framework.
*/
@SuppressWarnings("unused")
-public class FrameworkSQLiteOpenHelperFactory implements SupportSQLiteOpenHelper.Factory {
+public final class FrameworkSQLiteOpenHelperFactory implements SupportSQLiteOpenHelper.Factory {
@Override
public SupportSQLiteOpenHelper create(SupportSQLiteOpenHelper.Configuration configuration) {
return new FrameworkSQLiteOpenHelper(
- configuration.context, configuration.name,
- configuration.version, configuration.errorHandler, configuration.callback
- );
+ configuration.context, configuration.name, configuration.callback);
}
}
diff --git a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteProgram.java b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteProgram.java
similarity index 100%
rename from room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteProgram.java
rename to persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteProgram.java
diff --git a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteStatement.java b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteStatement.java
similarity index 95%
rename from room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteStatement.java
rename to persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteStatement.java
index a2daf12..53a04bd 100644
--- a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteStatement.java
+++ b/persistence/db-framework/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteStatement.java
@@ -30,8 +30,7 @@
*
* @param delegate The SQLiteStatement to delegate calls to.
*/
- @SuppressWarnings("WeakerAccess")
- public FrameworkSQLiteStatement(SQLiteStatement delegate) {
+ FrameworkSQLiteStatement(SQLiteStatement delegate) {
mDelegate = delegate;
}
diff --git a/room/db/build.gradle b/persistence/db/build.gradle
similarity index 100%
rename from room/db/build.gradle
rename to persistence/db/build.gradle
diff --git a/room/db/src/main/AndroidManifest.xml b/persistence/db/src/main/AndroidManifest.xml
similarity index 100%
rename from room/db/src/main/AndroidManifest.xml
rename to persistence/db/src/main/AndroidManifest.xml
diff --git a/room/db/src/main/java/android/arch/persistence/db/SimpleSQLiteQuery.java b/persistence/db/src/main/java/android/arch/persistence/db/SimpleSQLiteQuery.java
similarity index 97%
rename from room/db/src/main/java/android/arch/persistence/db/SimpleSQLiteQuery.java
rename to persistence/db/src/main/java/android/arch/persistence/db/SimpleSQLiteQuery.java
index b821176..e2a3829 100644
--- a/room/db/src/main/java/android/arch/persistence/db/SimpleSQLiteQuery.java
+++ b/persistence/db/src/main/java/android/arch/persistence/db/SimpleSQLiteQuery.java
@@ -20,7 +20,7 @@
* A basic implemtation of {@link SupportSQLiteQuery} which receives a query and its args and binds
* args based on the passed in Object type.
*/
-public class SimpleSQLiteQuery implements SupportSQLiteQuery {
+public final class SimpleSQLiteQuery implements SupportSQLiteQuery {
private final String mQuery;
private final Object[] mBindArgs;
diff --git a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteDatabase.java b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteDatabase.java
similarity index 100%
rename from room/db/src/main/java/android/arch/persistence/db/SupportSQLiteDatabase.java
rename to persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteDatabase.java
diff --git a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteOpenHelper.java b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteOpenHelper.java
similarity index 74%
rename from room/db/src/main/java/android/arch/persistence/db/SupportSQLiteOpenHelper.java
rename to persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteOpenHelper.java
index 5a96e5a..02e4e7d 100644
--- a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteOpenHelper.java
+++ b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteOpenHelper.java
@@ -17,13 +17,18 @@
package android.arch.persistence.db;
import android.content.Context;
-import android.database.DatabaseErrorHandler;
-import android.database.DefaultDatabaseErrorHandler;
+import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
+import android.util.Log;
+import android.util.Pair;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
/**
* An interface to map the behavior of {@link android.database.sqlite.SQLiteOpenHelper}.
@@ -99,10 +104,29 @@
void close();
/**
- * Matching callback methods from {@link android.database.sqlite.SQLiteOpenHelper}.
+ * Handles various lifecycle events for the SQLite connection, similar to
+ * {@link android.database.sqlite.SQLiteOpenHelper}.
*/
@SuppressWarnings({"unused", "WeakerAccess"})
abstract class Callback {
+ private static final String TAG = "SupportSQLite";
+ /**
+ * Version number of the database (starting at 1); if the database is older,
+ * {@link SupportSQLiteOpenHelper.Callback#onUpgrade(SupportSQLiteDatabase, int, int)}
+ * will be used to upgrade the database; if the database is newer,
+ * {@link SupportSQLiteOpenHelper.Callback#onDowngrade(SupportSQLiteDatabase, int, int)}
+ * will be used to downgrade the database.
+ */
+ public final int version;
+
+ /**
+ * Creates a new Callback to get database lifecycle events.
+ * @param version The version for the database instance. See {@link #version}.
+ */
+ public Callback(int version) {
+ this.version = version;
+ }
+
/**
* Called when the database connection is being configured, to enable features such as
* write-ahead logging or foreign key support.
@@ -193,6 +217,81 @@
public void onOpen(SupportSQLiteDatabase db) {
}
+
+ /**
+ * The method invoked when database corruption is detected. Default implementation will
+ * delete the database file.
+ *
+ * @param db the {@link SupportSQLiteDatabase} object representing the database on which
+ * corruption is detected.
+ */
+ public void onCorruption(SupportSQLiteDatabase db) {
+ // the following implementation is taken from {@link DefaultDatabaseErrorHandler}.
+
+ Log.e(TAG, "Corruption reported by sqlite on database: " + db.getPath());
+ // is the corruption detected even before database could be 'opened'?
+ if (!db.isOpen()) {
+ // database files are not even openable. delete this database file.
+ // NOTE if the database has attached databases, then any of them could be corrupt.
+ // and not deleting all of them could cause corrupted database file to remain and
+ // make the application crash on database open operation. To avoid this problem,
+ // the application should provide its own {@link DatabaseErrorHandler} impl class
+ // to delete ALL files of the database (including the attached databases).
+ deleteDatabaseFile(db.getPath());
+ return;
+ }
+
+ List<Pair<String, String>> attachedDbs = null;
+ try {
+ // Close the database, which will cause subsequent operations to fail.
+ // before that, get the attached database list first.
+ try {
+ attachedDbs = db.getAttachedDbs();
+ } catch (SQLiteException e) {
+ /* ignore */
+ }
+ try {
+ db.close();
+ } catch (IOException e) {
+ /* ignore */
+ }
+ } finally {
+ // Delete all files of this corrupt database and/or attached databases
+ if (attachedDbs != null) {
+ for (Pair<String, String> p : attachedDbs) {
+ deleteDatabaseFile(p.second);
+ }
+ } else {
+ // attachedDbs = null is possible when the database is so corrupt that even
+ // "PRAGMA database_list;" also fails. delete the main database file
+ deleteDatabaseFile(db.getPath());
+ }
+ }
+ }
+
+ private void deleteDatabaseFile(String fileName) {
+ if (fileName.equalsIgnoreCase(":memory:") || fileName.trim().length() == 0) {
+ return;
+ }
+ Log.w(TAG, "deleting the database file: " + fileName);
+ try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ SQLiteDatabase.deleteDatabase(new File(fileName));
+ } else {
+ try {
+ final boolean deleted = new File(fileName).delete();
+ if (!deleted) {
+ Log.e(TAG, "Could not delete the database file " + fileName);
+ }
+ } catch (Exception error) {
+ Log.e(TAG, "error while deleting corrupted database file", error);
+ }
+ }
+ } catch (Exception e) {
+ /* print warning and ignore exception */
+ Log.w(TAG, "delete failed: ", e);
+ }
+ }
}
/**
@@ -211,33 +310,15 @@
@Nullable
public final String name;
/**
- * Version number of the database (starting at 1); if the database is older,
- * {@link SupportSQLiteOpenHelper.Callback#onUpgrade(SupportSQLiteDatabase, int, int)}
- * will be used to upgrade the database; if the database is newer,
- * {@link SupportSQLiteOpenHelper.Callback#onDowngrade(SupportSQLiteDatabase, int, int)}
- * will be used to downgrade the database.
- */
- public final int version;
- /**
* The callback class to handle creation, upgrade and downgrade.
*/
@NonNull
public final SupportSQLiteOpenHelper.Callback callback;
- /**
- * The {@link DatabaseErrorHandler} to be used when sqlite reports database
- * corruption, or null to use the default error handler.
- */
- @Nullable
- public final DatabaseErrorHandler errorHandler;
- Configuration(@NonNull Context context, @Nullable String name,
- int version, @Nullable DatabaseErrorHandler errorHandler,
- @NonNull Callback callback) {
+ Configuration(@NonNull Context context, @Nullable String name, @NonNull Callback callback) {
this.context = context;
this.name = name;
- this.version = version;
this.callback = callback;
- this.errorHandler = errorHandler;
}
/**
@@ -255,9 +336,7 @@
public static class Builder {
Context mContext;
String mName;
- int mVersion = 1;
SupportSQLiteOpenHelper.Callback mCallback;
- DatabaseErrorHandler mErrorHandler;
public Configuration build() {
if (mCallback == null) {
@@ -268,11 +347,7 @@
throw new IllegalArgumentException("Must set a non-null context to create"
+ " the configuration.");
}
- if (mErrorHandler == null) {
- mErrorHandler = new DefaultDatabaseErrorHandler();
- }
- return new Configuration(mContext, mName, mVersion, mErrorHandler,
- mCallback);
+ return new Configuration(mContext, mName, mCallback);
}
Builder(@NonNull Context context) {
@@ -280,17 +355,6 @@
}
/**
- * @param errorHandler The {@link DatabaseErrorHandler} to be used when sqlite
- * reports database corruption, or null to use the default error
- * handler.
- * @return This
- */
- public Builder errorHandler(@Nullable DatabaseErrorHandler errorHandler) {
- mErrorHandler = errorHandler;
- return this;
- }
-
- /**
* @param name Name of the database file, or null for an in-memory database.
* @return This
*/
@@ -307,20 +371,6 @@
mCallback = callback;
return this;
}
-
- /**
- * @param version Version number of the database (starting at 1); if the database is
- * older,
- * {@link SupportSQLiteOpenHelper.Callback#onUpgrade(SupportSQLiteDatabase, int, int)}
- * will be used to upgrade the database; if the database is newer,
- * {@link SupportSQLiteOpenHelper.Callback#onDowngrade(SupportSQLiteDatabase, int, int)}
- * will be used to downgrade the database.
- * @return this
- */
- public Builder version(int version) {
- mVersion = version;
- return this;
- }
}
}
diff --git a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteProgram.java b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteProgram.java
similarity index 100%
rename from room/db/src/main/java/android/arch/persistence/db/SupportSQLiteProgram.java
rename to persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteProgram.java
diff --git a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteQuery.java b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteQuery.java
similarity index 100%
rename from room/db/src/main/java/android/arch/persistence/db/SupportSQLiteQuery.java
rename to persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteQuery.java
diff --git a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteQueryBuilder.java b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteQueryBuilder.java
similarity index 98%
rename from room/db/src/main/java/android/arch/persistence/db/SupportSQLiteQueryBuilder.java
rename to persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteQueryBuilder.java
index 183fb0a..52957a3 100644
--- a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteQueryBuilder.java
+++ b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteQueryBuilder.java
@@ -22,7 +22,7 @@
* A simple query builder to create SQL SELECT queries.
*/
@SuppressWarnings("unused")
-public class SupportSQLiteQueryBuilder {
+public final class SupportSQLiteQueryBuilder {
private static final Pattern sLimitPattern =
Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?");
diff --git a/room/db/src/main/java/android/arch/persistence/db/SupportSQLiteStatement.java b/persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteStatement.java
similarity index 100%
rename from room/db/src/main/java/android/arch/persistence/db/SupportSQLiteStatement.java
rename to persistence/db/src/main/java/android/arch/persistence/db/SupportSQLiteStatement.java
diff --git a/room/common/src/main/java/android/arch/persistence/room/ColumnInfo.java b/room/common/src/main/java/android/arch/persistence/room/ColumnInfo.java
index 84f5844..65da379 100644
--- a/room/common/src/main/java/android/arch/persistence/room/ColumnInfo.java
+++ b/room/common/src/main/java/android/arch/persistence/room/ColumnInfo.java
@@ -33,6 +33,7 @@
public @interface ColumnInfo {
/**
* Name of the column in the database. Defaults to the field name if not set.
+ *
* @return Name of the column in the database.
*/
String name() default INHERIT_FIELD_NAME;
@@ -40,13 +41,14 @@
/**
* The type affinity for the column, which will be used when constructing the database.
* <p>
- * If it is not specified, Room resolves it based on the field's type and available
- * TypeConverters.
+ * If it is not specified, the value defaults to {@link #UNDEFINED} and Room resolves it based
+ * on the field's type and available TypeConverters.
* <p>
* See <a href="https://www.sqlite.org/datatype3.html">SQLite types documentation</a> for
* details.
*
- * @return The type affinity of the column.
+ * @return The type affinity of the column. This is either {@link #UNDEFINED}, {@link #TEXT},
+ * {@link #INTEGER}, {@link #REAL}, or {@link #BLOB}.
*/
@SuppressWarnings("unused") @SQLiteTypeAffinity int typeAffinity() default UNDEFINED;
@@ -60,6 +62,17 @@
boolean index() default false;
/**
+ * The collation sequence for the column, which will be used when constructing the database.
+ * <p>
+ * The default value is {@link #UNSPECIFIED}. In that case, Room does not add any
+ * collation sequence to the column, and SQLite treats it like {@link #BINARY}.
+ *
+ * @return The collation sequence of the column. This is either {@link #UNSPECIFIED},
+ * {@link #BINARY}, {@link #NOCASE}, or {@link #RTRIM}.
+ */
+ @Collate int collate() default UNSPECIFIED;
+
+ /**
* Constant to let Room inherit the field name as the column name. If used, Room will use the
* field name as the column name.
*/
@@ -67,22 +80,32 @@
/**
* Undefined type affinity. Will be resolved based on the type.
+ *
+ * @see #typeAffinity()
*/
int UNDEFINED = 1;
/**
* Column affinity constant for strings.
+ *
+ * @see #typeAffinity()
*/
int TEXT = 2;
/**
* Column affinity constant for integers or booleans.
+ *
+ * @see #typeAffinity()
*/
int INTEGER = 3;
/**
* Column affinity constant for floats or doubles.
+ *
+ * @see #typeAffinity()
*/
int REAL = 4;
/**
* Column affinity constant for binary data.
+ *
+ * @see #typeAffinity()
*/
int BLOB = 5;
@@ -92,4 +115,34 @@
@IntDef({UNDEFINED, TEXT, INTEGER, REAL, BLOB})
@interface SQLiteTypeAffinity {
}
+
+ /**
+ * Collation sequence is not specified. The match will behave like {@link #BINARY}.
+ *
+ * @see #collate()
+ */
+ int UNSPECIFIED = 1;
+ /**
+ * Collation sequence for case-sensitive match.
+ *
+ * @see #collate()
+ */
+ int BINARY = 2;
+ /**
+ * Collation sequence for case-insensitive match.
+ *
+ * @see #collate()
+ */
+ int NOCASE = 3;
+ /**
+ * Collation sequence for case-sensitive match except that trailing space characters are
+ * ignored.
+ *
+ * @see #collate()
+ */
+ int RTRIM = 4;
+
+ @IntDef({UNSPECIFIED, BINARY, NOCASE, RTRIM})
+ @interface Collate {
+ }
}
diff --git a/room/common/src/main/java/android/arch/persistence/room/Entity.java b/room/common/src/main/java/android/arch/persistence/room/Entity.java
index f54f0f8..94ca3bf 100644
--- a/room/common/src/main/java/android/arch/persistence/room/Entity.java
+++ b/room/common/src/main/java/android/arch/persistence/room/Entity.java
@@ -36,6 +36,9 @@
* When a class is marked as an Entity, all of its fields are persisted. If you would like to
* exclude some of its fields, you can mark them with {@link Ignore}.
* <p>
+ * If a field is {@code transient}, it is automatically ignored <b>unless</b> it is annotated with
+ * {@link ColumnInfo}, {@link Embedded} or {@link Relation}.
+ * <p>
* Example:
* <pre>
* {@literal @}Entity
diff --git a/room/common/src/main/java/android/arch/persistence/room/Relation.java b/room/common/src/main/java/android/arch/persistence/room/Relation.java
index 0d2f152..7206699 100644
--- a/room/common/src/main/java/android/arch/persistence/room/Relation.java
+++ b/room/common/src/main/java/android/arch/persistence/room/Relation.java
@@ -41,7 +41,7 @@
*
* {@literal @}Dao
* public interface UserPetDao {
- * {@literal @}Query("SELECT id, name from User WHERE age >e; ?")
+ * {@literal @}Query("SELECT id, name from User WHERE age > :minAge")
* public List<UserNameAndAllPets> loadUserAndPets(int minAge);
* }
* </pre>
@@ -67,7 +67,7 @@
* }
* {@literal @}Dao
* public interface UserPetDao {
- * {@literal @}Query("SELECT * from User WHERE age >e; ?")
+ * {@literal @}Query("SELECT * from User WHERE age > :minAge")
* public List<UserAllPets> loadUserAndPets(int minAge);
* }
* </pre>
diff --git a/room/compiler/build.gradle b/room/compiler/build.gradle
index 8934f88..222a338 100644
--- a/room/compiler/build.gradle
+++ b/room/compiler/build.gradle
@@ -1,5 +1,3 @@
-import android.support.LibraryVersions
-
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -15,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import android.support.LibraryVersions
+import android.support.SupportLibraryExtension
-apply plugin: 'kotlin'
-apply plugin: 'maven'
+apply plugin: android.support.SupportKotlinLibraryPlugin
def antlrOut = "$buildDir/generated/antlr/grammar-gen/"
sourceSets {
@@ -57,7 +56,7 @@
include : "android.jar")
testCompile fileTree(dir: "${new File(project(":room:runtime").buildDir, "libJar")}",
include : "*.jar")
- testCompile fileTree(dir: "${new File(project(":room:db").buildDir, "libJar")}",
+ testCompile fileTree(dir: "${new File(project(":persistence:db").buildDir, "libJar")}",
include : "*.jar")
testCompile files(org.gradle.internal.jvm.Jvm.current().getToolsJar())
}
@@ -74,7 +73,14 @@
tasks.findByName("compileKotlin").dependsOn(generateAntlrTask)
tasks.findByName("compileKotlin").dependsOn(":room:runtime:jarDebug")
-tasks.findByName("compileKotlin").dependsOn(":room:db:jarDebug")
+tasks.findByName("compileKotlin").dependsOn(":persistence:db:jarDebug")
createKotlinCheckstyle(project)
+supportLibrary {
+ name 'Android Room Compiler'
+ publish true
+ inceptionYear '2017'
+ description "Android Room annotation processor"
+ url SupportLibraryExtension.ARCHITECTURE_URL
+}
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
index 09b6221..a74031d 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
@@ -47,13 +47,6 @@
|| hasAnnotation(org.jetbrains.annotations.NotNull::class)
/**
- * Checks if it has all of the annotations
- */
-fun Element.hasAllOf(vararg klasses: KClass<out Annotation>): Boolean {
- return !klasses.any { !hasAnnotation(it) }
-}
-
-/**
* gets all members including super privates. does not handle duplicate field names!!!
*/
// TODO handle conflicts with super: b/35568142
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/parser/SqlParser.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/parser/SqlParser.kt
index b71ba10..a4e8946 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/parser/SqlParser.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/parser/SqlParser.kt
@@ -210,3 +210,20 @@
}
}
}
+
+enum class Collate {
+ BINARY,
+ NOCASE,
+ RTRIM;
+
+ companion object {
+ fun fromAnnotationValue(value: Int): Collate? {
+ return when (value) {
+ ColumnInfo.BINARY -> BINARY
+ ColumnInfo.NOCASE -> NOCASE
+ ColumnInfo.RTRIM -> RTRIM
+ else -> null
+ }
+ }
+ }
+}
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/FieldProcessor.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/FieldProcessor.kt
index 2d11588..8677bf6 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/FieldProcessor.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/FieldProcessor.kt
@@ -20,6 +20,7 @@
import android.arch.persistence.room.ext.getAsBoolean
import android.arch.persistence.room.ext.getAsInt
import android.arch.persistence.room.ext.getAsString
+import android.arch.persistence.room.parser.Collate
import android.arch.persistence.room.parser.SQLTypeAffinity
import android.arch.persistence.room.vo.EmbeddedField
import android.arch.persistence.room.vo.Field
@@ -42,6 +43,7 @@
val name = element.simpleName.toString()
val columnName: String
val affinity : SQLTypeAffinity?
+ val collate: Collate?
val fieldPrefix = fieldParent?.prefix ?: ""
val indexed : Boolean
if (columnInfoAnnotation.isPresent) {
@@ -63,6 +65,9 @@
null
}
+ collate = Collate.fromAnnotationValue(AnnotationMirrors.getAnnotationValue(
+ columnInfoAnnotation.get(), "collate").getAsInt(ColumnInfo.UNSPECIFIED)!!)
+
indexed = AnnotationMirrors
.getAnnotationValue(columnInfoAnnotation.get(), "index")
.getAsBoolean(false)
@@ -70,6 +75,7 @@
} else {
columnName = fieldPrefix + name
affinity = null
+ collate = null
indexed = false
}
context.checker.notBlank(columnName, element,
@@ -82,6 +88,7 @@
element = element,
columnName = columnName,
affinity = affinity,
+ collate = collate,
parent = fieldParent,
indexed = indexed)
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
index baa351d..e83d1ef 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
@@ -52,6 +52,7 @@
import javax.lang.model.element.Modifier.PROTECTED
import javax.lang.model.element.Modifier.PUBLIC
import javax.lang.model.element.Modifier.STATIC
+import javax.lang.model.element.Modifier.TRANSIENT
import javax.lang.model.element.TypeElement
import javax.lang.model.element.VariableElement
import javax.lang.model.type.DeclaredType
@@ -82,7 +83,12 @@
// TODO handle conflicts with super: b/35568142
val allFields = element.getAllFieldsIncludingPrivateSupers(context.processingEnv)
.filter {
- !it.hasAnnotation(Ignore::class) && !it.hasAnyOf(Modifier.STATIC)
+ !it.hasAnnotation(Ignore::class)
+ && !it.hasAnyOf(STATIC)
+ && (!it.hasAnyOf(TRANSIENT)
+ || it.hasAnnotation(ColumnInfo::class)
+ || it.hasAnnotation(Embedded::class)
+ || it.hasAnnotation(Relation::class))
}
.groupBy { field ->
context.checker.check(
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt
index ee6f8a1..fa0575a 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt
@@ -19,6 +19,7 @@
import android.arch.persistence.room.ext.isNonNull
import android.arch.persistence.room.ext.typeName
import android.arch.persistence.room.migration.bundle.FieldBundle
+import android.arch.persistence.room.parser.Collate
import android.arch.persistence.room.parser.SQLTypeAffinity
import android.arch.persistence.room.solver.types.CursorValueReader
import android.arch.persistence.room.solver.types.StatementValueBinder
@@ -28,6 +29,7 @@
// used in cache matching, must stay as a data class or implement equals
data class Field(val element: Element, val name: String, val type: TypeMirror,
var affinity: SQLTypeAffinity?,
+ val collate: Collate? = null,
val columnName: String = name,
/* means that this field does not belong to parent, instead, it belongs to a
* embedded child of the main Pojo*/
@@ -117,6 +119,9 @@
if (nonNull) {
columnSpec.append(" NOT NULL")
}
+ if (collate != null) {
+ columnSpec.append(" COLLATE ${collate.name}")
+ }
return "`$columnName` ${(affinity ?: SQLTypeAffinity.TEXT).name}$columnSpec"
}
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/QueryWriter.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/QueryWriter.kt
index 2bf471a..a2c7e62 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/QueryWriter.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/QueryWriter.kt
@@ -72,7 +72,7 @@
query.sections.forEach {
when (it.type) {
TEXT -> addStatement("$L.append($S)", stringBuilderVar, it.text)
- NEWLINE -> addStatement("$L.append($S)", "\n")
+ NEWLINE -> addStatement("$L.append($S)", stringBuilderVar, "\n")
BIND_VAR -> {
// If it is null, will be reported as error before. We just try out
// best to generate as much code as possible.
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriter.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriter.kt
index afb12e9..bdc601f 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriter.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriter.kt
@@ -49,13 +49,12 @@
"""
final $T $L = $T.builder($N.context)
.name($N.name)
- .version($L)
.callback($L)
.build()
""".trimIndent(),
SupportDbTypeNames.SQLITE_OPEN_HELPER_CONFIG, sqliteConfigVar,
SupportDbTypeNames.SQLITE_OPEN_HELPER_CONFIG,
- configuration, configuration, database.version, callbackVar)
+ configuration, configuration, callbackVar)
addStatement("final $T $N = $N.sqliteOpenHelperFactory.create($L)",
SupportDbTypeNames.SQLITE_OPEN_HELPER, outVar,
configuration, sqliteConfigVar)
@@ -63,7 +62,7 @@
}
private fun createOpenCallback(scope: CodeGenScope) : TypeSpec {
- return TypeSpec.anonymousClassBuilder("").apply {
+ return TypeSpec.anonymousClassBuilder(L, database.version).apply {
superclass(RoomTypeNames.OPEN_HELPER_DELEGATE)
addMethod(createCreateAllTables())
addMethod(createDropAllTables())
diff --git a/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java b/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
index 39d4d42..80d73a9 100644
--- a/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
+++ b/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
@@ -23,7 +23,7 @@
private volatile ComplexDao _complexDao;
protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration configuration) {
- final SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration, new RoomOpenHelper.Delegate() {
+ final SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration, new RoomOpenHelper.Delegate(1923) {
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`uid` INTEGER NOT NULL, `name` TEXT, `lastName` TEXT, `ageColumn` INTEGER NOT NULL, PRIMARY KEY(`uid`))");
_db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
@@ -70,7 +70,6 @@
}, "6773601c5bcf94c71ee4eb0de04f21a4");
final SupportSQLiteOpenHelper.Configuration _sqliteConfig = SupportSQLiteOpenHelper.Configuration.builder(configuration.context)
.name(configuration.name)
- .version(1923)
.callback(_openCallback)
.build();
final SupportSQLiteOpenHelper _helper = configuration.sqliteOpenHelperFactory.create(_sqliteConfig);
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/FieldProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/FieldProcessorTest.kt
index 5498340..ef0170c 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/FieldProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/FieldProcessorTest.kt
@@ -17,6 +17,7 @@
package android.arch.persistence.room.processor
import android.arch.persistence.room.Entity
+import android.arch.persistence.room.parser.Collate
import android.arch.persistence.room.parser.SQLTypeAffinity
import android.arch.persistence.room.solver.types.ColumnTypeAdapter
import android.arch.persistence.room.testing.TestInvocation
@@ -330,6 +331,25 @@
}
}
+ @Test
+ fun collate() {
+ Collate.values().forEach { collate ->
+ singleEntity("""
+ @PrimaryKey
+ @ColumnInfo(collate = ColumnInfo.${collate.name})
+ String code;
+ """) { field, invocation ->
+ assertThat(field, `is`(
+ Field(name = "code",
+ type = invocation.context.COMMON_TYPES.STRING,
+ element = field.element,
+ columnName = "code",
+ collate = collate,
+ affinity = SQLTypeAffinity.TEXT)))
+ }.compilesWithoutError()
+ }
+ }
+
fun singleEntity(vararg input: String, handler: (Field, invocation: TestInvocation) -> Unit):
CompileTester {
return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources())
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
index faa6024..3ada5f6 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
@@ -18,6 +18,7 @@
import COMMON
import android.arch.persistence.room.parser.SQLTypeAffinity
+import android.arch.persistence.room.processor.ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD
import android.arch.persistence.room.processor.ProcessorErrors.CANNOT_FIND_TYPE
import android.arch.persistence.room.processor.ProcessorErrors.ENTITY_MUST_BE_ANNOTATED_WITH_ENTITY
import android.arch.persistence.room.processor.ProcessorErrors.POJO_FIELD_HAS_DUPLICATE_COLUMN_NAME
@@ -100,6 +101,72 @@
}
@Test
+ fun transient_ignore() {
+ singleRun("""
+ transient int foo;
+ int bar;
+ """) { pojo ->
+ assertThat(pojo.fields.size, `is`(1))
+ assertThat(pojo.fields[0].name, `is`("bar"))
+ }.compilesWithoutError()
+ }
+
+ @Test
+ fun transient_withColumnInfo() {
+ singleRun("""
+ @ColumnInfo
+ transient int foo;
+ int bar;
+ """) { pojo ->
+ assertThat(pojo.fields.map { it.name }.toSet(), `is`(setOf("bar", "foo")))
+ }.compilesWithoutError()
+ }
+
+ @Test
+ fun transient_embedded() {
+ singleRun("""
+ @Embedded
+ transient Foo foo;
+ int bar;
+ static class Foo {
+ int x;
+ }
+ """) { pojo ->
+ assertThat(pojo.fields.map { it.name }.toSet(), `is`(setOf("x", "bar")))
+ }.compilesWithoutError()
+ }
+
+ @Test
+ fun transient_insideEmbedded() {
+ singleRun("""
+ @Embedded
+ Foo foo;
+ int bar;
+ static class Foo {
+ transient int x;
+ int y;
+ }
+ """) { pojo ->
+ assertThat(pojo.fields.map { it.name }.toSet(), `is`(setOf("bar", "y")))
+ }.compilesWithoutError()
+ }
+
+ @Test
+ fun transient_relation() {
+ singleRun(
+ """
+ int id;
+ @Relation(parentColumn = "id", entityColumn = "uid")
+ public transient List<User> user;
+ """, COMMON.USER
+ ) { pojo ->
+ assertThat(pojo.relations.size, `is`(1))
+ assertThat(pojo.relations.first().entityField.name, `is`("uid"))
+ assertThat(pojo.relations.first().parentField.name, `is`("id"))
+ }.compilesWithoutError().withWarningCount(0)
+ }
+
+ @Test
fun embedded() {
singleRun(
"""
@@ -402,6 +469,20 @@
}
@Test
+ fun relation_badReturnTypeInGetter() {
+ singleRun(
+ """
+ int id;
+ @Relation(parentColumn = "id", entityColumn = "uid")
+ private List<User> user;
+ public void setUser(List<User> user){ this.user = user;}
+ public User getUser(){return null;}
+ """, COMMON.USER
+ ) { _ ->
+ }.failsToCompile().withErrorContaining(CANNOT_FIND_GETTER_FOR_FIELD)
+ }
+
+ @Test
fun cache() {
val pojo = """
$HEADER
diff --git a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper.java b/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper.java
deleted file mode 100644
index aa08fa4..0000000
--- a/room/db-impl/src/main/java/android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.arch.persistence.db.framework;
-
-import android.arch.persistence.db.SupportSQLiteDatabase;
-import android.arch.persistence.db.SupportSQLiteOpenHelper;
-import android.content.Context;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.os.Build;
-import android.support.annotation.RequiresApi;
-
-class FrameworkSQLiteOpenHelper implements SupportSQLiteOpenHelper {
- private final OpenHelper mDelegate;
-
- FrameworkSQLiteOpenHelper(Context context, String name, int version,
- DatabaseErrorHandler errorHandler,
- SupportSQLiteOpenHelper.Callback callback) {
- mDelegate = createDelegate(context, name, version, errorHandler, callback);
- }
-
- private OpenHelper createDelegate(Context context, String name,
- int version, DatabaseErrorHandler errorHandler,
- final Callback callback) {
- return new OpenHelper(context, name, null, version, errorHandler) {
- @Override
- public void onCreate(SQLiteDatabase sqLiteDatabase) {
- mWrappedDb = new FrameworkSQLiteDatabase(sqLiteDatabase);
- callback.onCreate(mWrappedDb);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
- callback.onUpgrade(getWrappedDb(sqLiteDatabase), oldVersion, newVersion);
- }
-
- @Override
- public void onConfigure(SQLiteDatabase db) {
- callback.onConfigure(getWrappedDb(db));
- }
-
- @Override
- public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- callback.onDowngrade(getWrappedDb(db), oldVersion, newVersion);
- }
-
- @Override
- public void onOpen(SQLiteDatabase db) {
- callback.onOpen(getWrappedDb(db));
- }
- };
- }
-
- @Override
- public String getDatabaseName() {
- return mDelegate.getDatabaseName();
- }
-
- @Override
- @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
- public void setWriteAheadLoggingEnabled(boolean enabled) {
- mDelegate.setWriteAheadLoggingEnabled(enabled);
- }
-
- @Override
- public SupportSQLiteDatabase getWritableDatabase() {
- return mDelegate.getWritableSupportDatabase();
- }
-
- @Override
- public SupportSQLiteDatabase getReadableDatabase() {
- return mDelegate.getReadableSupportDatabase();
- }
-
- @Override
- public void close() {
- mDelegate.close();
- }
-
- abstract static class OpenHelper extends SQLiteOpenHelper {
-
- FrameworkSQLiteDatabase mWrappedDb;
-
- OpenHelper(Context context, String name,
- SQLiteDatabase.CursorFactory factory, int version,
- DatabaseErrorHandler errorHandler) {
- super(context, name, factory, version, errorHandler);
- }
-
- SupportSQLiteDatabase getWritableSupportDatabase() {
- SQLiteDatabase db = super.getWritableDatabase();
- return getWrappedDb(db);
- }
-
- SupportSQLiteDatabase getReadableSupportDatabase() {
- SQLiteDatabase db = super.getReadableDatabase();
- return getWrappedDb(db);
- }
-
- FrameworkSQLiteDatabase getWrappedDb(SQLiteDatabase sqLiteDatabase) {
- if (mWrappedDb == null) {
- mWrappedDb = new FrameworkSQLiteDatabase(sqLiteDatabase);
- }
- return mWrappedDb;
- }
-
- @Override
- public synchronized void close() {
- super.close();
- mWrappedDb = null;
- }
- }
-}
diff --git a/room/integration-tests/kotlintestapp/build.gradle b/room/integration-tests/kotlintestapp/build.gradle
index 0d70666..f4df9cf 100644
--- a/room/integration-tests/kotlintestapp/build.gradle
+++ b/room/integration-tests/kotlintestapp/build.gradle
@@ -50,12 +50,12 @@
dependencies {
implementation project(":room:common")
- implementation project(":room:db")
- implementation project(":room:db-impl")
+ implementation project(":persistence:db")
+ implementation project(":persistence:db-framework")
implementation project(':room:runtime')
implementation project(':arch:runtime')
- implementation libs.support.app_compat
+ implementation libs.support.app_compat, libs.support_exclude_config
kapt project(":room:compiler")
kaptAndroidTest project(":room:compiler")
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
new file mode 100644
index 0000000..6425de7
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
@@ -0,0 +1,171 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "7beb328c9cd44a7782dfaa18c30ecb83",
+ "entities": [
+ {
+ "tableName": "Book",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT NOT NULL, `title` TEXT NOT NULL, `bookPublisherId` TEXT NOT NULL, PRIMARY KEY(`bookId`), FOREIGN KEY(`bookPublisherId`) REFERENCES `Publisher`(`publisherId`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+ "fields": [
+ {
+ "fieldPath": "bookId",
+ "columnName": "bookId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "bookPublisherId",
+ "columnName": "bookPublisherId",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "bookId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": [
+ {
+ "table": "Publisher",
+ "onDelete": "NO ACTION",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "bookPublisherId"
+ ],
+ "referencedColumns": [
+ "publisherId"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "Author",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`authorId` TEXT NOT NULL, `name` TEXT NOT NULL, `dateOfBirth` INTEGER, `aList` TEXT, PRIMARY KEY(`authorId`))",
+ "fields": [
+ {
+ "fieldPath": "authorId",
+ "columnName": "authorId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "dateOfBirth",
+ "columnName": "dateOfBirth",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "aList",
+ "columnName": "aList",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "authorId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Publisher",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`publisherId` TEXT NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`publisherId`))",
+ "fields": [
+ {
+ "fieldPath": "publisherId",
+ "columnName": "publisherId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "publisherId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "BookAuthor",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT NOT NULL, `authorId` TEXT NOT NULL, PRIMARY KEY(`bookId`, `authorId`), FOREIGN KEY(`bookId`) REFERENCES `Book`(`bookId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`authorId`) REFERENCES `Author`(`authorId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
+ "fields": [
+ {
+ "fieldPath": "bookId",
+ "columnName": "bookId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "authorId",
+ "columnName": "authorId",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "bookId",
+ "authorId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": [
+ {
+ "table": "Book",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "bookId"
+ ],
+ "referencedColumns": [
+ "bookId"
+ ]
+ },
+ {
+ "table": "Author",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "authorId"
+ ],
+ "referencedColumns": [
+ "authorId"
+ ]
+ }
+ ]
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"7beb328c9cd44a7782dfaa18c30ecb83\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/BooksDatabase.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/TestDatabase.kt
similarity index 83%
rename from room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/BooksDatabase.kt
rename to room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/TestDatabase.kt
index b5b6f26..b9344af 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/BooksDatabase.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/TestDatabase.kt
@@ -18,6 +18,8 @@
import android.arch.persistence.room.Database
import android.arch.persistence.room.RoomDatabase
+import android.arch.persistence.room.integration.kotlintestapp.dao.BooksDao
+import android.arch.persistence.room.integration.kotlintestapp.dao.DerivedDao
import android.arch.persistence.room.integration.kotlintestapp.vo.Author
import android.arch.persistence.room.integration.kotlintestapp.vo.Book
import android.arch.persistence.room.integration.kotlintestapp.vo.BookAuthor
@@ -25,8 +27,9 @@
@Database(entities = arrayOf(Book::class, Author::class, Publisher::class, BookAuthor::class),
version = 1)
-abstract class BooksDatabase : RoomDatabase() {
+abstract class TestDatabase : RoomDatabase() {
abstract fun booksDao(): BooksDao
+ abstract fun derivedDao(): DerivedDao
}
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BaseDao.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BaseDao.kt
new file mode 100644
index 0000000..60d97ed
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BaseDao.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.arch.persistence.room.integration.kotlintestapp.dao
+
+import android.arch.persistence.room.Delete
+import android.arch.persistence.room.Insert
+import android.arch.persistence.room.OnConflictStrategy
+import android.arch.persistence.room.Update
+
+interface BaseDao<T> {
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insert(t: T)
+
+ @Update
+ fun update(t: T)
+
+ @Delete
+ fun delete(t: T)
+}
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/BooksDao.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BooksDao.kt
similarity index 79%
rename from room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/BooksDao.kt
rename to room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BooksDao.kt
index 6f4f91e..20e9d18 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/BooksDao.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BooksDao.kt
@@ -14,13 +14,18 @@
* limitations under the License.
*/
-package android.arch.persistence.room.integration.kotlintestapp
+package android.arch.persistence.room.integration.kotlintestapp.dao
import android.arch.lifecycle.LiveData
import android.arch.persistence.room.Dao
import android.arch.persistence.room.Insert
import android.arch.persistence.room.Query
-import android.arch.persistence.room.integration.kotlintestapp.vo.*
+import android.arch.persistence.room.integration.kotlintestapp.vo.Author
+import android.arch.persistence.room.integration.kotlintestapp.vo.Book
+import android.arch.persistence.room.integration.kotlintestapp.vo.BookAuthor
+import android.arch.persistence.room.integration.kotlintestapp.vo.BookWithPublisher
+import android.arch.persistence.room.integration.kotlintestapp.vo.Publisher
+import android.arch.persistence.room.integration.kotlintestapp.vo.PublisherWithBooks
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.Single
@@ -34,6 +39,9 @@
@Insert
fun addAuthors(vararg authors: Author)
+ @Query("SELECT * FROM author WHERE authorId = :authorId")
+ fun getAuthor(authorId: String): Author
+
@Insert
fun addBooks(vararg books: Book)
@@ -43,6 +51,11 @@
@Query("SELECT * FROM book WHERE bookId = :bookId")
fun getBook(bookId: String): Book
+ @Query("""SELECT * FROM book WHERE
+ bookId IN(:bookIds)
+ order by bookId DESC""")
+ fun getBooksMultiLineQuery(bookIds: List<String>): List<Book>
+
@Query("SELECT * FROM book WHERE bookId = :bookId")
fun getBookLiveData(bookId: String): LiveData<Book>
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/DerivedDao.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/DerivedDao.kt
new file mode 100644
index 0000000..01e8167
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/DerivedDao.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.arch.persistence.room.integration.kotlintestapp.dao
+
+import android.arch.persistence.room.Dao
+import android.arch.persistence.room.Query
+import android.arch.persistence.room.integration.kotlintestapp.vo.Author
+
+
+@Dao
+interface DerivedDao : BaseDao<Author> {
+
+ @Query("SELECT * FROM author WHERE authorId = :authorId")
+ fun getAuthor(authorId: String): Author
+}
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt
index b918731..7985c77 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt
@@ -16,15 +16,19 @@
package android.arch.persistence.room.integration.kotlintestapp.test
+import android.arch.persistence.room.integration.kotlintestapp.vo.Author
import android.arch.persistence.room.integration.kotlintestapp.vo.Book
import android.arch.persistence.room.integration.kotlintestapp.vo.BookWithPublisher
import android.arch.persistence.room.integration.kotlintestapp.vo.Publisher
import android.database.sqlite.SQLiteConstraintException
+import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert.assertNotNull
import org.junit.Test
+import java.util.Date
+import kotlin.collections.ArrayList
class BooksDaoTest : TestDatabaseTest() {
@@ -82,4 +86,35 @@
assertThat(actualPublisherWithBooks.books?.get(0), `is`<Book>(TestUtil.BOOK_1))
assertThat(actualPublisherWithBooks.books?.get(1), `is`<Book>(TestUtil.BOOK_2))
}
+
+ @Test
+ fun insertAuthorWithAllFields() {
+ val author = Author("id", "name", Date(), ArrayList())
+ database.booksDao().addAuthors(author)
+
+ val authorDb = database.booksDao().getAuthor(author.authorId)
+
+ assertThat(authorDb, CoreMatchers.`is`<Author>(author))
+ }
+
+ @Test
+ fun insertInInheritedDao() {
+ database.derivedDao().insert(TestUtil.AUTHOR_1)
+
+ val author = database.derivedDao().getAuthor(TestUtil.AUTHOR_1.authorId)
+
+ assertThat(author, CoreMatchers.`is`<Author>(TestUtil.AUTHOR_1))
+ }
+
+ @Test
+ fun findBooksInMultiLineQuery() {
+ booksDao.addPublishers(TestUtil.PUBLISHER)
+ booksDao.addBooks(TestUtil.BOOK_1)
+ booksDao.addBooks(TestUtil.BOOK_2)
+
+ val books = database.booksDao().getBooksMultiLineQuery(arrayListOf(
+ TestUtil.BOOK_1.bookId,
+ TestUtil.BOOK_2.bookId))
+ assertThat(books, `is`(listOf(TestUtil.BOOK_2, TestUtil.BOOK_1)))
+ }
}
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestDatabaseTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestDatabaseTest.kt
index 42815b2..520c4d3 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestDatabaseTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestDatabaseTest.kt
@@ -18,8 +18,8 @@
import android.arch.core.executor.testing.InstantTaskExecutorRule
import android.arch.persistence.room.Room
-import android.arch.persistence.room.integration.kotlintestapp.BooksDao
-import android.arch.persistence.room.integration.kotlintestapp.BooksDatabase
+import android.arch.persistence.room.integration.kotlintestapp.dao.BooksDao
+import android.arch.persistence.room.integration.kotlintestapp.TestDatabase
import android.support.test.InstrumentationRegistry
import org.junit.After
import org.junit.Before
@@ -30,14 +30,14 @@
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
- protected lateinit var database: BooksDatabase
+ protected lateinit var database: TestDatabase
protected lateinit var booksDao: BooksDao
@Before
@Throws(Exception::class)
fun setUp() {
database = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getContext(),
- BooksDatabase::class.java)
+ TestDatabase::class.java)
// allowing main thread queries, just for testing
.allowMainThreadQueries()
.build()
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Author.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Author.kt
index a51c256..067fcb3 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Author.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Author.kt
@@ -18,6 +18,13 @@
import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey
+import android.arch.persistence.room.TypeConverters
+import java.util.Date
@Entity
-data class Author(@PrimaryKey val authorId: String, val name: String)
+@TypeConverters(DateConverter::class, StringToIntListConverters::class)
+data class Author(
+ @PrimaryKey val authorId: String,
+ val name: String,
+ val dateOfBirth: Date? = null,
+ val aList: List<Integer>? = null)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/DateConverter.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/DateConverter.kt
new file mode 100755
index 0000000..62a3c21
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/DateConverter.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.arch.persistence.room.integration.kotlintestapp.vo
+
+import android.arch.persistence.room.TypeConverter
+
+import java.util.Date
+
+class DateConverter {
+ @TypeConverter
+ fun toDate(timestamp: Long?): Date? {
+ return if (timestamp == null) null else Date(timestamp)
+ }
+
+ @TypeConverter
+ fun toTimestamp(date: Date?): Long? {
+ return date?.time
+ }
+}
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/StringToIntListConverters.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/StringToIntListConverters.kt
new file mode 100644
index 0000000..5c6620d
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/StringToIntListConverters.kt
@@ -0,0 +1,16 @@
+package android.arch.persistence.room.integration.kotlintestapp.vo
+
+import android.arch.persistence.room.TypeConverter
+import android.arch.persistence.room.util.StringUtil
+
+object StringToIntListConverters {
+ @TypeConverter
+ // Specifying that a static method should be generated. Otherwise, the compiler looks for the
+ // constructor of the class, and a object has a private constructor.
+ @JvmStatic
+ fun stringToIntList(data: String?): List<Int>? = if (data == null) null else StringUtil.splitToIntList(data)
+
+ @TypeConverter
+ @JvmStatic
+ fun intListToString(ints: List<Int>?): String? = if (ints == null) null else StringUtil.joinIntoString(ints)
+}
diff --git a/room/integration-tests/testapp/build.gradle b/room/integration-tests/testapp/build.gradle
index 361c33a..6fefc29 100644
--- a/room/integration-tests/testapp/build.gradle
+++ b/room/integration-tests/testapp/build.gradle
@@ -48,8 +48,8 @@
dependencies {
compile project(":room:common")
- compile project(":room:db")
- compile project(":room:db-impl")
+ compile project(":persistence:db")
+ compile project(":persistence:db-framework")
compile project(':room:runtime')
compile project(':arch:runtime')
compile project(':arch:common')
@@ -60,8 +60,8 @@
compile project(':room:rxjava2')
compile project(':paging:runtime')
- compile libs.support.recyclerview
- compile libs.support.app_compat
+ compile libs.support.recyclerview, libs.support_exclude_config
+ compile libs.support.app_compat, libs.support_exclude_config
annotationProcessor project(":room:compiler")
androidTestAnnotationProcessor project(":room:compiler")
@@ -79,6 +79,9 @@
androidTestCompile(libs.espresso_core, {
exclude group: 'com.android.support', module: 'support-annotations'
})
+ androidTestImplementation libs.mockito_core, { exclude group: 'net.bytebuddy' } // DexMaker has it's own MockMaker
+ androidTestImplementation libs.dexmaker_mockito, { exclude group: 'net.bytebuddy' } // DexMaker has it's own MockMaker
+
testCompile libs.junit
}
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json
index 93a9682..c8118b6 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json
@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 7,
- "identityHash": "03ff272b825e27b5c15545c85fe1b845",
+ "identityHash": "dbb4fd91128a81c867a779f0b5d304ff",
"entities": [
{
"tableName": "Entity1",
@@ -73,7 +73,7 @@
},
{
"tableName": "Entity4",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT COLLATE NOCASE, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
"fields": [
{
"fieldPath": "id",
@@ -112,7 +112,7 @@
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
- "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"03ff272b825e27b5c15545c85fe1b845\")"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"dbb4fd91128a81c867a779f0b5d304ff\")"
]
}
}
\ No newline at end of file
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
index 428d87c..337c233 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
@@ -59,6 +59,9 @@
@Query("select * from user where mId IN(:ids)")
public abstract User[] loadByIds(int... ids);
+ @Query("select * from user where custommm = :customField")
+ public abstract List<User> findByCustomField(String customField);
+
@Insert
public abstract void insert(User user);
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationDb.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationDb.java
index 4a95ad8..ef207cf 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationDb.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationDb.java
@@ -17,6 +17,7 @@
package android.arch.persistence.room.integration.testapp.migration;
import android.arch.persistence.db.SupportSQLiteDatabase;
+import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Entity;
@@ -75,6 +76,7 @@
public static final String TABLE_NAME = "Entity4";
@PrimaryKey
public int id;
+ @ColumnInfo(collate = ColumnInfo.NOCASE)
public String name;
}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
index aa297ed..725d53f 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
@@ -315,7 +315,7 @@
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS " + MigrationDb.Entity4.TABLE_NAME
- + " (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`),"
+ + " (`id` INTEGER NOT NULL, `name` TEXT COLLATE NOCASE, PRIMARY KEY(`id`),"
+ " FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`)"
+ " ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)");
}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/CustomDatabaseTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/CustomDatabaseTest.java
index 353c2e3..6f44546 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/CustomDatabaseTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/CustomDatabaseTest.java
@@ -55,7 +55,6 @@
Customer customer = new Customer();
for (int i = 0; i < 100; i++) {
SampleDatabase db = builder.build();
- customer.setId(i);
db.getCustomerDao().insert(customer);
// Give InvalidationTracker enough time to start #mRefreshRunnable and pass the
// initialization check.
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
index 2b4a0e9..8861adb 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
@@ -265,6 +265,16 @@
}
@Test
+ public void findByCollateNoCase() {
+ User user = TestUtil.createUser(3);
+ user.setCustomField("abc");
+ mUserDao.insert(user);
+ List<User> users = mUserDao.findByCustomField("ABC");
+ assertThat(users, hasSize(1));
+ assertThat(users.get(0).getId(), is(3));
+ }
+
+ @Test
public void deleteByAge() {
User user1 = TestUtil.createUser(3);
user1.setAge(30);
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java
index 57cf585..a5b8839 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java
@@ -43,7 +43,7 @@
private Date mBirthday;
- @ColumnInfo(name = "custommm")
+ @ColumnInfo(name = "custommm", collate = ColumnInfo.NOCASE)
private String mCustomField;
public int getId() {
diff --git a/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/RoomPagedListActivity.java b/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/RoomPagedListActivity.java
index 5650829..818c46b 100644
--- a/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/RoomPagedListActivity.java
+++ b/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/RoomPagedListActivity.java
@@ -17,7 +17,6 @@
package android.arch.persistence.room.integration.testapp;
import android.arch.lifecycle.LifecycleRegistry;
-import android.arch.lifecycle.LifecycleRegistryOwner;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
@@ -35,7 +34,7 @@
/**
* Sample PagedList activity which uses Room.
*/
-public class RoomPagedListActivity extends AppCompatActivity implements LifecycleRegistryOwner {
+public class RoomPagedListActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private PagedListCustomerAdapter mAdapter;
diff --git a/room/runtime/build.gradle b/room/runtime/build.gradle
index 18fa660..a170c8e 100644
--- a/room/runtime/build.gradle
+++ b/room/runtime/build.gradle
@@ -46,13 +46,13 @@
dependencies {
api project(":room:common")
- api project(":room:db")
- api project(":room:db-impl")
+ api project(":persistence:db-framework")
+ api project(":persistence:db")
api project(":arch:runtime")
provided project(":paging:common")
provided project(":lifecycle:runtime")
provided project(":lifecycle:extensions")
- compile libs.support.core_utils
+ compile libs.support.core_utils, libs.support_exclude_config
testCompile project(":arch:core-testing")
testCompile libs.junit
diff --git a/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java b/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
index c6eade5..8b7025b 100644
--- a/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
+++ b/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
@@ -199,8 +199,7 @@
SupportSQLiteOpenHelper.Configuration
.builder(InstrumentationRegistry.getTargetContext())
.name(null)
- .version(1)
- .callback(new SupportSQLiteOpenHelper.Callback() {
+ .callback(new SupportSQLiteOpenHelper.Callback(1) {
@Override
public void onCreate(SupportSQLiteDatabase db) {
for (String query : queries) {
diff --git a/room/runtime/src/main/java/android/arch/persistence/room/RoomOpenHelper.java b/room/runtime/src/main/java/android/arch/persistence/room/RoomOpenHelper.java
index 8767f06..47279d6 100644
--- a/room/runtime/src/main/java/android/arch/persistence/room/RoomOpenHelper.java
+++ b/room/runtime/src/main/java/android/arch/persistence/room/RoomOpenHelper.java
@@ -44,6 +44,7 @@
public RoomOpenHelper(@NonNull DatabaseConfiguration configuration, @NonNull Delegate delegate,
@NonNull String identityHash) {
+ super(delegate.version);
mConfiguration = configuration;
mDelegate = delegate;
mIdentityHash = identityHash;
@@ -135,6 +136,12 @@
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public abstract static class Delegate {
+ public final int version;
+
+ public Delegate(int version) {
+ this.version = version;
+ }
+
protected abstract void dropAllTables(SupportSQLiteDatabase database);
protected abstract void createAllTables(SupportSQLiteDatabase database);
diff --git a/room/runtime/src/main/java/android/arch/persistence/room/package-info.java b/room/runtime/src/main/java/android/arch/persistence/room/package-info.java
index faaa952..1dafc1b 100644
--- a/room/runtime/src/main/java/android/arch/persistence/room/package-info.java
+++ b/room/runtime/src/main/java/android/arch/persistence/room/package-info.java
@@ -39,8 +39,8 @@
* database row. For each {@link android.arch.persistence.room.Entity Entity}, a database table
* is created to hold the items. The Entity class must be referenced in the
* {@link android.arch.persistence.room.Database#entities() Database#entities} array. Each field
- * of the Entity is persisted in the database unless it is annotated with
- * {@link android.arch.persistence.room.Ignore Ignore}. Entities must have no-arg constructors.
+ * of the Entity (and its super class) is persisted in the database unless it is denoted
+ * otherwise (see {@link android.arch.persistence.room.Entity Entity} docs for details).
* </li>
* <li>{@link android.arch.persistence.room.Dao Dao}: This annotation marks a class or interface
* as a Data Access Object. Data access objects are the main component of Room that are
diff --git a/room/rxjava2/build.gradle b/room/rxjava2/build.gradle
index d35e7d5..7f86842 100644
--- a/room/rxjava2/build.gradle
+++ b/room/rxjava2/build.gradle
@@ -50,7 +50,7 @@
compile project(":room:common")
compile project(":room:runtime")
compile project(":arch:runtime")
- compile libs.support.core_utils
+ compile libs.support.core_utils, libs.support_exclude_config
compile libs.rx_java
testCompile libs.junit
testCompile libs.mockito_core
diff --git a/room/testing/build.gradle b/room/testing/build.gradle
index ad25e64..078de88 100644
--- a/room/testing/build.gradle
+++ b/room/testing/build.gradle
@@ -42,11 +42,11 @@
dependencies {
compile project(":room:common")
compile project(":room:runtime")
- compile project(":room:db")
- compile project(":room:db-impl")
+ compile project(":persistence:db")
+ compile project(":persistence:db-framework")
compile project(":room:migration")
compile project(":arch:runtime")
- compile libs.support.core_utils
+ compile libs.support.core_utils, libs.support_exclude_config
compile libs.junit
}
diff --git a/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java b/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
index aea3e96..a27fe0f 100644
--- a/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
+++ b/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
@@ -146,7 +146,7 @@
RoomOpenHelper roomOpenHelper = new RoomOpenHelper(configuration,
new CreatingDelegate(schemaBundle.getDatabase()),
schemaBundle.getDatabase().getIdentityHash());
- return openDatabase(name, version, roomOpenHelper);
+ return openDatabase(name, roomOpenHelper);
}
/**
@@ -189,17 +189,15 @@
RoomOpenHelper roomOpenHelper = new RoomOpenHelper(configuration,
new MigratingDelegate(schemaBundle.getDatabase(), validateDroppedTables),
schemaBundle.getDatabase().getIdentityHash());
- return openDatabase(name, version, roomOpenHelper);
+ return openDatabase(name, roomOpenHelper);
}
- private SupportSQLiteDatabase openDatabase(String name, int version,
- RoomOpenHelper roomOpenHelper) {
+ private SupportSQLiteDatabase openDatabase(String name, RoomOpenHelper roomOpenHelper) {
SupportSQLiteOpenHelper.Configuration config =
SupportSQLiteOpenHelper.Configuration
.builder(mInstrumentation.getTargetContext())
.callback(roomOpenHelper)
.name(name)
- .version(version)
.build();
SupportSQLiteDatabase db = mOpenFactory.create(config).getWritableDatabase();
mManagedDatabases.add(new WeakReference<>(db));
@@ -401,6 +399,7 @@
final DatabaseBundle mDatabaseBundle;
RoomOpenHelperDelegate(DatabaseBundle databaseBundle) {
+ super(databaseBundle.getVersion());
mDatabaseBundle = databaseBundle;
}
diff --git a/samples/SupportContentDemos/build.gradle b/samples/SupportContentDemos/build.gradle
index 7e204b1..1ed1134 100644
--- a/samples/SupportContentDemos/build.gradle
+++ b/samples/SupportContentDemos/build.gradle
@@ -31,6 +31,13 @@
targetSdkVersion project.ext.currentSdk
}
+ signingConfigs {
+ debug {
+ // Use a local debug keystore to avoid build server issues.
+ storeFile project.rootProject.init.debugKeystore
+ }
+ }
+
lintOptions {
abortOnError true
disable "SetTextI18n", "AppCompatResource", "WrongConstant", "AllowBackup",
diff --git a/v17/leanback/api/current.txt b/v17/leanback/api/current.txt
index 59b236d..4f5201e 100644
--- a/v17/leanback/api/current.txt
+++ b/v17/leanback/api/current.txt
@@ -1325,6 +1325,7 @@
method protected void onHostStop();
method public void pause();
method public void play();
+ method public void playWhenPrepared();
method public void previous();
method public void removePlayerCallback(android.support.v17.leanback.media.PlaybackGlue.PlayerCallback);
method public final void setHost(android.support.v17.leanback.media.PlaybackGlueHost);
diff --git a/v17/leanback/res/values-bn/strings.xml b/v17/leanback/res/values-bn/strings.xml
index 899c564..d0e08c4 100644
--- a/v17/leanback/res/values-bn/strings.xml
+++ b/v17/leanback/res/values-bn/strings.xml
@@ -21,7 +21,7 @@
<string name="orb_search_action" msgid="5651268540267663887">"অনুসন্ধান অ্যাকশন"</string>
<string name="lb_search_bar_hint" msgid="8325490927970116252">"অনুসন্ধান"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"অনুসন্ধান করতে বলুন"</string>
- <string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> অনুসন্ধান করুন"</string>
+ <string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> খুঁজুন"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> অনুসন্ধান করতে বলুন"</string>
<string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
<string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
@@ -33,11 +33,11 @@
<string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"পেছনের দিকে যান %1$dX"</string>
<string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"সরাসরি পরেরটিতে চলে যান"</string>
<string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"সরাসরি আগেরটিতে চলে যান"</string>
- <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"আরো অ্যাকশন"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"আরও অ্যাকশন"</string>
<string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"উপরের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচন মুক্ত করুন"</string>
<string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"উপরের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচিত করুন"</string>
<string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"নীচের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচন মুক্ত করুন"</string>
- <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"নীচের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচন করুন"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"নীচের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন বেছে নিন"</string>
<string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"একটিরও পুনরাবৃত্তি করবেন না"</string>
<string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"সবগুলির পুনরাবৃত্তি করুন"</string>
<string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"একটির পুনরাবৃত্তি করুন"</string>
diff --git a/v17/leanback/res/values-hi/strings.xml b/v17/leanback/res/values-hi/strings.xml
index 6287f14..00ef8ab 100644
--- a/v17/leanback/res/values-hi/strings.xml
+++ b/v17/leanback/res/values-hi/strings.xml
@@ -41,11 +41,11 @@
<string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"कुछ भी न दोहराएं"</string>
<string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"सभी को दोहराएं"</string>
<string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"एक दोहराएं"</string>
- <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"फेर-बदल सक्षम करें"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"शफ़ल करना चालू करें"</string>
<string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"फेर-बदल अक्षम करें"</string>
- <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"उच्च गुणवत्ता सक्षम करें"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"अच्छी क्वालिटी में चलाएं"</string>
<string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"उच्च गुणवत्ता अक्षम करें"</string>
- <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"उपशीर्षक सक्षम करें"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"सबटाइटल चालू करें"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"उपशीर्षक अक्षम करें"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"चित्र मोड में चित्र डालें"</string>
<string name="lb_playback_time_separator" msgid="3208380806582304911">"/"</string>
@@ -55,5 +55,5 @@
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"जारी रखें"</string>
<string name="lb_media_player_error" msgid="3650250994187305396">"मीडिया प्लेयर गड़बड़ी कोड %1$d कुछ और %2$d"</string>
<string name="lb_onboarding_get_started" msgid="6961440391306351139">"शुरू करें"</string>
- <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"अगला"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"आगे बढ़ें"</string>
</resources>
diff --git a/v17/leanback/res/values-pa/strings.xml b/v17/leanback/res/values-pa/strings.xml
index 4b3c515..57956ee 100644
--- a/v17/leanback/res/values-pa/strings.xml
+++ b/v17/leanback/res/values-pa/strings.xml
@@ -18,7 +18,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="lb_navigation_menu_contentDescription" msgid="6215811486591629025">"ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਮੀਨੂ"</string>
- <string name="orb_search_action" msgid="5651268540267663887">"ਖੋਜ ਕਿਰਿਆ"</string>
+ <string name="orb_search_action" msgid="5651268540267663887">"ਖੋਜ ਕਾਰਵਾਈ"</string>
<string name="lb_search_bar_hint" msgid="8325490927970116252">"ਖੋਜੋ"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"ਖੋਜਣ ਲਈ ਬੋਲੋ"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ਖੋਜੋ"</string>
@@ -27,12 +27,12 @@
<string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
<string name="lb_playback_controls_play" msgid="731953341987346903">"ਪਲੇ ਕਰੋ"</string>
<string name="lb_playback_controls_pause" msgid="6189521112079849518">"ਰੋਕੋ"</string>
- <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ਅੱਗੇ ਭੇਜੋ"</string>
- <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX ਨੂੰ ਅੱਗੇ ਭੇਜੋ"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਭੇਜੋ"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX ਨੂੰ ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਭੇਜੋ"</string>
<string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ਰੀਵਾਈਂਡ"</string>
<string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX ਨੂੰ ਰੀਵਾਈਂਡ ਕਰੋ"</string>
- <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"ਅਗਲਾ ਨੂੰ ਛੱਡੋ"</string>
- <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"ਪਿਛਲਾ ਨੂੰ ਛੱਡੋ"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"ਅਗਲੇ ਨੂੰ ਛੱਡੋ"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"ਪਿਛਲੇ ਨੂੰ ਛੱਡੋ"</string>
<string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"ਹੋਰ ਕਿਰਿਆਵਾਂ"</string>
<string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"ਥੰਬ ਅਪ ਨੂੰ ਅਚੋਣਵਾਂ ਕਰੋ"</string>
<string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"ਥੰਬ ਅਪ ਨੂੰ ਚੁਣੋ"</string>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
index 7686c5c..d4c8d5d 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
@@ -267,6 +267,10 @@
void onExecuteEntranceTransition() {
// wait till views get their initial position before start transition
final View view = getView();
+ if (view == null) {
+ // fragment view destroyed, transition not needed
+ return;
+ }
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
index 213ed83..cbc4fa2 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
@@ -270,6 +270,10 @@
void onExecuteEntranceTransition() {
// wait till views get their initial position before start transition
final View view = getView();
+ if (view == null) {
+ // fragment view destroyed, transition not needed
+ return;
+ }
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
diff --git a/v17/leanback/src/android/support/v17/leanback/media/PlaybackBannerControlGlue.java b/v17/leanback/src/android/support/v17/leanback/media/PlaybackBannerControlGlue.java
index ca424a8..e644632 100644
--- a/v17/leanback/src/android/support/v17/leanback/media/PlaybackBannerControlGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/media/PlaybackBannerControlGlue.java
@@ -59,6 +59,24 @@
* {@link #onPlayCompleted()}.
* </p>
*
+ * Sample Code:
+ * <pre><code>
+ * public class MyVideoFragment extends VideoFragment {
+ * @Override
+ * public void onCreate(Bundle savedInstanceState) {
+ * super.onCreate(savedInstanceState);
+ * PlaybackBannerControlGlue<MediaPlayerAdapter> playerGlue =
+ * new PlaybackBannerControlGlue(getActivity(),
+ * new MediaPlayerAdapter(getActivity()));
+ * playerGlue.setHost(new VideoFragmentGlueHost(this));
+ * playerGlue.setSubtitle("Leanback artist");
+ * playerGlue.setTitle("Leanback team at work");
+ * String uriPath = "android.resource://com.example.android.leanback/raw/video";
+ * playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath));
+ * playerGlue.playWhenPrepared();
+ * }
+ * }
+ * </code></pre>
* @param <T> Type of {@link PlayerAdapter} passed in constructor.
*/
public class PlaybackBannerControlGlue<T extends PlayerAdapter>
diff --git a/v17/leanback/src/android/support/v17/leanback/media/PlaybackGlue.java b/v17/leanback/src/android/support/v17/leanback/media/PlaybackGlue.java
index 32d5545..020f660 100644
--- a/v17/leanback/src/android/support/v17/leanback/media/PlaybackGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/media/PlaybackGlue.java
@@ -174,12 +174,32 @@
}
/**
- * Starts the media player.
+ * Starts the media player. Does nothing if {@link #isPrepared()} is false. To wait
+ * {@link #isPrepared()} to be true before playing, use {@link #playWhenPrepared()}.
*/
public void play() {
}
/**
+ * Starts play when {@link #isPrepared()} becomes true.
+ */
+ public void playWhenPrepared() {
+ if (isPrepared()) {
+ play();
+ } else {
+ addPlayerCallback(new PlayerCallback() {
+ @Override
+ public void onPreparedStateChanged(PlaybackGlue glue) {
+ if (glue.isPrepared()) {
+ removePlayerCallback(this);
+ play();
+ }
+ }
+ });
+ }
+ }
+
+ /**
* Pauses the media player.
*/
public void pause() {
diff --git a/v17/leanback/src/android/support/v17/leanback/media/PlaybackTransportControlGlue.java b/v17/leanback/src/android/support/v17/leanback/media/PlaybackTransportControlGlue.java
index d0496e4..4aa9bf6 100644
--- a/v17/leanback/src/android/support/v17/leanback/media/PlaybackTransportControlGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/media/PlaybackTransportControlGlue.java
@@ -68,23 +68,15 @@
* @Override
* public void onCreate(Bundle savedInstanceState) {
* super.onCreate(savedInstanceState);
- * final PlaybackTransportControlGlue<MediaPlayerAdapter> playerGlue =
+ * PlaybackTransportControlGlue<MediaPlayerAdapter> playerGlue =
* new PlaybackTransportControlGlue(getActivity(),
* new MediaPlayerAdapter(getActivity()));
* playerGlue.setHost(new VideoFragmentGlueHost(this));
- * playerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() {
- * @Override
- * public void onPreparedStateChanged(PlaybackGlue glue) {
- * if (glue.isPrepared()) {
- * playerGlue.setSeekProvider(new MySeekProvider());
- * playerGlue.play();
- * }
- * }
- * });
* playerGlue.setSubtitle("Leanback artist");
* playerGlue.setTitle("Leanback team at work");
* String uriPath = "android.resource://com.example.android.leanback/raw/video";
* playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath));
+ * playerGlue.playWhenPrepared();
* }
* }
* </code></pre>
@@ -254,9 +246,7 @@
// playing paused paused
// paused playing playing
// ff/rw playing playing paused
- if (canPause
- && (canPlay ? mIsPlaying :
- !mIsPlaying)) {
+ if (canPause && mIsPlaying) {
mIsPlaying = false;
pause();
} else if (canPlay && !mIsPlaying) {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
index 6787491..38d08c7 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
@@ -34,6 +34,7 @@
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
+import android.support.test.filters.SdkSuppress;
import android.support.v17.leanback.R;
import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
import android.support.v17.leanback.media.MediaPlayerGlue;
@@ -1171,4 +1172,45 @@
});
}
+ public static class DetailsFragmentEntranceTransitionTimeout extends DetailsTestFragment {
+
+ public DetailsFragmentEntranceTransitionTimeout() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ prepareEntranceTransition();
+ }
+
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+ public void startEntranceTransitionAfterDestroyed() {
+ SingleFragmentTestActivity activity = launchAndWaitActivity(
+ DetailsFragmentEntranceTransition.class, new Options().uiVisibility(
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN),
+ 1000);
+ final DetailsFragmentEntranceTransition detailsFragment =
+ (DetailsFragmentEntranceTransition)
+ activity.getTestFragment();
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+ android.support.v17.leanback.test.R.drawable.spiderman));
+ }
+ });
+ SystemClock.sleep(100);
+ activity.finish();
+ PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity));
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ detailsFragment.startEntranceTransition();
+ }
+ });
+ }
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
index d4a41e0..04f20bc 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
@@ -37,6 +37,7 @@
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
+import android.support.test.filters.SdkSuppress;
import android.support.v17.leanback.R;
import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
import android.support.v17.leanback.media.MediaPlayerGlue;
@@ -1174,4 +1175,45 @@
});
}
+ public static class DetailsSupportFragmentEntranceTransitionTimeout extends DetailsTestSupportFragment {
+
+ public DetailsSupportFragmentEntranceTransitionTimeout() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ prepareEntranceTransition();
+ }
+
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+ public void startEntranceTransitionAfterDestroyed() {
+ SingleSupportFragmentTestActivity activity = launchAndWaitActivity(
+ DetailsSupportFragmentEntranceTransition.class, new Options().uiVisibility(
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN),
+ 1000);
+ final DetailsSupportFragmentEntranceTransition detailsFragment =
+ (DetailsSupportFragmentEntranceTransition)
+ activity.getTestFragment();
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+ android.support.v17.leanback.test.R.drawable.spiderman));
+ }
+ });
+ SystemClock.sleep(100);
+ activity.finish();
+ PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity));
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ detailsFragment.startEntranceTransition();
+ }
+ });
+ }
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueTest.java
index 0f96196..38c73e8 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueTest.java
@@ -17,10 +17,13 @@
package android.support.v17.leanback.media;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
@@ -114,4 +117,25 @@
assertTrue(called[1]);
assertEquals(2, glue.getPlayerCallbacks().size());
}
+
+ @Test
+ public void playWhenPrepared() {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ PlaybackGlue glue = Mockito.spy(new PlaybackGlueImpl(context));
+ PlaybackGlueHostImpl host = new PlaybackGlueHostImpl();
+
+ when(glue.isPrepared()).thenReturn(false);
+ glue.setHost(host);
+ glue.playWhenPrepared();
+ assertFalse(glue.isPrepared());
+ Mockito.verify(glue, never()).play();
+
+ when(glue.isPrepared()).thenReturn(true);
+ for (PlaybackGlue.PlayerCallback callback: glue.getPlayerCallbacks()) {
+ callback.onPreparedStateChanged(glue);
+ }
+ assertTrue(glue.isPrepared());
+ Mockito.verify(glue, times(1)).play();
+ assertEquals(0, glue.getPlayerCallbacks().size());
+ }
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackTransportControlGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackTransportControlGlueTest.java
index d6ce824..ab936ad 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackTransportControlGlueTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackTransportControlGlueTest.java
@@ -22,6 +22,7 @@
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
@@ -33,6 +34,7 @@
import android.support.v17.leanback.widget.PlaybackTransportRowPresenter;
import android.support.v17.leanback.widget.RowPresenter;
import android.view.ContextThemeWrapper;
+import android.view.KeyEvent;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -67,6 +69,41 @@
Context mContext;
PlaybackTransportControlGlueImpl mGlue;
PlaybackTransportRowPresenter.ViewHolder mViewHolder;
+ PlayerAdapter mAdapter;
+
+ void setupWithMockAdapterAndViewHolder() {
+ mContext = new ContextThemeWrapper(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(),
+ android.support.v17.leanback.test.R.style.Theme_Leanback);
+
+ mAdapter = Mockito.mock(PlayerAdapter.class);
+ when(mAdapter.isPrepared()).thenReturn(true);
+ when(mAdapter.getCurrentPosition()).thenReturn(123L);
+ when(mAdapter.getDuration()).thenReturn(20000L);
+ when(mAdapter.getBufferedPosition()).thenReturn(321L);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mGlue = new PlaybackTransportControlGlueImpl(mContext, mAdapter);
+ PlaybackGlueHostImpl host = new PlaybackGlueHostImpl();
+ mGlue.setHost(host);
+
+ PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter)
+ mGlue.getPlaybackRowPresenter();
+ FrameLayout parent = new FrameLayout(mContext);
+ mViewHolder = (PlaybackTransportRowPresenter.ViewHolder)
+ presenter.onCreateViewHolder(parent);
+ presenter.onBindViewHolder(mViewHolder, mGlue.getControlsRow());
+ }
+ });
+ }
+
+ void playMockAdapter() {
+ mGlue.play();
+ Mockito.verify(mAdapter, times(1)).play();
+ when(mAdapter.isPlaying()).thenReturn(true);
+ mAdapter.getCallback().onPlayStateChanged(mAdapter);
+ }
@Test
public void usingDefaultRowAndPresenter() {
@@ -163,54 +200,30 @@
@Test
public void playerAdapterTest() {
- mContext = new ContextThemeWrapper(
- InstrumentationRegistry.getInstrumentation().getTargetContext(),
- android.support.v17.leanback.test.R.style.Theme_Leanback);
-
- final PlayerAdapter impl = Mockito.mock(PlayerAdapter.class);
- when(impl.isPrepared()).thenReturn(true);
- when(impl.getCurrentPosition()).thenReturn(123L);
- when(impl.getDuration()).thenReturn(20000L);
- when(impl.getBufferedPosition()).thenReturn(321L);
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mGlue = new PlaybackTransportControlGlueImpl(mContext, impl);
- PlaybackGlueHostImpl host = new PlaybackGlueHostImpl();
- mGlue.setHost(host);
-
- PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter)
- mGlue.getPlaybackRowPresenter();
- FrameLayout parent = new FrameLayout(mContext);
- mViewHolder = (PlaybackTransportRowPresenter.ViewHolder)
- presenter.onCreateViewHolder(parent);
- presenter.onBindViewHolder(mViewHolder, mGlue.getControlsRow());
- }
- });
-
+ setupWithMockAdapterAndViewHolder();
mGlue.play();
- Mockito.verify(impl, times(1)).play();
+ Mockito.verify(mAdapter, times(1)).play();
mGlue.pause();
- Mockito.verify(impl, times(1)).pause();
+ Mockito.verify(mAdapter, times(1)).pause();
mGlue.seekTo(123L);
- Mockito.verify(impl, times(1)).seekTo(123L);
+ Mockito.verify(mAdapter, times(1)).seekTo(123L);
assertEquals(123L, mGlue.getCurrentPosition());
assertEquals(20000L, mGlue.getDuration());
assertEquals(321L, mGlue.getBufferedPosition());
- assertSame(mGlue.mAdapterCallback, impl.getCallback());
+ assertSame(mGlue.mAdapterCallback, mAdapter.getCallback());
- when(impl.getCurrentPosition()).thenReturn(124L);
- impl.getCallback().onCurrentPositionChanged(impl);
+ when(mAdapter.getCurrentPosition()).thenReturn(124L);
+ mAdapter.getCallback().onCurrentPositionChanged(mAdapter);
assertEquals(124L, mGlue.getControlsRow().getCurrentPosition());
- when(impl.getBufferedPosition()).thenReturn(333L);
- impl.getCallback().onBufferedPositionChanged(impl);
+ when(mAdapter.getBufferedPosition()).thenReturn(333L);
+ mAdapter.getCallback().onBufferedPositionChanged(mAdapter);
assertEquals(333L, mGlue.getControlsRow().getBufferedPosition());
- when(impl.getDuration()).thenReturn((long) (Integer.MAX_VALUE) * 2);
- impl.getCallback().onDurationChanged(impl);
+ when(mAdapter.getDuration()).thenReturn((long) (Integer.MAX_VALUE) * 2);
+ mAdapter.getCallback().onDurationChanged(mAdapter);
assertEquals((long) (Integer.MAX_VALUE) * 2, mGlue.getControlsRow().getDuration());
}
@@ -272,4 +285,60 @@
Mockito.verify(hostCallback2, times(0)).onError(anyInt(), anyString());
}
+ @Test
+ public void playStateReceivePlayPause() {
+ setupWithMockAdapterAndViewHolder();
+ playMockAdapter();
+
+ mGlue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE,
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
+ Mockito.verify(mAdapter, times(1)).pause();
+ }
+
+ @Test
+ public void playStateReceivePause() {
+ setupWithMockAdapterAndViewHolder();
+ playMockAdapter();
+
+ mGlue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE,
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PAUSE));
+ Mockito.verify(mAdapter, times(1)).pause();
+ }
+
+ @Test
+ public void playStateReceivePlay() {
+ setupWithMockAdapterAndViewHolder();
+ playMockAdapter();
+
+ mGlue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY,
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY));
+ Mockito.verify(mAdapter, never()).pause();
+ }
+
+ @Test
+ public void pauseStateReceivePlayPause() {
+ setupWithMockAdapterAndViewHolder();
+
+ mGlue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE,
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
+ Mockito.verify(mAdapter, times(1)).play();
+ }
+
+ @Test
+ public void pauseStateReceivePause() {
+ setupWithMockAdapterAndViewHolder();
+
+ mGlue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE,
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PAUSE));
+ Mockito.verify(mAdapter, never()).play();
+ }
+
+ @Test
+ public void pauseStateReceivePlay() {
+ setupWithMockAdapterAndViewHolder();
+
+ mGlue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY,
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY));
+ Mockito.verify(mAdapter, times(1)).play();
+ }
}
diff --git a/v7/appcompat/res/values-bn/strings.xml b/v7/appcompat/res/values-bn/strings.xml
index 5959799..2ea7591 100644
--- a/v7/appcompat/res/values-bn/strings.xml
+++ b/v7/appcompat/res/values-bn/strings.xml
@@ -19,11 +19,11 @@
<string name="abc_action_mode_done" msgid="4076576682505996667">"সম্পন্ন হয়েছে"</string>
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"হোম এ নেভিগেট করুন"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"উপরের দিকে নেভিগেট করুন"</string>
- <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"আরো বিকল্প"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"আরও বিকল্প"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"সঙ্কুচিত করুন"</string>
- <string name="abc_searchview_description_search" msgid="8264924765203268293">"অনুসন্ধান করুন"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"খুঁজুন"</string>
<string name="abc_search_hint" msgid="7723749260725869598">"অনুসন্ধান..."</string>
- <string name="abc_searchview_description_query" msgid="2550479030709304392">"ক্যোয়ারী অনুসন্ধান করুন"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"ক্যোয়ারী খুঁজুন"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"ক্যোয়ারী সাফ করুন"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ক্যোয়ারী জমা দিন"</string>
<string name="abc_searchview_description_voice" msgid="893419373245838918">"ভয়েস অনুসন্ধান"</string>
@@ -33,5 +33,5 @@
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"এর সাথে শেয়ার করুন"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"চালু"</string>
<string name="abc_capital_off" msgid="121134116657445385">"বন্ধ"</string>
- <string name="search_menu_title" msgid="146198913615257606">"অনুসন্ধান করুন"</string>
+ <string name="search_menu_title" msgid="146198913615257606">"খুঁজুন"</string>
</resources>
diff --git a/v7/appcompat/res/values-hi/strings.xml b/v7/appcompat/res/values-hi/strings.xml
index 0d90e55..3a393c7 100644
--- a/v7/appcompat/res/values-hi/strings.xml
+++ b/v7/appcompat/res/values-hi/strings.xml
@@ -16,11 +16,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="abc_action_mode_done" msgid="4076576682505996667">"पूर्ण"</string>
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"हो गया"</string>
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"होम पेज पर जाएं"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"ऊपर जाएं"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ज़्यादा विकल्प"</string>
- <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"संक्षिप्त करें"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"छोटा करें"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"सर्च करें"</string>
<string name="abc_search_hint" msgid="7723749260725869598">"खोजा जा रहा है…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"सर्च क्वेरी"</string>
diff --git a/v7/appcompat/res/values-pa/strings.xml b/v7/appcompat/res/values-pa/strings.xml
index bc2e6ea..7f28ac8 100644
--- a/v7/appcompat/res/values-pa/strings.xml
+++ b/v7/appcompat/res/values-pa/strings.xml
@@ -17,13 +17,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_action_mode_done" msgid="4076576682505996667">"ਹੋ ਗਿਆ"</string>
- <string name="abc_action_bar_home_description" msgid="4600421777120114993">"ਹੋਮ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
- <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ਉੱਪਰ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"ਹੋਮ \'ਤੇ ਜਾਓ"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ਉੱਪਰ ਜਾਓ"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ਹੋਰ ਚੋਣਾਂ"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"ਨਸ਼ਟ ਕਰੋ"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"ਖੋਜੋ"</string>
<string name="abc_search_hint" msgid="7723749260725869598">"ਖੋਜ…"</string>
- <string name="abc_searchview_description_query" msgid="2550479030709304392">"ਸਵਾਲ ਖੋਜੋ"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"ਖੋਜ ਪੁੱਛਗਿੱਛ"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"ਸਵਾਲ ਹਟਾਓ"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ਸਵਾਲ ਪ੍ਰਸਤੁਤ ਕਰੋ"</string>
<string name="abc_searchview_description_voice" msgid="893419373245838918">"ਵੌਇਸ ਖੋਜ"</string>
@@ -33,5 +33,5 @@
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ਇਸ ਨਾਲ ਸਾਂਝਾ ਕਰੋ"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"ਤੇ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ਬੰਦ"</string>
- <string name="search_menu_title" msgid="146198913615257606">"ਖੋਜ"</string>
+ <string name="search_menu_title" msgid="146198913615257606">"ਖੋਜੋ"</string>
</resources>
diff --git a/v7/appcompat/res/values-ta/strings.xml b/v7/appcompat/res/values-ta/strings.xml
index 7daeaaf..4a2ad2f 100644
--- a/v7/appcompat/res/values-ta/strings.xml
+++ b/v7/appcompat/res/values-ta/strings.xml
@@ -31,7 +31,7 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"எல்லாம் காட்டு"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> மூலம் பகிர்"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"இதனுடன் பகிர்"</string>
- <string name="abc_capital_on" msgid="3405795526292276155">"இயக்கு"</string>
- <string name="abc_capital_off" msgid="121134116657445385">"முடக்கு"</string>
+ <string name="abc_capital_on" msgid="3405795526292276155">"ஆன்"</string>
+ <string name="abc_capital_off" msgid="121134116657445385">"ஆஃப்"</string>
<string name="search_menu_title" msgid="146198913615257606">"தேடு"</string>
</resources>
diff --git a/v7/appcompat/res/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index d48d826..52ae694 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -568,6 +568,9 @@
<enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
<enum name="screen" value="15" />
+ <!-- Combines the tint and icon color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
</attr>
</declare-styleable>
@@ -1037,6 +1040,9 @@
<enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
<enum name="screen" value="15" />
+ <!-- Combines the tint and icon color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
</attr>
</declare-styleable>
@@ -1175,6 +1181,9 @@
<enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
<enum name="screen" value="15" />
+ <!-- Combines the tint and icon color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
</attr>
</declare-styleable>
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
index 90e6aa9..b2b1f10 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
@@ -23,7 +23,6 @@
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
import android.net.Uri;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
@@ -102,14 +101,6 @@
}
@Override
- public void setImageIcon(@Nullable Icon icon) {
- super.setImageIcon(icon);
- if (mImageHelper != null) {
- mImageHelper.applySupportImageTint();
- }
- }
-
- @Override
public void setImageURI(@Nullable Uri uri) {
super.setImageURI(uri);
if (mImageHelper != null) {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
index 0844f9a..f50799e 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
@@ -23,7 +23,6 @@
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
import android.net.Uri;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
@@ -112,14 +111,6 @@
}
@Override
- public void setImageIcon(@Nullable Icon icon) {
- super.setImageIcon(icon);
- if (mImageHelper != null) {
- mImageHelper.applySupportImageTint();
- }
- }
-
- @Override
public void setImageURI(@Nullable Uri uri) {
super.setImageURI(uri);
if (mImageHelper != null) {
diff --git a/v7/mediarouter/res/values-hi/strings.xml b/v7/mediarouter/res/values-hi/strings.xml
index adf3e88..f9ac43b 100644
--- a/v7/mediarouter/res/values-hi/strings.xml
+++ b/v7/mediarouter/res/values-hi/strings.xml
@@ -30,8 +30,8 @@
<string name="mr_controller_play" msgid="683634565969987458">"चलाएं"</string>
<string name="mr_controller_pause" msgid="5451884435510905406">"रोकें"</string>
<string name="mr_controller_stop" msgid="735874641921425123">"बंद करें"</string>
- <string name="mr_controller_expand_group" msgid="8062427022744266907">"विस्तृत करें"</string>
- <string name="mr_controller_collapse_group" msgid="7924809056904240926">"संक्षिप्त करें"</string>
+ <string name="mr_controller_expand_group" msgid="8062427022744266907">"विस्तार करें"</string>
+ <string name="mr_controller_collapse_group" msgid="7924809056904240926">"छोटा करें"</string>
<string name="mr_controller_album_art" msgid="6422801843540543585">"एल्बम आर्ट"</string>
<string name="mr_controller_volume_slider" msgid="2361785992211841709">"वॉल्यूम स्लाइडर"</string>
<string name="mr_controller_no_media_selected" msgid="6547130360349182381">"कोई मीडिया चयनित नहीं है"</string>
diff --git a/v7/mediarouter/res/values-ta/strings.xml b/v7/mediarouter/res/values-ta/strings.xml
index 59dac88..99c6172 100644
--- a/v7/mediarouter/res/values-ta/strings.xml
+++ b/v7/mediarouter/res/values-ta/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mr_system_route_name" msgid="5441529851481176817">"அமைப்பு"</string>
+ <string name="mr_system_route_name" msgid="5441529851481176817">"சிஸ்டம்"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"சாதனங்கள்"</string>
<string name="mr_button_content_description" msgid="3698378085901466129">"திரையிடு பட்டன்"</string>
<string name="mr_cast_button_disconnected" msgid="816305490427819240">"அனுப்புதல் பொத்தான். துண்டிக்கப்பட்டது"</string>
diff --git a/v7/mediarouter/res/values/themes.xml b/v7/mediarouter/res/values/themes.xml
index 8c6e97a..586db92 100644
--- a/v7/mediarouter/res/values/themes.xml
+++ b/v7/mediarouter/res/values/themes.xml
@@ -17,6 +17,7 @@
<resources>
<style name="Theme.MediaRouter" parent="ThemeOverlay.AppCompat.Dark">
+ <item name="android:backgroundDimEnabled">true</item>
<item name="windowNoTitle">true</item>
<item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.MediaRouteButton</item>
@@ -38,6 +39,7 @@
</style>
<style name="Theme.MediaRouter.Light" parent="ThemeOverlay.AppCompat.Light">
+ <item name="android:backgroundDimEnabled">true</item>
<item name="windowNoTitle">true</item>
<item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.Light.MediaRouteButton</item>
diff --git a/v7/preference/res/layout/preference_dialog_edittext.xml b/v7/preference/res/layout/preference_dialog_edittext.xml
index 9fbf2b7..34aa7f3 100644
--- a/v7/preference/res/layout/preference_dialog_edittext.xml
+++ b/v7/preference/res/layout/preference_dialog_edittext.xml
@@ -25,7 +25,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="5dip"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
android:orientation="vertical">
<TextView android:id="@android:id/message"
@@ -35,10 +36,12 @@
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary" />
- <EditText
- android:id="@android:id/edit"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ <EditText
+ android:id="@android:id/edit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="-4dp"
+ android:layout_marginEnd="-4dp" />
</LinearLayout>