Merge "Tweaks to CarContext#requestPermissions javadoc" into androidx-main
diff --git a/core/core/lint-baseline.xml b/core/core/lint-baseline.xml
index 63626a6..cbe1a6d 100644
--- a/core/core/lint-baseline.xml
+++ b/core/core/lint-baseline.xml
@@ -46,39 +46,6 @@
</issue>
<issue
- id="BanSynchronizedMethods"
- message="Use of synchronized methods is not recommended"
- errorLine1=" /**"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/core/widget/ContentLoadingProgressBar.java"
- line="92"
- column="5"/>
- </issue>
-
- <issue
- id="BanSynchronizedMethods"
- message="Use of synchronized methods is not recommended"
- errorLine1=" /**"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/core/widget/ContentLoadingProgressBar.java"
- line="118"
- column="5"/>
- </issue>
-
- <issue
- id="BanSynchronizedMethods"
- message="Use of synchronized methods is not recommended"
- errorLine1=" private synchronized static File createFilesDir(File file) {"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="602"
- column="5"/>
- </issue>
-
- <issue
id="BanUncheckedReflection"
message="Calling Method.invoke without an SDK check"
errorLine1=" requestRelaunchActivityMethod.invoke(activityThread,"
diff --git a/core/core/src/main/java/androidx/core/content/ContextCompat.java b/core/core/src/main/java/androidx/core/content/ContextCompat.java
index 882f35b..2f54ab4 100644
--- a/core/core/src/main/java/androidx/core/content/ContextCompat.java
+++ b/core/core/src/main/java/androidx/core/content/ContextCompat.java
@@ -158,6 +158,9 @@
private static final Object sLock = new Object();
+ // Lock that provides similar functionality to ContextImpl.mSync.
+ private static final Object sSync = new Object();
+
private static TypedValue sTempValue;
/**
@@ -599,18 +602,23 @@
}
}
- private synchronized static File createFilesDir(File file) {
- if (!file.exists()) {
- if (!file.mkdirs()) {
- if (file.exists()) {
- // spurious failure; probably racing with another process for this app
+ private static File createFilesDir(File file) {
+ // In the platform, all operations on Context that involve creating files (codeCacheDir,
+ // noBackupFilesDir, etc.) are synchronized on a single lock owned by the Context. So, if
+ // we lock on a single static lock owned by ContextCompat then we're a bit too broad but
+ // at least we'll provide similar guarantees.
+ synchronized (sSync) {
+ if (!file.exists()) {
+ if (file.mkdirs()) {
return file;
+ } else {
+ // There used to be another check for file.exists() here, but that was a
+ // side-effect of improper synchronization.
+ Log.w(TAG, "Unable to create files subdir " + file.getPath());
}
- Log.w(TAG, "Unable to create files subdir " + file.getPath());
- return null;
}
+ return file;
}
- return file;
}
/**
diff --git a/core/core/src/main/java/androidx/core/widget/ContentLoadingProgressBar.java b/core/core/src/main/java/androidx/core/widget/ContentLoadingProgressBar.java
index e24b6a1..2eb84ef 100644
--- a/core/core/src/main/java/androidx/core/widget/ContentLoadingProgressBar.java
+++ b/core/core/src/main/java/androidx/core/widget/ContentLoadingProgressBar.java
@@ -23,44 +23,35 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
/**
* ContentLoadingProgressBar implements a ProgressBar that waits a minimum time to be
* dismissed before showing. Once visible, the progress bar will be visible for
* a minimum amount of time to avoid "flashes" in the UI when an event could take
- * a largely variable time to complete (from none, to a user perceivable amount)
+ * a largely variable time to complete (from none, to a user perceivable amount).
*/
public class ContentLoadingProgressBar extends ProgressBar {
- private static final int MIN_SHOW_TIME = 500; // ms
- private static final int MIN_DELAY = 500; // ms
+ private static final int MIN_SHOW_TIME_MS = 500;
+ private static final int MIN_DELAY_MS = 500;
+ // These fields should only be accessed on the UI thread.
long mStartTime = -1;
-
boolean mPostedHide = false;
-
boolean mPostedShow = false;
-
boolean mDismissed = false;
- private final Runnable mDelayedHide = new Runnable() {
-
- @Override
- public void run() {
- mPostedHide = false;
- mStartTime = -1;
- setVisibility(View.GONE);
- }
+ private final Runnable mDelayedHide = () -> {
+ mPostedHide = false;
+ mStartTime = -1;
+ setVisibility(View.GONE);
};
- private final Runnable mDelayedShow = new Runnable() {
-
- @Override
- public void run() {
- mPostedShow = false;
- if (!mDismissed) {
- mStartTime = System.currentTimeMillis();
- setVisibility(View.VISIBLE);
- }
+ private final Runnable mDelayedShow = () -> {
+ mPostedShow = false;
+ if (!mDismissed) {
+ mStartTime = System.currentTimeMillis();
+ setVisibility(View.VISIBLE);
}
};
@@ -93,13 +84,23 @@
* Hide the progress view if it is visible. The progress view will not be
* hidden until it has been shown for at least a minimum show time. If the
* progress view was not yet visible, cancels showing the progress view.
+ * <p>
+ * This method may be called off the UI thread.
*/
- public synchronized void hide() {
+ public void hide() {
+ // This method used to be synchronized, presumably so that it could be safely called off
+ // the UI thread; however, the referenced fields were still accessed both on and off the
+ // UI thread, e.g. not thread-safe. Now we hand-off everything to the UI thread.
+ post(this::hideOnUiThread);
+ }
+
+ @UiThread
+ private void hideOnUiThread() {
mDismissed = true;
removeCallbacks(mDelayedShow);
mPostedShow = false;
long diff = System.currentTimeMillis() - mStartTime;
- if (diff >= MIN_SHOW_TIME || mStartTime == -1) {
+ if (diff >= MIN_SHOW_TIME_MS || mStartTime == -1) {
// The progress spinner has been shown long enough
// OR was not shown yet. If it wasn't shown yet,
// it will just never be shown.
@@ -109,7 +110,7 @@
// so put a delayed message in to hide it when its been
// shown long enough.
if (!mPostedHide) {
- postDelayed(mDelayedHide, MIN_SHOW_TIME - diff);
+ postDelayed(mDelayedHide, MIN_SHOW_TIME_MS - diff);
mPostedHide = true;
}
}
@@ -118,15 +119,25 @@
/**
* Show the progress view after waiting for a minimum delay. If
* during that time, hide() is called, the view is never made visible.
+ * <p>
+ * This method may be called off the UI thread.
*/
- public synchronized void show() {
+ public void show() {
+ // This method used to be synchronized, presumably so that it could be safely called off
+ // the UI thread; however, the referenced fields were still accessed both on and off the
+ // UI thread, e.g. not thread-safe. Now we hand-off everything to the UI thread.
+ post(this::showOnUiThread);
+ }
+
+ @UiThread
+ private void showOnUiThread() {
// Reset the start time.
mStartTime = -1;
mDismissed = false;
removeCallbacks(mDelayedHide);
mPostedHide = false;
if (!mPostedShow) {
- postDelayed(mDelayedShow, MIN_DELAY);
+ postDelayed(mDelayedShow, MIN_DELAY_MS);
mPostedShow = true;
}
}
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index 69af6e3..1ffc337 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -208,6 +208,7 @@
docs(project(":room:room-guava"))
docs(project(":room:room-ktx"))
docs(project(":room:room-migration"))
+ docs(project(":room:room-paging"))
docs(project(":room:room-runtime"))
docs(project(":room:room-rxjava2"))
docs(project(":room:room-rxjava3"))
diff --git a/room/OWNERS b/room/OWNERS
index 3ea2934..6d57c2e 100644
--- a/room/OWNERS
+++ b/room/OWNERS
@@ -1,5 +1,6 @@
[email protected]
[email protected]
[email protected]
[email protected]
-per-file settings.gradle = [email protected], [email protected]
+per-file settings.gradle = [email protected]
diff --git a/room/room-paging/api/current.txt b/room/room-paging/api/current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/api/public_plus_experimental_current.txt b/room/room-paging/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/public_plus_experimental_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/api/res-current.txt b/room/room-paging/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-paging/api/res-current.txt
diff --git a/room/room-paging/api/restricted_current.txt b/room/room-paging/api/restricted_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/restricted_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/build.gradle b/room/room-paging/build.gradle
new file mode 100644
index 0000000..e9645b8
--- /dev/null
+++ b/room/room-paging/build.gradle
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+import static androidx.build.dependencies.DependenciesKt.*
+import androidx.build.LibraryGroups
+import androidx.build.LibraryType
+import androidx.build.LibraryVersions
+import androidx.build.Publish
+
+plugins {
+ id("AndroidXPlugin")
+ id("com.android.library")
+ id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+ api(KOTLIN_STDLIB)
+ // Add dependencies here
+}
+
+androidx {
+ name = "Room Paging"
+ type = LibraryType.PUBLISHED_LIBRARY
+ mavenGroup = LibraryGroups.ROOM
+ inceptionYear = "2021"
+ description = "Room Paging integration"
+ publish = Publish.NONE
+}
diff --git a/room/room-paging/src/androidTest/AndroidManifest.xml b/room/room-paging/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..50ba2eb
--- /dev/null
+++ b/room/room-paging/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="androidx.room.paging.test">
+
+</manifest>
diff --git a/room/room-paging/src/main/AndroidManifest.xml b/room/room-paging/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..fa18cd8
--- /dev/null
+++ b/room/room-paging/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="androidx.room.paging">
+
+</manifest>
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index de23551..ba10801 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -529,6 +529,7 @@
includeProject(":room:room-guava", "room/guava", [BuildType.MAIN])
includeProject(":room:room-ktx", "room/ktx", [BuildType.MAIN])
includeProject(":room:room-migration", "room/migration", [BuildType.MAIN])
+includeProject(":room:room-paging", "room/room-paging", [BuildType.MAIN])
includeProject(":room:room-runtime", "room/runtime", [BuildType.MAIN])
includeProject(":room:room-rxjava2", "room/rxjava2", [BuildType.MAIN])
includeProject(":room:room-rxjava3", "room/rxjava3", [BuildType.MAIN])