Merge changes from topic "androidx-no-internet-2" into androidx-master-dev
* changes:
Disabling network in most builds
Support to depend on artifacts having no groupId
diff --git a/appcompat/appcompat/api/1.2.0-alpha01.txt b/appcompat/appcompat/api/1.2.0-alpha01.txt
index a19c8b1..330bca1 100644
--- a/appcompat/appcompat/api/1.2.0-alpha01.txt
+++ b/appcompat/appcompat/api/1.2.0-alpha01.txt
@@ -253,7 +253,8 @@
public abstract class AppCompatDelegate {
method public abstract void addContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
method public abstract boolean applyDayNight();
- method public void attachBaseContext(android.content.Context!);
+ method @Deprecated public void attachBaseContext(android.content.Context!);
+ method @CallSuper public android.content.Context attachBaseContext2(android.content.Context);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Dialog, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.view.Window, androidx.appcompat.app.AppCompatCallback?);
diff --git a/appcompat/appcompat/api/current.txt b/appcompat/appcompat/api/current.txt
index a19c8b1..330bca1 100644
--- a/appcompat/appcompat/api/current.txt
+++ b/appcompat/appcompat/api/current.txt
@@ -253,7 +253,8 @@
public abstract class AppCompatDelegate {
method public abstract void addContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
method public abstract boolean applyDayNight();
- method public void attachBaseContext(android.content.Context!);
+ method @Deprecated public void attachBaseContext(android.content.Context!);
+ method @CallSuper public android.content.Context attachBaseContext2(android.content.Context);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Dialog, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.view.Window, androidx.appcompat.app.AppCompatCallback?);
diff --git a/appcompat/appcompat/api/public_plus_experimental_1.2.0-alpha01.txt b/appcompat/appcompat/api/public_plus_experimental_1.2.0-alpha01.txt
index a19c8b1..330bca1 100644
--- a/appcompat/appcompat/api/public_plus_experimental_1.2.0-alpha01.txt
+++ b/appcompat/appcompat/api/public_plus_experimental_1.2.0-alpha01.txt
@@ -253,7 +253,8 @@
public abstract class AppCompatDelegate {
method public abstract void addContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
method public abstract boolean applyDayNight();
- method public void attachBaseContext(android.content.Context!);
+ method @Deprecated public void attachBaseContext(android.content.Context!);
+ method @CallSuper public android.content.Context attachBaseContext2(android.content.Context);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Dialog, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.view.Window, androidx.appcompat.app.AppCompatCallback?);
diff --git a/appcompat/appcompat/api/public_plus_experimental_current.txt b/appcompat/appcompat/api/public_plus_experimental_current.txt
index a19c8b1..330bca1 100644
--- a/appcompat/appcompat/api/public_plus_experimental_current.txt
+++ b/appcompat/appcompat/api/public_plus_experimental_current.txt
@@ -253,7 +253,8 @@
public abstract class AppCompatDelegate {
method public abstract void addContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
method public abstract boolean applyDayNight();
- method public void attachBaseContext(android.content.Context!);
+ method @Deprecated public void attachBaseContext(android.content.Context!);
+ method @CallSuper public android.content.Context attachBaseContext2(android.content.Context);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Dialog, androidx.appcompat.app.AppCompatCallback?);
method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.view.Window, androidx.appcompat.app.AppCompatCallback?);
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
index 5af7154..bd54923 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
@@ -69,8 +69,12 @@
@Test
fun testRotateDoesNotRecreateActivity() {
- // Don't run this test on SDK 26 because it has issues with setRequestedOrientation.
- if (Build.VERSION.SDK_INT == 26) {
+ // Don't run this test on SDK 26 because it has issues with setRequestedOrientation. Also
+ // don't run it on SDK 24 (Nexus Player) or SDK 23 (Pixel C) because those devices only
+ // support a single orientation and there doesn't seem to be a way to query supported
+ // screen orientations.
+ val sdkInt = Build.VERSION.SDK_INT
+ if (sdkInt == 26 || sdkInt == 24 || sdkInt == 23) {
return
}
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
index 2340c83..a85ba01 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
@@ -94,8 +94,7 @@
@Override
protected void attachBaseContext(Context newBase) {
- super.attachBaseContext(newBase);
- getDelegate().attachBaseContext(newBase);
+ super.attachBaseContext(getDelegate().attachBaseContext2(newBase));
}
@Override
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
index 61a1936..116dcbf 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
@@ -30,6 +30,7 @@
import android.view.ViewGroup;
import android.view.Window;
+import androidx.annotation.CallSuper;
import androidx.annotation.IdRes;
import androidx.annotation.IntDef;
import androidx.annotation.LayoutRes;
@@ -373,12 +374,23 @@
public abstract void addContentView(View v, ViewGroup.LayoutParams lp);
/**
- * Should be called from {@link Activity#attachBaseContext(Context)}
+ * @deprecated use {@link #attachBaseContext2(Context)} instead.
*/
+ @Deprecated
public void attachBaseContext(Context context) {
}
/**
+ * Should be called from {@link Activity#attachBaseContext(Context)}.
+ */
+ @NonNull
+ @CallSuper
+ public Context attachBaseContext2(@NonNull Context context) {
+ attachBaseContext(context);
+ return context;
+ }
+
+ /**
* Should be called from {@link Activity#onTitleChanged(CharSequence, int)}}
*/
public abstract void setTitle(@Nullable CharSequence title);
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index bfa0f2b..6d462f1 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -72,6 +72,7 @@
import android.widget.PopupWindow;
import android.widget.TextView;
+import androidx.annotation.CallSuper;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -136,18 +137,18 @@
private static final int[] sWindowBackgroundStyleable = {android.R.attr.windowBackground};
- private static boolean sInstalledExceptionHandler;
-
/**
- * AppCompat selectively uses applyOverrideConfiguration() for DayNight functionality.
- * Unfortunately the framework has a few bugs around Resources instances on SDKs 21-25,
+ * AppCompat selectively uses an override configuration for DayNight functionality.
+ * Unfortunately the framework has a few issues around Resources instances on SDKs 21-25,
* resulting in the root Resources instance (i.e. Application) being modified when it
- * shouldn't be. We can work around it by always calling applyOverrideConfiguration()
- * where available.
+ * shouldn't be. We can work around it by always calling using an override configuration
+ * where available, to force a local resources instance being used.
*/
private static final boolean sAlwaysOverrideConfiguration = Build.VERSION.SDK_INT >= 21
&& Build.VERSION.SDK_INT <= 25;
+ private static boolean sInstalledExceptionHandler;
+
static final String EXCEPTION_HANDLER_MESSAGE_SUFFIX= ". If the resource you are"
+ " trying to use is a vector resource, you may be referencing it in an unsupported"
+ " way. See AppCompatDelegate.setCompatVectorFromResourcesEnabled() for more info.";
@@ -330,11 +331,13 @@
AppCompatDrawableManager.preload();
}
+ @NonNull
@Override
- public void attachBaseContext(Context context) {
+ @CallSuper
+ public Context attachBaseContext2(@NonNull final Context baseContext) {
final Configuration appConfig =
- context.getApplicationContext().getResources().getConfiguration();
- final Configuration baseConfig = context.getResources().getConfiguration();
+ baseContext.getApplicationContext().getResources().getConfiguration();
+ final Configuration baseConfig = baseContext.getResources().getConfiguration();
final Configuration configOverlay;
if (!appConfig.equals(baseConfig)) {
configOverlay = generateConfigDelta(appConfig, baseConfig);
@@ -350,9 +353,27 @@
}
}
- // Activity.recreate() cannot be called before attach is complete.
- applyDayNight(false, configOverlay);
mBaseContextAttached = true;
+
+ if (Build.VERSION.SDK_INT >= 17) {
+ @ApplyableNightMode final int modeToApply = mapNightMode(baseContext,
+ calculateNightMode());
+ final Configuration config = createOverrideConfigurationForDayNight(
+ baseContext, modeToApply, configOverlay);
+
+ final int currentNightMode = baseContext.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK;
+ final int newNightMode = config.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+
+ if (sAlwaysOverrideConfiguration || currentNightMode != newNightMode) {
+ // If the target night mode is different to the new night mode, return a
+ // configuration context with the new config.
+ return super.attachBaseContext2(baseContext.createConfigurationContext(config));
+ }
+ }
+
+ // Otherwise just return the original base context
+ return super.attachBaseContext2(baseContext);
}
@Override
@@ -363,7 +384,7 @@
// Our implicit call to applyDayNight() should not recreate until after the Activity is
// created
- applyDayNight(false, null);
+ applyDayNight(false);
// We lazily fetch the Window for Activities, to allow DayNight to apply in
// attachBaseContext
@@ -518,7 +539,7 @@
// Re-apply Day/Night with the new configuration but disable recreations. Since this
// configuration change has only just happened we can safely just update the resources now
- applyDayNight(false, null);
+ applyDayNight(false);
}
@Override
@@ -2179,29 +2200,28 @@
@Override
public boolean applyDayNight() {
- return applyDayNight(true, null);
+ return applyDayNight(true);
}
@SuppressWarnings("deprecation")
- private boolean applyDayNight(final boolean allowRecreation,
- @Nullable Configuration configOverlay) {
+ private boolean applyDayNight(final boolean allowRecreation) {
if (mIsDestroyed) {
// If we're destroyed, ignore the call
return false;
}
@NightMode final int nightMode = calculateNightMode();
- @ApplyableNightMode final int modeToApply = mapNightMode(nightMode);
- final boolean applied = updateForNightMode(modeToApply, allowRecreation, configOverlay);
+ @ApplyableNightMode final int modeToApply = mapNightMode(mContext, nightMode);
+ final boolean applied = updateForNightMode(modeToApply, allowRecreation);
if (nightMode == MODE_NIGHT_AUTO_TIME) {
- getAutoTimeNightModeManager().setup();
+ getAutoTimeNightModeManager(mContext).setup();
} else if (mAutoTimeNightModeManager != null) {
// Make sure we clean up the existing manager
mAutoTimeNightModeManager.cleanup();
}
if (nightMode == MODE_NIGHT_AUTO_BATTERY) {
- getAutoBatteryNightModeManager().setup();
+ getAutoBatteryNightModeManager(mContext).setup();
} else if (mAutoBatteryNightModeManager != null) {
// Make sure we clean up the existing manager
mAutoBatteryNightModeManager.cleanup();
@@ -2225,7 +2245,7 @@
@SuppressWarnings("deprecation")
@ApplyableNightMode
- int mapNightMode(@NightMode final int mode) {
+ int mapNightMode(@NonNull Context context, @NightMode final int mode) {
switch (mode) {
case MODE_NIGHT_NO:
case MODE_NIGHT_YES:
@@ -2234,16 +2254,16 @@
return mode;
case MODE_NIGHT_AUTO_TIME:
if (Build.VERSION.SDK_INT >= 23) {
- UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
+ UiModeManager uiModeManager = context.getSystemService(UiModeManager.class);
if (uiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_AUTO) {
// If we're set to AUTO and the system's auto night mode is already enabled,
// we'll just let the system handle it by returning FOLLOW_SYSTEM
return MODE_NIGHT_FOLLOW_SYSTEM;
}
}
- return getAutoTimeNightModeManager().getApplyableNightMode();
+ return getAutoTimeNightModeManager(context).getApplyableNightMode();
case MODE_NIGHT_AUTO_BATTERY:
- return getAutoBatteryNightModeManager().getApplyableNightMode();
+ return getAutoBatteryNightModeManager(context).getApplyableNightMode();
case MODE_NIGHT_UNSPECIFIED:
// If we don't have a mode specified, let the system handle it
return MODE_NIGHT_FOLLOW_SYSTEM;
@@ -2258,23 +2278,10 @@
return mLocalNightMode != MODE_NIGHT_UNSPECIFIED ? mLocalNightMode : getDefaultNightMode();
}
- /**
- * Updates the {@link Resources} configuration {@code uiMode} with the
- * chosen {@code UI_MODE_NIGHT} value.
- *
- * @param mode The new night mode to apply
- * @param allowRecreation whether to attempt activity recreate
- * @param configOverlay the developer-provided configuration overlay to use, if any
- * @return true if an action has been taken (recreation, resources updating, etc)
- */
- private boolean updateForNightMode(@ApplyableNightMode final int mode,
- final boolean allowRecreation, @Nullable Configuration configOverlay) {
- boolean handled = false;
-
- final Configuration appConfig = mContext.getApplicationContext()
- .getResources().getConfiguration();
- final int applicationNightMode = appConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
+ @NonNull
+ private Configuration createOverrideConfigurationForDayNight(
+ @NonNull Context context, @ApplyableNightMode final int mode,
+ @Nullable Configuration configOverlay) {
int newNightMode;
switch (mode) {
case MODE_NIGHT_YES:
@@ -2287,64 +2294,56 @@
case MODE_NIGHT_FOLLOW_SYSTEM:
// If we're following the system, we just use the system default from the
// application context
- newNightMode = applicationNightMode;
+ final Configuration appConfig =
+ context.getApplicationContext().getResources().getConfiguration();
+ newNightMode = appConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
break;
}
- final boolean activityHandlingUiMode = isActivityManifestHandlingUiMode();
-
- if ((sAlwaysOverrideConfiguration || newNightMode != applicationNightMode)
- && !activityHandlingUiMode
- && Build.VERSION.SDK_INT >= 17
- && !mBaseContextAttached
- && mHost instanceof android.view.ContextThemeWrapper) {
- final android.view.ContextThemeWrapper host = (android.view.ContextThemeWrapper) mHost;
-
- // If we're here then we can try and apply an override configuration on the Context.
- final Configuration overrideConfig;
- if (configOverlay != null) {
- overrideConfig = new Configuration(configOverlay);
- } else {
- overrideConfig = new Configuration();
- overrideConfig.fontScale = 0;
- }
- overrideConfig.uiMode =
- newNightMode | (overrideConfig.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
-
- try {
- if (DEBUG) {
- Log.d(TAG, "updateForNightMode. Applying override config: " + overrideConfig);
- }
- host.applyOverrideConfiguration(overrideConfig);
- handled = true;
- } catch (IllegalStateException e) {
- // applyOverrideConfiguration throws an IllegalStateException if its resources
- // have already been created. Since there's no way to check this beforehand we
- // just have to try it and catch the exception. We only log if we're actually
- // trying to apply a uiMode configuration though.
- if (newNightMode != applicationNightMode) {
- Log.w(TAG, "updateForNightMode. Calling applyOverrideConfiguration() failed"
- + " with an exception. Will fall back to using"
- + " Resources.updateConfiguration()", e);
- }
- handled = false;
- }
+ // If we're here then we can try and apply an override configuration on the Context.
+ final Configuration overrideConf = new Configuration();
+ overrideConf.fontScale = 0;
+ if (configOverlay != null) {
+ overrideConf.setTo(configOverlay);
}
+ overrideConf.uiMode = newNightMode
+ | (overrideConf.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
+
+ return overrideConf;
+ }
+
+ /**
+ * Updates the {@link Resources} configuration {@code uiMode} with the
+ * chosen {@code UI_MODE_NIGHT} value.
+ *
+ * @param mode The new night mode to apply
+ * @param allowRecreation whether to attempt activity recreate
+ * @return true if an action has been taken (recreation, resources updating, etc)
+ */
+ private boolean updateForNightMode(@ApplyableNightMode final int mode,
+ final boolean allowRecreation) {
+ boolean handled = false;
+
+ final Configuration overrideConfig =
+ createOverrideConfigurationForDayNight(mContext, mode, null);
+
+ final boolean activityHandlingUiMode = isActivityManifestHandlingUiMode();
final int currentNightMode = mContext.getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
+ final int newNightMode = overrideConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
- if (!handled
- && currentNightMode != newNightMode
+ if (currentNightMode != newNightMode
&& allowRecreation
&& !activityHandlingUiMode
&& mBaseContextAttached
&& (Build.VERSION.SDK_INT >= 17 || mCreated)
&& mHost instanceof Activity) {
// If we're an attached Activity, we can recreate to apply
- // The SDK_INT check above is because applyOverrideConfiguration only exists on
- // API 17+, so we don't want to get into an loop of infinite recreations.
- // On < API 17 we need to use updateConfiguration before we're 'created'
+ // The SDK_INT check above is because createConfigurationContext(), called from
+ // attachBaseContext(), only exists on API 17+, so we don't want to get into an loop
+ // of infinite recreations.
+ // On < API 17 we need to use updateConfiguration() before we're 'created' (below)
if (DEBUG) {
Log.d(TAG, "updateForNightMode. Recreating Activity");
}
@@ -2357,8 +2356,7 @@
if (DEBUG) {
Log.d(TAG, "updateForNightMode. Updating resources config");
}
- updateResourcesConfigurationForNightMode(newNightMode, activityHandlingUiMode,
- configOverlay);
+ updateResourcesConfigurationForNightMode(newNightMode, activityHandlingUiMode, null);
handled = true;
}
@@ -2431,17 +2429,22 @@
*/
@NonNull
@RestrictTo(LIBRARY)
+ @VisibleForTesting
final AutoNightModeManager getAutoTimeNightModeManager() {
+ return getAutoTimeNightModeManager(mContext);
+ }
+
+ private AutoNightModeManager getAutoTimeNightModeManager(@NonNull Context context) {
if (mAutoTimeNightModeManager == null) {
mAutoTimeNightModeManager = new AutoTimeNightModeManager(
- TwilightManager.getInstance(mContext));
+ TwilightManager.getInstance(context));
}
return mAutoTimeNightModeManager;
}
- private AutoNightModeManager getAutoBatteryNightModeManager() {
+ private AutoNightModeManager getAutoBatteryNightModeManager(@NonNull Context context) {
if (mAutoBatteryNightModeManager == null) {
- mAutoBatteryNightModeManager = new AutoBatteryNightModeManager(mContext);
+ mAutoBatteryNightModeManager = new AutoBatteryNightModeManager(context);
}
return mAutoBatteryNightModeManager;
}
diff --git a/arch/core-common/build.gradle b/arch/core-common/build.gradle
index 3c5f2fd..77324ae 100644
--- a/arch/core-common/build.gradle
+++ b/arch/core-common/build.gradle
@@ -26,10 +26,10 @@
}
dependencies {
- compile("androidx.annotation:annotation:1.1.0")
+ api("androidx.annotation:annotation:1.1.0")
- testCompile(JUNIT)
- testCompile(MOCKITO_CORE)
+ testImplementation(JUNIT)
+ testImplementation(MOCKITO_CORE)
}
sourceCompatibility = JavaVersion.VERSION_1_7
diff --git a/buildSrc/build_dependencies.gradle b/buildSrc/build_dependencies.gradle
index 2503895..28e2999 100644
--- a/buildSrc/build_dependencies.gradle
+++ b/buildSrc/build_dependencies.gradle
@@ -29,7 +29,7 @@
build_versions.lint = '26.6.0-beta04'
}
-build_versions.dokka = '0.9.17-g002'
+build_versions.dokka = '0.9.17-g004'
rootProject.ext['build_versions'] = build_versions
diff --git a/buildSrc/repos.gradle b/buildSrc/repos.gradle
index 54d76bd..06dc65b 100644
--- a/buildSrc/repos.gradle
+++ b/buildSrc/repos.gradle
@@ -27,8 +27,7 @@
ext.repos.prebuiltsRoot = "${checkoutRoot}/prebuilts"
ext.repoNames = ["${repos.prebuiltsRoot}/androidx/internal",
- "${repos.prebuiltsRoot}/androidx/external",
- "${checkoutRoot}/external/dokka/maven",]
+ "${repos.prebuiltsRoot}/androidx/external"]
/**
* Adds maven repositories to the given repository handler.
diff --git a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
index 9b3fdc4..408b48b 100644
--- a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
@@ -175,7 +175,7 @@
val reportLibraryMetrics = project.tasks.register(
REPORT_LIBRARY_METRICS, ReportLibraryMetricsTask::class.java
)
-
+ project.addToBuildOnServer(reportLibraryMetrics)
extension.defaultPublishVariant { libraryVariant ->
reportLibraryMetrics.configure {
it.jarFiles.from(libraryVariant.packageLibraryProvider.map { zip ->
@@ -258,20 +258,20 @@
if (isRunningOnBuildServer()) {
gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
}
- val createAggregateBuildInfoFilesTask =
- tasks.register(CREATE_AGGREGATE_BUILD_INFO_FILES_TASK,
- CreateAggregateLibraryBuildInfoFileTask::class.java)
- val createLibraryBuildInfoFilesTask =
+ val buildOnServerTask = tasks.create(BUILD_ON_SERVER_TASK, BuildOnServer::class.java)
+ buildOnServerTask.dependsOn(
+ tasks.register(
+ CREATE_AGGREGATE_BUILD_INFO_FILES_TASK,
+ CreateAggregateLibraryBuildInfoFileTask::class.java
+ )
+ )
+ buildOnServerTask.dependsOn(
tasks.register(CREATE_LIBRARY_BUILD_INFO_FILES_TASK)
+ )
extra.set("versionChecker", GMavenVersionChecker(logger))
val createArchiveTask = Release.getGlobalFullZipTask(this)
-
- val buildOnServerTask = tasks.create(BUILD_ON_SERVER_TASK, BuildOnServer::class.java)
buildOnServerTask.dependsOn(createArchiveTask)
- buildOnServerTask.dependsOn(createAggregateBuildInfoFilesTask)
- buildOnServerTask.dependsOn(createLibraryBuildInfoFilesTask)
-
val partiallyDejetifyArchiveTask = partiallyDejetifyArchiveTask(
createArchiveTask.get().archiveFile)
if (partiallyDejetifyArchiveTask != null)
@@ -299,9 +299,6 @@
buildOnServerTask.dependsOn("${project.path}:lintDebug")
}
}
- project.plugins.withType(LibraryPlugin::class.java) {
- buildOnServerTask.dependsOn("${project.path}:reportLibraryMetrics")
- }
project.plugins.withType(JavaPlugin::class.java) {
buildOnServerTask.dependsOn("${project.path}:jar")
}
@@ -319,27 +316,22 @@
}
val createCoverageJarTask = Jacoco.createCoverageJarTask(this)
- buildOnServerTask.dependsOn(createCoverageJarTask)
-
- val createZipEcFilesTask = Jacoco.createZipEcFilesTask(this)
- buildOnServerTask.dependsOn(createZipEcFilesTask)
-
tasks.register(BUILD_TEST_APKS) {
it.dependsOn(createCoverageJarTask)
}
+ buildOnServerTask.dependsOn(createCoverageJarTask)
+ buildOnServerTask.dependsOn(Jacoco.createZipEcFilesTask(this))
val rootProjectDir = SupportConfig.getSupportRoot(rootProject).canonicalFile
val allDocsTask = DiffAndDocs.configureDiffAndDocs(this, rootProjectDir,
DacOptions("androidx", "ANDROIDX_DATA"),
listOf(RELEASE_RULE))
buildOnServerTask.dependsOn(allDocsTask)
-
- val jacocoUberJar = Jacoco.createUberJarTask(this)
- buildOnServerTask.dependsOn(jacocoUberJar)
- val checkSameVersionLibraryGroupsTask = tasks.register(
+ buildOnServerTask.dependsOn(Jacoco.createUberJarTask(this))
+ buildOnServerTask.dependsOn(tasks.register(
CHECK_SAME_VERSION_LIBRARY_GROUPS,
CheckSameVersionLibraryGroupsTask::class.java)
- buildOnServerTask.dependsOn(checkSameVersionLibraryGroupsTask)
+ )
AffectedModuleDetector.configure(gradle, this)
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index ec7ed31..db61c15 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -59,7 +59,7 @@
val DYNAMICANIMATION_KTX = Version("1.0.0-alpha03")
val EMOJI = Version("1.1.0-alpha01")
val ENTERPRISE = Version("1.1.0-alpha01")
- val EXIFINTERFACE = Version("1.2.0-alpha01")
+ val EXIFINTERFACE = Version("1.2.0-beta01")
val FRAGMENT = Version("1.3.0-alpha01")
val FUTURES = Version("1.1.0-alpha01")
val GRIDLAYOUT = Version("1.1.0-alpha01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt b/buildSrc/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt
index c4c9cc7..772f6f4 100644
--- a/buildSrc/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt
@@ -19,6 +19,7 @@
import org.gradle.api.DefaultTask
import org.gradle.api.Task
import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import java.io.File
@@ -29,7 +30,9 @@
abstract class ListTaskOutputsTask() : DefaultTask() {
@OutputFile
val outputFile: Property<File> = project.objects.property(File::class.java)
+ @Input
val removePrefixes: MutableList<String> = mutableListOf()
+ @Input
val tasks: MutableList<Task> = mutableListOf()
init {
diff --git a/buildSrc/src/main/kotlin/androidx/build/MavenUploadHelper.kt b/buildSrc/src/main/kotlin/androidx/build/MavenUploadHelper.kt
index 427c11a..7218e30 100644
--- a/buildSrc/src/main/kotlin/androidx/build/MavenUploadHelper.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/MavenUploadHelper.kt
@@ -28,6 +28,7 @@
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPom
import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.api.publish.tasks.GenerateModuleMetadata
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.create
import java.io.File
@@ -49,6 +50,9 @@
if (extension.publish.shouldPublish() && component.isAndroidOrJavaReleaseComponent()) {
val androidxGroup = validateCoordinatesAndGetGroup(extension)
group = androidxGroup
+ tasks.withType(GenerateModuleMetadata::class.java) {
+ it.enabled = false
+ }
configure<PublishingExtension> {
repositories {
it.maven { repo ->
diff --git a/buildSrc/src/main/kotlin/androidx/build/TaskUpToDateValidator.kt b/buildSrc/src/main/kotlin/androidx/build/TaskUpToDateValidator.kt
index cfb72ca..3624a89 100644
--- a/buildSrc/src/main/kotlin/androidx/build/TaskUpToDateValidator.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/TaskUpToDateValidator.kt
@@ -78,6 +78,7 @@
"partiallyDejetifyArchive",
"postInstrumentCode",
"publishBenchmarkPluginMarkerMavenPublicationToMavenRepository",
+ "publishKotlinMultiplatformPublicationToMavenRepository",
"publishMavenPublicationToMavenRepository",
"publishMetadataPublicationToMavenRepository",
"publishPluginMavenPublicationToMavenRepository",
@@ -88,7 +89,8 @@
"transformClassesWithDexBuilderForPublicDebug",
"transformClassesWithDexBuilderForTipOfTreeDebug",
"unzipDokkaPublicDocsDeps",
- "verifyDependencyVersions"
+ "verifyDependencyVersions",
+ "zipEcFiles"
)
class TaskUpToDateValidator {
companion object {
diff --git a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
index 7a0b5e1..15f20b3 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
@@ -33,6 +33,7 @@
const val APACHE_COMMONS_CODEC = "commons-codec:commons-codec:1.10"
const val CHECKER_FRAMEWORK = "org.checkerframework:checker-qual:2.5.3"
const val CONSTRAINT_LAYOUT = "androidx.constraintlayout:constraintlayout:1.1.0@aar"
+const val CONSTRAINT_LAYOUT_SOLVER = "androidx.constraintlayout:constraintlayout-solver:2.0.0-beta3"
const val DEXMAKER_MOCKITO = "com.linkedin.dexmaker:dexmaker-mockito:2.25.0"
const val ESPRESSO_CONTRIB = "androidx.test.espresso:espresso-contrib:3.1.0"
const val ESPRESSO_CORE = "androidx.test.espresso:espresso-core:3.1.0"
diff --git a/buildSrc/src/main/kotlin/androidx/build/doclava/DoclavaTask.kt b/buildSrc/src/main/kotlin/androidx/build/doclava/DoclavaTask.kt
index ada5665..4adf272 100644
--- a/buildSrc/src/main/kotlin/androidx/build/doclava/DoclavaTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/doclava/DoclavaTask.kt
@@ -23,6 +23,7 @@
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.external.javadoc.CoreJavadocOptions
+import org.gradle.external.javadoc.StandardJavadocDocletOptions
import java.io.File
// external/doclava/src/com/google/doclava/Errors.java
@@ -145,7 +146,7 @@
* "Configures" this DoclavaTask with parameters that might not be at their final values
* until this task is run.
*/
- private fun configureDoclava() = (options as CoreJavadocOptions).apply {
+ private fun configureDoclava() = (options as StandardJavadocDocletOptions).apply {
docletpath = this@DoclavaTask.docletpath
@@ -181,6 +182,9 @@
}
// Always treat this as an Android docs task.
addBooleanOption("android", true)
+
+ // Doclava does not understand -notimestamp option that is default since Gradle 6.0
+ isNoTimestamp = false
}
fun coreJavadocOptions(configure: CoreJavadocOptions.() -> Unit) =
diff --git a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
index de986d5..b5e4eae 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
@@ -27,6 +27,8 @@
import org.gradle.api.Project
import org.gradle.api.artifacts.ResolveException
import org.gradle.api.tasks.Copy
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskCollection
import org.gradle.api.tasks.TaskContainer
@@ -41,6 +43,7 @@
private const val UNZIP_DEPS_TASK_NAME = "unzipDokkaPublicDocsDeps"
val hiddenPackages = listOf(
+ "androidx.animation.samples",
"androidx.camera.camera2.impl",
"androidx.camera.camera2.impl.compat",
"androidx.camera.camera2.impl.compat.params",
@@ -49,8 +52,16 @@
"androidx.camera.core.impl.utils.executor",
"androidx.camera.core.impl.utils.futures",
"androidx.camera.core.impl.utils.futures.internal",
+ "androidx.compose.samples",
"androidx.core.internal",
"androidx.preference.internal",
+ "androidx.ui.animation.samples",
+ "androidx.ui.core.samples",
+ "androidx.ui.foundation.samples",
+ "androidx.ui.framework.samples",
+ "androidx.ui.layout.samples",
+ "androidx.ui.material.samples",
+ "androidx.ui.text.samples",
"androidx.wear.internal.widget.drawer",
"androidx.webkit.internal",
"androidx.work.impl",
@@ -64,13 +75,6 @@
"androidx.work.impl.utils",
"androidx.work.impl.utils.futures",
"androidx.work.impl.utils.taskexecutor",
- "androidx.compose.samples",
- "androidx.ui.animation.samples",
- "androidx.ui.foundation.samples",
- "androidx.ui.framework.samples",
- "androidx.ui.layout.samples",
- "androidx.ui.material.samples",
- "androidx.ui.text.samples",
"sample",
"sample.foo")
@@ -215,14 +219,22 @@
// TODO(b/143243490): can this be made to run more quickly, cleanly and clearly via some other
// approach, such as maybe with an ArtifactTransform?
open class LocateJarsTask : DefaultTask() {
+ init {
+ // This task does not correctly model inputs and outputs.
+ // Mark it to be never up to date
+ outputs.upToDateWhen { false }
+ }
+
// dependencies to search for .jar files
+ @get:Input
val inputDependencies = mutableListOf<String>()
// .jar files found in any dependencies
+ @get:OutputFiles
val outputJars = mutableListOf<File>()
@TaskAction
- fun Extract() {
+ fun extract() {
// setup
val inputDependencies = checkNotNull(inputDependencies) { "inputDependencies not set" }
val project = this.project
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt
index 7c8a6528..d329caa 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt
@@ -23,10 +23,14 @@
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction
+import org.gradle.workers.WorkerExecutor
import java.io.File
+import javax.inject.Inject
// Validate that the API described in one signature txt file is compatible with the API in another
-abstract class CheckApiCompatibilityTask : MetalavaTask() {
+abstract class CheckApiCompatibilityTask @Inject constructor(
+ workerExecutor: WorkerExecutor
+) : MetalavaTask(workerExecutor) {
// Text file from which the API signatures will be obtained.
@get:Input
abstract val referenceApi: Property<ApiLocation>
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt
index 3a2661a..c73f597 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt
@@ -19,9 +19,13 @@
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
+import org.gradle.workers.WorkerExecutor
import java.io.File
+import javax.inject.Inject
-abstract class GenerateApiStubClassesTask : MetalavaTask() {
+abstract class GenerateApiStubClassesTask @Inject constructor(
+ workerExecutor: WorkerExecutor
+) : MetalavaTask(workerExecutor) {
@get:OutputDirectory
abstract val apiStubsDirectory: DirectoryProperty
@@ -49,4 +53,4 @@
)
)
}
-}
\ No newline at end of file
+}
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
index 4276984..9991331 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
@@ -25,10 +25,14 @@
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction
+import org.gradle.workers.WorkerExecutor
import java.io.File
+import javax.inject.Inject
/** Generate an API signature text file from a set of source files. */
-abstract class GenerateApiTask : MetalavaTask() {
+abstract class GenerateApiTask @Inject constructor(
+ workerExecutor: WorkerExecutor
+) : MetalavaTask(workerExecutor) {
/** Text file to which API signatures will be written. */
@get:Input
abstract val apiLocation: Property<ApiLocation>
@@ -71,7 +75,8 @@
apiLocation.get(),
apiLocation.get().publicApiFile.parentFile,
ApiLintMode.CheckBaseline(baselines.get().apiLintFile),
- generateRestrictedAPIs
+ generateRestrictedAPIs,
+ workerExecutor
)
}
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
index f02bf3e..2440471 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
@@ -22,10 +22,56 @@
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.Property
+import org.gradle.process.ExecOperations
+import org.gradle.workers.WorkAction
+import org.gradle.workers.WorkerExecutor
+import org.gradle.workers.WorkParameters
import java.io.File
+import javax.inject.Inject
// MetalavaRunner stores common configuration for executing Metalava
+fun runMetalavaWithArgs(metalavaJar: File, args: List<String>, workerExecutor: WorkerExecutor) {
+ val allArgs = listOf(
+ "--no-banner",
+ "--hide",
+ "HiddenSuperclass" // We allow having a hidden parent class
+ ) + args
+
+ val workQueue = workerExecutor.noIsolation()
+ workQueue.submit(MetalavaWorkAction::class.java) { parameters ->
+ parameters.getArgs().set(allArgs)
+ parameters.getMetalavaJar().set(metalavaJar)
+ }
+}
+
+interface MetalavaParams : WorkParameters {
+ fun getArgs(): ListProperty<String>
+ fun getMetalavaJar(): Property<File>
+}
+
+abstract class MetalavaWorkAction @Inject constructor (
+ private val execOperations: ExecOperations
+) : WorkAction<MetalavaParams> {
+
+ override fun execute() {
+ val allArgs = getParameters().getArgs().get()
+ val metalavaJar = getParameters().getMetalavaJar().get()
+
+ execOperations.javaexec {
+ it.classpath(metalavaJar)
+ it.main = "com.android.tools.metalava.Driver"
+ it.args = allArgs
+ }
+ }
+}
+
+fun Project.getMetalavaJar(): File {
+ return getMetalavaConfiguration().resolvedConfiguration.files.iterator().next()
+}
+
fun Project.getMetalavaConfiguration(): Configuration {
return configurations.findByName("metalava") ?: configurations.create("metalava") {
val dependency = dependencies.create("com.android:metalava:1.3.0:shadow@jar")
@@ -33,18 +79,6 @@
}
}
-fun Project.runMetalavaWithArgs(configuration: Configuration, args: List<String>) {
- javaexec {
- it.classpath = checkNotNull(configuration) { "Configuration not set." }
- it.main = "com.android.tools.metalava.Driver"
- it.args = listOf(
- "--no-banner",
- "--hide",
- "HiddenSuperclass" // We allow having a hidden parent class
- ) + args
- }
-}
-
// Metalava arguments to hide all experimental API surfaces.
val HIDE_EXPERIMENTAL_ARGS: List<String> = listOf(
"--hide-annotation", "androidx.annotation.experimental.Experimental",
@@ -122,15 +156,18 @@
apiLocation: ApiLocation,
tempDir: File,
apiLintMode: ApiLintMode,
- includeRestrictedApis: Boolean
+ includeRestrictedApis: Boolean,
+ workerExecutor: WorkerExecutor
) {
generateApi(files.bootClasspath, files.dependencyClasspath, files.sourcePaths.files,
- apiLocation.publicApiFile, tempDir, GenerateApiMode.PublicApi, apiLintMode)
+ apiLocation.publicApiFile, tempDir, GenerateApiMode.PublicApi, apiLintMode, workerExecutor)
generateApi(files.bootClasspath, files.dependencyClasspath, files.sourcePaths.files,
- apiLocation.experimentalApiFile, tempDir, GenerateApiMode.ExperimentalApi, apiLintMode)
+ apiLocation.experimentalApiFile, tempDir, GenerateApiMode.ExperimentalApi, apiLintMode,
+ workerExecutor)
if (includeRestrictedApis) {
generateApi(files.bootClasspath, files.dependencyClasspath, files.sourcePaths.files,
- apiLocation.restrictedApiFile, tempDir, GenerateApiMode.RestrictedApi, ApiLintMode.Skip)
+ apiLocation.restrictedApiFile, tempDir, GenerateApiMode.RestrictedApi, ApiLintMode.Skip,
+ workerExecutor)
}
}
@@ -142,7 +179,8 @@
outputFile: File,
tempDir: File,
generateApiMode: GenerateApiMode,
- apiLintMode: ApiLintMode
+ apiLintMode: ApiLintMode,
+ workerExecutor: WorkerExecutor
) {
val tempOutputFile = if (generateApiMode is GenerateApiMode.RestrictedApi) {
File(tempDir, outputFile.name + ".tmp")
@@ -209,11 +247,13 @@
}
}
- val metalavaConfiguration = getMetalavaConfiguration()
- runMetalavaWithArgs(metalavaConfiguration, args)
-
if (generateApiMode is GenerateApiMode.RestrictedApi) {
+ runMetalavaWithArgs(getMetalavaJar(), args, workerExecutor)
+ // TODO(119617147): when we no longer need to fix Metalava's output, remove this "await"
+ workerExecutor.await()
removeRestrictToLibraryLines(tempOutputFile, outputFile)
+ } else {
+ runMetalavaWithArgs(getMetalavaJar(), args, workerExecutor)
}
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
index 78480c81..b0d8932 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
@@ -22,9 +22,16 @@
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.Internal
+import org.gradle.workers.WorkerExecutor
+import javax.inject.Inject
/** Base class for invoking Metalava. */
-abstract class MetalavaTask : DefaultTask() {
+abstract class MetalavaTask @Inject constructor(
+ @Internal
+ protected val workerExecutor: WorkerExecutor
+) : DefaultTask() {
+
/** Configuration containing Metalava and its dependencies. */
@get:Classpath
@get:InputFiles
@@ -42,7 +49,7 @@
@get:InputFiles
var sourcePaths: Collection<File> = emptyList()
- protected fun runWithArgs(args: List<String>) {
- project.runMetalavaWithArgs(configuration, args)
+ fun runWithArgs(args: List<String>) {
+ runMetalavaWithArgs(project.getMetalavaJar(), args, workerExecutor)
}
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
index 40bba3c..b02956c 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
@@ -27,10 +27,14 @@
import org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.util.PatternFilterable
+import org.gradle.workers.WorkerExecutor
import java.io.File
+import javax.inject.Inject
/** Generate API signature text files using previously built .jar/.aar artifacts. */
-abstract class RegenerateOldApisTask : DefaultTask() {
+abstract class RegenerateOldApisTask @Inject constructor(
+ private val workerExecutor: WorkerExecutor
+) : DefaultTask() {
@TaskAction
fun exec() {
val groupId = project.group.toString()
@@ -84,7 +88,8 @@
project.logger.lifecycle("Regenerating $mavenId")
val generateRestrictedAPIs = outputApiLocation.restrictedApiFile.exists()
project.generateApi(
- inputs, outputApiLocation, tempDir, ApiLintMode.Skip, generateRestrictedAPIs)
+ inputs, outputApiLocation, tempDir, ApiLintMode.Skip, generateRestrictedAPIs,
+ workerExecutor)
}
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
index 1eca2fa..77fe582 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
@@ -25,9 +25,13 @@
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction
+import org.gradle.workers.WorkerExecutor
import java.io.File
+import javax.inject.Inject
-abstract class UpdateApiLintBaselineTask : MetalavaTask() {
+abstract class UpdateApiLintBaselineTask @Inject constructor(
+ workerExecutor: WorkerExecutor
+) : MetalavaTask(workerExecutor) {
init {
group = "API"
description = "Updates an API lint baseline file (api/api_lint.ignore) to match the " +
@@ -60,7 +64,9 @@
}
}
-abstract class IgnoreApiChangesTask : MetalavaTask() {
+abstract class IgnoreApiChangesTask @Inject constructor(
+ workerExecutor: WorkerExecutor
+) : MetalavaTask(workerExecutor) {
init {
description = "Updates an API tracking baseline file (api/X.Y.Z.ignore) to match the " +
"current set of violations"
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageAnalysisTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageAnalysisTest.java
index 3cb85ac..9fe69e6 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageAnalysisTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageAnalysisTest.java
@@ -38,7 +38,6 @@
import androidx.camera.core.ImageAnalysis.BackpressureStrategy;
import androidx.camera.core.ImageAnalysisConfig;
import androidx.camera.core.ImageProxy;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.UseCase.StateChangeCallback;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.testing.CameraUtil;
@@ -107,7 +106,8 @@
mHandlerThread = new HandlerThread("AnalysisThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
- mCameraSelector = new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ mCameraSelector = new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
mLifecycleOwner = new FakeLifecycleOwner();
}
@@ -154,13 +154,13 @@
@Test
public void analyzesImages_withKEEP_ONLY_LATEST_whenCameraIsOpen()
throws InterruptedException {
- analyzerAnalyzesImagesWithStrategy(BackpressureStrategy.KEEP_ONLY_LATEST);
+ analyzerAnalyzesImagesWithStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST);
}
@Test
public void analyzesImages_withBLOCK_PRODUCER_whenCameraIsOpen()
throws InterruptedException {
- analyzerAnalyzesImagesWithStrategy(BackpressureStrategy.BLOCK_PRODUCER);
+ analyzerAnalyzesImagesWithStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER);
}
private void analyzerAnalyzesImagesWithStrategy(@BackpressureStrategy int backpressureStrategy)
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java
index 4d057f6..3e0e96b 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/ImageCaptureTest.java
@@ -61,14 +61,11 @@
import androidx.camera.core.CaptureStage;
import androidx.camera.core.Exif;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.ImageCapture.CaptureMode;
-import androidx.camera.core.ImageCapture.ImageCaptureError;
import androidx.camera.core.ImageCapture.Metadata;
import androidx.camera.core.ImageCapture.OnImageCapturedCallback;
import androidx.camera.core.ImageCapture.OnImageSavedCallback;
import androidx.camera.core.ImageCaptureConfig;
import androidx.camera.core.ImageProxy;
-import androidx.camera.core.LensFacing;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.fakes.FakeCameraControl;
import androidx.camera.testing.fakes.FakeCaptureStage;
@@ -112,8 +109,8 @@
private static final Size DEFAULT_RESOLUTION = new Size(640, 480);
private static final Size GUARANTEED_RESOLUTION = new Size(640, 480);
- @LensFacing
- private static final int BACK_LENS_FACING = LensFacing.BACK;
+ @CameraSelector.LensFacing
+ private static final int BACK_LENS_FACING = CameraSelector.LENS_FACING_BACK;
private static final CameraSelector BACK_SELECTOR =
new CameraSelector.Builder().requireLensFacing(BACK_LENS_FACING).build();
@@ -249,7 +246,7 @@
@Test
public void canCaptureMultipleImagesWithMaxQuality() {
ImageCapture useCase = new ImageCapture.Builder()
- .setCaptureMode(CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.build();
mInstrumentation.runOnMainSync(
() -> {
@@ -432,7 +429,7 @@
// Wait for the signal that the image has been saved.
verify(callback, timeout(2000))
- .onError(eq(ImageCaptureError.FILE_IO_ERROR), anyString(), any(Throwable.class));
+ .onError(eq(ImageCapture.ERROR_FILE_IO), anyString(), any(Throwable.class));
}
@Test
@@ -605,7 +602,7 @@
verify(callback, timeout(500).times(1)).onError(errorCaptor.capture(),
any(String.class),
any(Throwable.class));
- assertThat(errorCaptor.getValue()).isEqualTo(ImageCaptureError.CAMERA_CLOSED);
+ assertThat(errorCaptor.getValue()).isEqualTo(ImageCapture.ERROR_CAMERA_CLOSED);
}
@Test
@@ -634,7 +631,7 @@
verify(callback, timeout(500).times(1)).onError(errorCaptor.capture(),
any(String.class),
any(Throwable.class));
- assertThat(errorCaptor.getValue()).isEqualTo(ImageCaptureError.CAPTURE_FAILED);
+ assertThat(errorCaptor.getValue()).isEqualTo(ImageCapture.ERROR_CAPTURE_FAILED);
}
@Test
@@ -661,9 +658,9 @@
any(String.class),
any(Throwable.class));
assertThat(errorCaptor.getAllValues()).containsExactly(
- ImageCaptureError.CAMERA_CLOSED,
- ImageCaptureError.CAMERA_CLOSED,
- ImageCaptureError.CAMERA_CLOSED);
+ ImageCapture.ERROR_CAMERA_CLOSED,
+ ImageCapture.ERROR_CAMERA_CLOSED,
+ ImageCapture.ERROR_CAMERA_CLOSED);
}
@Test
@@ -676,7 +673,7 @@
ArgumentCaptor<Integer> errorCaptor = ArgumentCaptor.forClass(Integer.class);
verify(callback, timeout(500)).onError(errorCaptor.capture(), any(String.class),
any(Throwable.class));
- assertThat(errorCaptor.getValue()).isEqualTo(ImageCaptureError.INVALID_CAMERA);
+ assertThat(errorCaptor.getValue()).isEqualTo(ImageCapture.ERROR_INVALID_CAMERA);
}
private static final class ImageProperties {
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
index 3092e16..5904e3d0 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
@@ -36,7 +36,6 @@
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.CaptureConfig;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.SessionConfig;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
@@ -110,18 +109,20 @@
CameraFactory cameraFactory = Preconditions.checkNotNull(cameraXConfig.getCameraFactory(
/*valueIfMissing=*/ null));
try {
- mCameraId = cameraFactory.cameraIdForLensFacing(LensFacing.BACK);
+ mCameraId = cameraFactory.cameraIdForLensFacing(CameraSelector.LENS_FACING_BACK);
} catch (Exception e) {
throw new IllegalArgumentException(
- "Unable to attach to camera with LensFacing " + LensFacing.BACK, e);
+ "Unable to attach to camera with LensFacing " + CameraSelector.LENS_FACING_BACK,
+ e);
}
// init CameraX before creating Preview to get preview size with CameraX's context
mDefaultBuilder = Preview.Builder.fromConfig(
- Preview.DEFAULT_CONFIG.getConfig(LensFacing.BACK));
+ Preview.DEFAULT_CONFIG.getConfig(CameraSelector.LENS_FACING_BACK));
mSurfaceFutureSemaphore = new Semaphore(/*permits=*/ 0);
mSaveToReleaseSemaphore = new Semaphore(/*permits=*/ 0);
- mCameraSelector = new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ mCameraSelector = new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
mLifecycleOwner = new FakeLifecycleOwner();
}
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/SurfaceOrientedMeteringPointFactoryTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/SurfaceOrientedMeteringPointFactoryTest.java
index 63c7e7a..ca85c1b 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/SurfaceOrientedMeteringPointFactoryTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/SurfaceOrientedMeteringPointFactoryTest.java
@@ -29,7 +29,6 @@
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ImageAnalysis;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.MeteringPoint;
import androidx.camera.core.MeteringPointFactory;
import androidx.camera.core.SurfaceOrientedMeteringPointFactory;
@@ -112,14 +111,15 @@
@Test
public void createPointWithFoVUseCase_success() {
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.BACK));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK));
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.setTargetName("ImageAnalysis")
.build();
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
@@ -135,7 +135,7 @@
@Test(expected = IllegalStateException.class)
public void createPointWithFoVUseCase_FailedNotBound() {
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.BACK));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK));
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java
index 4f5e7ea..396efda 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java
@@ -34,7 +34,6 @@
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.testing.CameraUtil;
@@ -66,7 +65,7 @@
@RunWith(AndroidJUnit4.class)
public final class UseCaseCombinationTest {
private static final CameraSelector DEFAULT_SELECTOR =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
private final MutableLiveData<Long> mAnalysisResult = new MutableLiveData<>();
@Rule
public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/VideoCaptureTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/VideoCaptureTest.java
index f0a93a5..3a4adda 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/VideoCaptureTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/VideoCaptureTest.java
@@ -30,7 +30,6 @@
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.UseCase;
import androidx.camera.core.UseCase.StateChangeCallback;
import androidx.camera.core.VideoCapture;
@@ -101,7 +100,8 @@
CameraFactory cameraFactory = cameraXConfig.getCameraFactory(/*valueIfMissing=*/ null);
CameraX.initialize(context, cameraXConfig);
mLifecycleOwner = new FakeLifecycleOwner();
- mCameraSelector = new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ mCameraSelector = new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
}
@After
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java
index 40dbcb54d..a936757 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraControlTest.java
@@ -54,11 +54,10 @@
import androidx.camera.core.CameraControl;
import androidx.camera.core.CameraControlInternal;
import androidx.camera.core.CameraInfoUnavailableException;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CaptureConfig;
-import androidx.camera.core.FlashMode;
import androidx.camera.core.FocusMeteringAction;
-import androidx.camera.core.FocusMeteringAction.MeteringMode;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.ImageCapture;
import androidx.camera.core.SessionConfig;
import androidx.camera.core.SurfaceOrientedMeteringPointFactory;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
@@ -102,14 +101,14 @@
@Before
public void setUp() throws InterruptedException, CameraAccessException,
CameraInfoUnavailableException {
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.BACK));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK));
Context context = ApplicationProvider.getApplicationContext();
CameraManager cameraManager = (CameraManager) context.getSystemService(
Context.CAMERA_SERVICE);
Camera2CameraFactory camera2CameraFactory = new Camera2CameraFactory(context);
mCameraCharacteristics = cameraManager.getCameraCharacteristics(
- camera2CameraFactory.cameraIdForLensFacing(LensFacing.BACK));
+ camera2CameraFactory.cameraIdForLensFacing(CameraSelector.LENS_FACING_BACK));
Boolean hasFlashUnit =
mCameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
mHasFlashUnit = hasFlashUnit != null && hasFlashUnit.booleanValue();
@@ -177,7 +176,7 @@
@Test
public void setFlashModeAuto_aeModeSetAndRequestUpdated() throws InterruptedException {
- mCamera2CameraControl.setFlashMode(FlashMode.AUTO);
+ mCamera2CameraControl.setFlashMode(ImageCapture.FLASH_MODE_AUTO);
HandlerUtil.waitForLooperToIdle(mHandler);
@@ -188,12 +187,12 @@
sessionConfig.getImplementationOptions());
assertAeMode(camera2Config, CONTROL_AE_MODE_ON_AUTO_FLASH);
- assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(FlashMode.AUTO);
+ assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(ImageCapture.FLASH_MODE_AUTO);
}
@Test
public void setFlashModeOff_aeModeSetAndRequestUpdated() throws InterruptedException {
- mCamera2CameraControl.setFlashMode(FlashMode.OFF);
+ mCamera2CameraControl.setFlashMode(ImageCapture.FLASH_MODE_OFF);
HandlerUtil.waitForLooperToIdle(mHandler);
@@ -205,12 +204,12 @@
assertAeMode(camera2Config, CONTROL_AE_MODE_ON);
- assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(FlashMode.OFF);
+ assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(ImageCapture.FLASH_MODE_OFF);
}
@Test
public void setFlashModeOn_aeModeSetAndRequestUpdated() throws InterruptedException {
- mCamera2CameraControl.setFlashMode(FlashMode.ON);
+ mCamera2CameraControl.setFlashMode(ImageCapture.FLASH_MODE_ON);
HandlerUtil.waitForLooperToIdle(mHandler);
@@ -222,7 +221,7 @@
assertAeMode(camera2Config, CONTROL_AE_MODE_ON_ALWAYS_FLASH);
- assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(FlashMode.ON);
+ assertThat(mCamera2CameraControl.getFlashMode()).isEqualTo(ImageCapture.FLASH_MODE_ON);
}
@Test
@@ -249,7 +248,7 @@
@Test
public void disableTorchFlashModeAuto_aeModeSetAndRequestUpdated() throws InterruptedException {
assumeTrue(mHasFlashUnit);
- mCamera2CameraControl.setFlashMode(FlashMode.AUTO);
+ mCamera2CameraControl.setFlashMode(ImageCapture.FLASH_MODE_AUTO);
mCamera2CameraControl.enableTorch(false);
HandlerUtil.waitForLooperToIdle(mHandler);
@@ -452,7 +451,7 @@
SurfaceOrientedMeteringPointFactory factory = new SurfaceOrientedMeteringPointFactory(1.0f,
1.0f);
FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0),
- MeteringMode.AE | MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
.build();
mCamera2CameraControl.startFocusAndMetering(action);
HandlerUtil.waitForLooperToIdle(mHandler);
@@ -546,7 +545,7 @@
SurfaceOrientedMeteringPointFactory factory = new SurfaceOrientedMeteringPointFactory(1.0f,
1.0f);
FocusMeteringAction action = FocusMeteringAction.Builder.from(factory.createPoint(0, 0),
- MeteringMode.AE)
+ FocusMeteringAction.FLAG_AE)
.build();
mCamera2CameraControl.startFocusAndMetering(action);
HandlerUtil.waitForLooperToIdle(mHandler);
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraImplTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraImplTest.java
index 6ea0506..1a8f75c 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraImplTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2CameraImplTest.java
@@ -51,7 +51,6 @@
import androidx.camera.core.CaptureConfig;
import androidx.camera.core.DeferrableSurface;
import androidx.camera.core.ImmediateSurface;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Observable;
import androidx.camera.core.SessionConfig;
import androidx.camera.core.UseCase;
@@ -101,8 +100,8 @@
@LargeTest
@RunWith(AndroidJUnit4.class)
public final class Camera2CameraImplTest {
- @LensFacing
- private static final int DEFAULT_LENS_FACING = LensFacing.BACK;
+ @CameraSelector.LensFacing
+ private static final int DEFAULT_LENS_FACING = CameraSelector.LENS_FACING_BACK;
// For the purpose of this test, always say we have 1 camera available.
private static final int DEFAULT_AVAILABLE_CAMERA_COUNT = 1;
private static final Set<CameraInternal.State> STABLE_STATES = new HashSet<>(Arrays.asList(
@@ -124,7 +123,8 @@
OnImageAvailableListener mMockOnImageAvailableListener;
String mCameraId;
- private static String getCameraIdForLensFacingUnchecked(@LensFacing int lensFacing) {
+ private static String getCameraIdForLensFacingUnchecked(
+ @CameraSelector.LensFacing int lensFacing) {
try {
return sCameraFactory.cameraIdForLensFacing(lensFacing);
} catch (Exception e) {
@@ -150,8 +150,8 @@
mSemaphore = new Semaphore(0);
mAvailableCameras = new SettableObservable<>(DEFAULT_AVAILABLE_CAMERA_COUNT);
mCamera2CameraImpl = new Camera2CameraImpl(
- CameraManagerCompat.from(ApplicationProvider.getApplicationContext()),
- mCameraId, mAvailableCameras, mCameraHandler);
+ CameraManagerCompat.from(ApplicationProvider.getApplicationContext()), mCameraId,
+ mAvailableCameras, mCameraHandler);
}
@After
@@ -806,7 +806,8 @@
FakeUseCaseConfig.Builder configBuilder =
new FakeUseCaseConfig.Builder().setTargetName("UseCase");
CameraSelector selector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
TestUseCase testUseCase = new TestUseCase(configBuilder.getUseCaseConfig(), selector,
mMockOnImageAvailableListener);
Map<String, Size> suggestedResolutionMap = new HashMap<>();
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraRepositoryTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraRepositoryTest.java
index cca44f9..188cc0b 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraRepositoryTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraRepositoryTest.java
@@ -32,8 +32,8 @@
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.CameraFactory;
import androidx.camera.core.CameraRepository;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImmediateSurface;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.SessionConfig;
import androidx.camera.core.UseCaseConfig;
import androidx.camera.core.UseCaseGroup;
@@ -74,7 +74,7 @@
private CameraDevice.StateCallback mDeviceStateCallback;
private String mCameraId;
- private String getCameraIdForLensFacingUnchecked(@LensFacing int lensFacing) {
+ private String getCameraIdForLensFacingUnchecked(@CameraSelector.LensFacing int lensFacing) {
try {
return mCameraFactory.cameraIdForLensFacing(lensFacing);
} catch (Exception e) {
@@ -116,7 +116,7 @@
FakeUseCaseConfig.Builder configBuilder = new FakeUseCaseConfig.Builder();
new Camera2Interop.Extender<>(configBuilder).setDeviceStateCallback(mDeviceStateCallback);
mConfig = configBuilder.getUseCaseConfig();
- mCameraId = getCameraIdForLensFacingUnchecked(LensFacing.BACK);
+ mCameraId = getCameraIdForLensFacingUnchecked(CameraSelector.LENS_FACING_BACK);
mUseCase = new CallbackAttachingFakeUseCase(mConfig, mCameraId);
mUseCaseGroup.addUseCase(mUseCase);
}
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java
index d0bcc8b..90436af 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/Camera2ImplCameraXTest.java
@@ -49,7 +49,6 @@
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageProxy;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.fakes.FakeLifecycleOwner;
@@ -82,8 +81,8 @@
@RunWith(AndroidJUnit4.class)
@UseExperimental(markerClass = ExperimentalCamera2Interop.class)
public final class Camera2ImplCameraXTest {
- @LensFacing
- private static final int DEFAULT_LENS_FACING = LensFacing.BACK;
+ @CameraSelector.LensFacing
+ private static final int DEFAULT_LENS_FACING = CameraSelector.LENS_FACING_BACK;
private static final CameraSelector DEFAULT_SELECTOR =
new CameraSelector.Builder().requireLensFacing(DEFAULT_LENS_FACING).build();
private final MutableLiveData<Long> mAnalysisResult = new MutableLiveData<>();
@@ -428,7 +427,7 @@
ImageAnalysis useCase0 = builder.build();
ImageCapture useCase1 = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.build();
mInstrumentation.runOnMainSync(new Runnable() {
@@ -460,7 +459,7 @@
ImageAnalysis useCase0 = builder.build();
ImageCapture useCase1 = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.build();
mInstrumentation.runOnMainSync(new Runnable() {
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/TorchControlDeviceTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/TorchControlDeviceTest.java
index 56c9277..c50ee68 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/TorchControlDeviceTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/TorchControlDeviceTest.java
@@ -27,7 +27,6 @@
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ImageAnalysis;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.fakes.FakeLifecycleOwner;
@@ -50,8 +49,8 @@
@MediumTest
@RunWith(AndroidJUnit4.class)
public class TorchControlDeviceTest {
- @LensFacing
- private static final int LENS_FACING = LensFacing.BACK;
+ @CameraSelector.LensFacing
+ private static final int LENS_FACING = CameraSelector.LENS_FACING_BACK;
@Rule
public GrantPermissionRule mCameraPermissionRule =
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/ZoomControlDeviceTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/ZoomControlDeviceTest.java
index b0ce14ef..2d1be53 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/ZoomControlDeviceTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/impl/ZoomControlDeviceTest.java
@@ -39,9 +39,9 @@
import androidx.camera.camera2.Camera2Config;
import androidx.camera.core.CameraControlInternal.ControlUpdateCallback;
import androidx.camera.core.CameraInfoUnavailableException;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.SessionConfig;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.testing.CameraUtil;
@@ -84,14 +84,14 @@
@Before
public void setUp()
throws CameraInfoUnavailableException, CameraAccessException, InterruptedException {
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.BACK));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK));
// Init CameraX
Context context = ApplicationProvider.getApplicationContext();
CameraXConfig config = Camera2Config.defaultConfig(context);
CameraX.initialize(context, config);
- String cameraId = CameraX.getCameraWithLensFacing(LensFacing.BACK);
+ String cameraId = CameraX.getCameraWithLensFacing(CameraSelector.LENS_FACING_BACK);
CameraManager cameraManager = (CameraManager) context.getSystemService(
Context.CAMERA_SERVICE);
mCameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java
index 10b8952..3d1258e 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraControl.java
@@ -16,6 +16,10 @@
package androidx.camera.camera2.impl;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_AUTO;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_OFF;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_ON;
+
import android.graphics.Rect;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
@@ -34,9 +38,9 @@
import androidx.camera.core.CameraControlInternal;
import androidx.camera.core.CaptureConfig;
import androidx.camera.core.Config;
-import androidx.camera.core.FlashMode;
import androidx.camera.core.FocusMeteringAction;
import androidx.camera.core.FocusMeteringResult;
+import androidx.camera.core.ImageCapture;
import androidx.camera.core.SessionConfig;
import androidx.camera.core.impl.utils.futures.Futures;
import androidx.core.util.Preconditions;
@@ -72,8 +76,8 @@
private final TorchControl mTorchControl;
// use volatile modifier to make these variables in sync in all threads.
private volatile boolean mIsTorchOn = false;
- @FlashMode
- private volatile int mFlashMode = FlashMode.OFF;
+ @ImageCapture.FlashMode
+ private volatile int mFlashMode = FLASH_MODE_OFF;
//******************** Should only be accessed by executor *****************************//
private Rect mCropRect = null;
@@ -171,7 +175,7 @@
mExecutor.execute(() -> setCropRegionInternal(crop));
}
- @FlashMode
+ @ImageCapture.FlashMode
@Override
public int getFlashMode() {
return mFlashMode;
@@ -179,7 +183,7 @@
/** {@inheritDoc} */
@Override
- public void setFlashMode(@FlashMode int flashMode) {
+ public void setFlashMode(@ImageCapture.FlashMode int flashMode) {
// update mFlashMode immediately so that following getFlashMode() returns correct value.
mFlashMode = flashMode;
@@ -323,13 +327,13 @@
CaptureRequest.FLASH_MODE_TORCH);
} else {
switch (mFlashMode) {
- case FlashMode.OFF:
+ case FLASH_MODE_OFF:
aeMode = CaptureRequest.CONTROL_AE_MODE_ON;
break;
- case FlashMode.ON:
+ case FLASH_MODE_ON:
aeMode = CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH;
break;
- case FlashMode.AUTO:
+ case FLASH_MODE_AUTO:
aeMode = CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH;
break;
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java
index 0e5a8b8..b2a2cde 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraFactory.java
@@ -29,8 +29,8 @@
import androidx.camera.core.CameraFactory;
import androidx.camera.core.CameraInfoUnavailableException;
import androidx.camera.core.CameraInternal;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraXThreads;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.LensFacingCameraIdFilter;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
@@ -93,7 +93,7 @@
@Override
@Nullable
- public String cameraIdForLensFacing(@LensFacing int lensFacing)
+ public String cameraIdForLensFacing(@CameraSelector.LensFacing int lensFacing)
throws CameraInfoUnavailableException {
Set<String> availableCameraIds = getLensFacingCameraIdFilter(
lensFacing).filter(getAvailableCameraIds());
@@ -107,7 +107,8 @@
@Override
@NonNull
- public LensFacingCameraIdFilter getLensFacingCameraIdFilter(@LensFacing int lensFacing) {
+ public LensFacingCameraIdFilter getLensFacingCameraIdFilter(
+ @CameraSelector.LensFacing int lensFacing) {
return new Camera2LensFacingCameraIdFilter(lensFacing, mCameraManager.unwrap());
}
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java
index 79225ad..c896054 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2CameraInfo.java
@@ -24,8 +24,8 @@
import androidx.annotation.Nullable;
import androidx.camera.core.CameraInfoInternal;
import androidx.camera.core.CameraOrientationUtil;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageOutputConfig.RotationValue;
-import androidx.camera.core.LensFacing;
import androidx.core.util.Preconditions;
import androidx.lifecycle.LiveData;
@@ -56,9 +56,9 @@
Preconditions.checkNotNull(lensFacing);
switch (lensFacing) {
case CameraCharacteristics.LENS_FACING_FRONT:
- return LensFacing.FRONT;
+ return CameraSelector.LENS_FACING_FRONT;
case CameraCharacteristics.LENS_FACING_BACK:
- return LensFacing.BACK;
+ return CameraSelector.LENS_FACING_BACK;
default:
return null;
}
@@ -73,7 +73,8 @@
// This may not be the case for all devices, so in the future we may need to handle that
// scenario.
final Integer lensFacing = getLensFacing();
- boolean isOppositeFacingScreen = (lensFacing != null && LensFacing.BACK == lensFacing);
+ boolean isOppositeFacingScreen =
+ (lensFacing != null && CameraSelector.LENS_FACING_BACK == lensFacing);
return CameraOrientationUtil.getRelativeImageRotation(
relativeRotationDegrees,
sensorOrientation,
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilter.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilter.java
index 1a020e7..70fc540 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilter.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilter.java
@@ -24,7 +24,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.LensFacingCameraIdFilter;
import java.util.LinkedHashSet;
@@ -40,7 +40,7 @@
private static final String TAG = "Camera2LensFacingCIF";
private CameraManager mCameraManager;
- Camera2LensFacingCameraIdFilter(@LensFacing int lensFacing,
+ Camera2LensFacingCameraIdFilter(@CameraSelector.LensFacing int lensFacing,
@NonNull CameraManager cameraManager) {
super(lensFacing);
mCameraManager = cameraManager;
@@ -70,13 +70,14 @@
return resultCameraIdSet;
}
- private Integer cameraXLensFacingToCamera2LensFacing(@LensFacing int lensFacing) {
+ private Integer cameraXLensFacingToCamera2LensFacing(
+ @CameraSelector.LensFacing int lensFacing) {
Integer lensFacingInteger = -1;
switch (lensFacing) {
- case LensFacing.BACK:
+ case CameraSelector.LENS_FACING_BACK:
lensFacingInteger = CameraMetadata.LENS_FACING_BACK;
break;
- case LensFacing.FRONT:
+ case CameraSelector.LENS_FACING_FRONT:
lensFacingInteger = CameraMetadata.LENS_FACING_FRONT;
break;
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpacker.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpacker.java
index 64993c6..38794ad 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpacker.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpacker.java
@@ -22,6 +22,7 @@
import androidx.camera.core.CaptureConfig;
import androidx.camera.core.DeviceProperties;
+import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCapture.CaptureMode;
import androidx.camera.core.ImageCaptureConfig;
import androidx.camera.core.UseCaseConfig;
@@ -69,12 +70,12 @@
|| "Pixel 3".equals(mDeviceProperties.model()))) {
if (mDeviceProperties.sdkVersion() >= Build.VERSION_CODES.O) {
switch (captureMode) {
- case CaptureMode.MAXIMIZE_QUALITY:
+ case ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY:
// enable ZSL to make sure HDR+ is enabled
builder.setCaptureRequestOption(
CaptureRequest.CONTROL_ENABLE_ZSL, true);
break;
- case CaptureMode.MINIMIZE_LATENCY:
+ case ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY:
// disable ZSL to turn off HDR+
builder.setCaptureRequestOption(
CaptureRequest.CONTROL_ENABLE_ZSL, false);
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/SupportedSurfaceCombination.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/SupportedSurfaceCombination.java
index c67da97..c9bf8b4 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/SupportedSurfaceCombination.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/SupportedSurfaceCombination.java
@@ -367,7 +367,7 @@
if (config.hasTargetAspectRatio()) {
// Checks the sensor orientation.
boolean isSensorLandscapeOrientation = isRotationNeeded(Surface.ROTATION_0);
- @AspectRatio int targetAspectRatio = config.getTargetAspectRatio();
+ @AspectRatio.Ratio int targetAspectRatio = config.getTargetAspectRatio();
switch (targetAspectRatio) {
case AspectRatio.RATIO_4_3:
aspectRatio =
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2CameraInfoTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2CameraInfoTest.java
index 6fa063c..bbaa3ec 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2CameraInfoTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2CameraInfoTest.java
@@ -29,7 +29,7 @@
import android.view.Surface;
import androidx.camera.core.CameraInfoInternal;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.TorchState;
import androidx.lifecycle.MutableLiveData;
import androidx.test.core.app.ApplicationProvider;
@@ -53,8 +53,8 @@
private static final String CAMERA0_ID = "0";
private static final int CAMERA0_SENSOR_ORIENTATION = 90;
- @LensFacing
- private static final int CAMERA0_LENS_FACING_ENUM = LensFacing.BACK;
+ @CameraSelector.LensFacing
+ private static final int CAMERA0_LENS_FACING_ENUM = CameraSelector.LENS_FACING_BACK;
private static final int CAMERA0_LENS_FACING_INT = CameraCharacteristics.LENS_FACING_BACK;
private static final boolean CAMERA0_FLASH_INFO_BOOLEAN = true;
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java
index aeb71dd..e1ebf57 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2DeviceSurfaceManagerTest.java
@@ -47,7 +47,6 @@
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureConfig;
import androidx.camera.core.ImageFormatConstants;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
import androidx.camera.core.SurfaceCombination;
@@ -503,7 +502,8 @@
CameraDeviceConfig deviceConfig =
CameraSelectorUtil.toCameraDeviceConfig(
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build());
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build());
Rational resultAspectRatio = mSurfaceManager.getCorrectedAspectRatio(deviceConfig,
previewConfig.getTargetRotation(Surface.ROTATION_0));
@@ -527,13 +527,15 @@
addCamera(
LEGACY_CAMERA_ID, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY, null,
CameraCharacteristics.LENS_FACING_FRONT);
- mCameraFactory.setDefaultCameraIdForLensFacing(LensFacing.FRONT, LEGACY_CAMERA_ID);
+ mCameraFactory.setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_FRONT,
+ LEGACY_CAMERA_ID);
addCamera(
LIMITED_CAMERA_ID, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
null,
CameraCharacteristics.LENS_FACING_BACK);
- mCameraFactory.setDefaultCameraIdForLensFacing(LensFacing.BACK, LIMITED_CAMERA_ID);
+ mCameraFactory.setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_BACK,
+ LIMITED_CAMERA_ID);
addCamera(
FULL_CAMERA_ID, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL, null,
@@ -575,7 +577,8 @@
StreamConfigurationMapUtil.generateFakeStreamConfigurationMap(
mSupportedFormats, mSupportedSizes));
- @LensFacing int lensFacingEnum = CameraUtil.getLensFacingEnumFromInt(lensFacing);
+ @CameraSelector.LensFacing int lensFacingEnum = CameraUtil.getLensFacingEnumFromInt(
+ lensFacing);
mCameraFactory.insertCamera(lensFacingEnum, cameraId, () -> new FakeCamera(cameraId, null,
new Camera2CameraInfo(characteristics, mock(ZoomControl.class),
mock(TorchControl.class))));
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilterTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilterTest.java
index 28c07188..620eb1c 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilterTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/Camera2LensFacingCameraIdFilterTest.java
@@ -23,7 +23,7 @@
import android.hardware.camera2.CameraManager;
import android.os.Build;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.CameraSelector;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
@@ -86,7 +86,8 @@
@Test
public void canFilterBackCamera() {
Camera2LensFacingCameraIdFilter lensFacingCameraIdFilter =
- new Camera2LensFacingCameraIdFilter(LensFacing.BACK, mCameraManager);
+ new Camera2LensFacingCameraIdFilter(CameraSelector.LENS_FACING_BACK,
+ mCameraManager);
mCameraIds = lensFacingCameraIdFilter.filter(mCameraIds);
assertThat(mCameraIds).contains(CAMERA0_ID);
assertThat(mCameraIds).doesNotContain(CAMERA1_ID);
@@ -95,7 +96,8 @@
@Test
public void canFilterFrontCamera() {
Camera2LensFacingCameraIdFilter lensFacingCameraIdFilter =
- new Camera2LensFacingCameraIdFilter(LensFacing.FRONT, mCameraManager);
+ new Camera2LensFacingCameraIdFilter(CameraSelector.LENS_FACING_FRONT,
+ mCameraManager);
mCameraIds = lensFacingCameraIdFilter.filter(mCameraIds);
assertThat(mCameraIds).contains(CAMERA1_ID);
assertThat(mCameraIds).doesNotContain(CAMERA0_ID);
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/DisplayOrientedMeteringPointFactoryTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/DisplayOrientedMeteringPointFactoryTest.java
index 3e27fae..02f4d59 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/DisplayOrientedMeteringPointFactoryTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/DisplayOrientedMeteringPointFactoryTest.java
@@ -34,7 +34,6 @@
import androidx.camera.core.ConfigProvider;
import androidx.camera.core.DisplayOrientedMeteringPointFactory;
import androidx.camera.core.ExtendableUseCaseConfigFactory;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.MeteringPoint;
import androidx.camera.core.MeteringPointFactory;
import androidx.camera.testing.fakes.FakeCamera;
@@ -68,9 +67,10 @@
private Context mMockContext;
private Display mMockDisplay;
private static final CameraSelector FRONT_CAM =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build();
private static final CameraSelector BACK_CAM =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
@Before
public void setUp() {
@@ -79,9 +79,11 @@
// Init CameraX to inject our FakeCamera with FakeCameraInfo.
FakeCameraFactory fakeCameraFactory = new FakeCameraFactory();
fakeCameraFactory.insertDefaultBackCamera(BACK_CAMERA_ID,
- () -> new FakeCamera(null, new FakeCameraInfoInternal(90, LensFacing.BACK)));
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(90, CameraSelector.LENS_FACING_BACK)));
fakeCameraFactory.insertDefaultFrontCamera(FRONT_CAMERA_ID,
- () -> new FakeCamera(null, new FakeCameraInfoInternal(270, LensFacing.FRONT)));
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(270, CameraSelector.LENS_FACING_FRONT)));
CameraDeviceSurfaceManager surfaceManager = new FakeCameraDeviceSurfaceManager();
ExtendableUseCaseConfigFactory defaultConfigFactory = new ExtendableUseCaseConfigFactory();
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/FocusMeteringControlTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/FocusMeteringControlTest.java
index d122e9f..53efd49 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/FocusMeteringControlTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/FocusMeteringControlTest.java
@@ -43,7 +43,6 @@
import androidx.camera.camera2.impl.Camera2CameraControl.CaptureResultListener;
import androidx.camera.core.CameraControlInternal;
import androidx.camera.core.FocusMeteringAction;
-import androidx.camera.core.FocusMeteringAction.MeteringMode;
import androidx.camera.core.FocusMeteringResult;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.MeteringPoint;
@@ -273,9 +272,11 @@
@Test
public void startFocusAndMetering_multiplePointVariousModes() {
mFocusMeteringControl.startFocusAndMetering(
- FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AF | MeteringMode.AE)
- .addPoint(mPoint3, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
+ FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
.build(), PREVIEW_ASPECT_RATIO_4_X_3);
MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
@@ -298,9 +299,9 @@
@Test
public void startFocusAndMetering_multiplePointVariousModes2() {
mFocusMeteringControl.startFocusAndMetering(
- FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AF)
- .addPoint(mPoint2, MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AE)
+ FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.FLAG_AF)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AE)
.build(), PREVIEW_ASPECT_RATIO_4_X_3);
MeteringRectangle[] afRects = getAfRects(mFocusMeteringControl);
MeteringRectangle[] aeRects = getAeRects(mFocusMeteringControl);
@@ -424,7 +425,8 @@
@Test
public void withAFPoints_AFIsTriggered() {
mFocusMeteringControl.startFocusAndMetering(FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB).build(),
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl).triggerAf();
@@ -432,21 +434,21 @@
mFocusMeteringControl.startFocusAndMetering(
FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF).build(),
+ FocusMeteringAction.FLAG_AF).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl).triggerAf();
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.startFocusAndMetering(
FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AE).build(),
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl).triggerAf();
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.startFocusAndMetering(
FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AWB).build(),
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AWB).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl).triggerAf();
Mockito.reset(mFocusMeteringControl);
@@ -455,26 +457,26 @@
@Test
public void withoutAFPoints_AFIsNotTriggered() {
mFocusMeteringControl.startFocusAndMetering(
- FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AE).build(),
+ FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.FLAG_AE).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl, never()).triggerAf();
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.startFocusAndMetering(
- FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AWB).build(),
+ FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.FLAG_AWB).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl, never()).triggerAf();
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.startFocusAndMetering(
- FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AE).build(),
+ FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.FLAG_AE).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl, never()).triggerAf();
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.startFocusAndMetering(
FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AE | MeteringMode.AWB).build(),
+ FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB).build(),
PREVIEW_ASPECT_RATIO_4_X_3);
verify(mFocusMeteringControl, never()).triggerAf();
Mockito.reset(mFocusMeteringControl);
@@ -533,7 +535,7 @@
public void listenableFutureForStart_AEAWB_focusIsFalse()
throws ExecutionException, InterruptedException {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AE | MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
.build();
ListenableFuture<FocusMeteringResult> future =
mFocusMeteringControl.startFocusAndMetering(action,
@@ -544,7 +546,8 @@
@Test
public void listenableFutureForStart_AE_focusIsFalse()
throws ExecutionException, InterruptedException {
- FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AE)
+ FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+ FocusMeteringAction.FLAG_AE)
.build();
ListenableFuture<FocusMeteringResult> future2 =
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
@@ -556,7 +559,7 @@
public void listenableFutureForStart_AWB_focusIsFalse()
throws ExecutionException, InterruptedException {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- FocusMeteringAction.MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AWB)
.build();
ListenableFuture<FocusMeteringResult> future3 =
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
@@ -617,8 +620,11 @@
@Test
public void cancelFocusAndMetering_regionIsReset() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
@@ -644,8 +650,11 @@
@Test
public void cancelFocusAndMetering_updateSessionIsCalled() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
@@ -660,7 +669,8 @@
public void cancelFocusAndMetering_triggerCancelAfProperly() {
// If AF is enabled, cancel operation needs to call cancelAfAeTriggerInternal(true, false)
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
@@ -668,21 +678,23 @@
mFocusMeteringControl.cancelFocusAndMetering();
verify(mFocusMeteringControl, times(1)).cancelAfAeTrigger(true, false);
- action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AF | MeteringMode.AE)
+ action = FocusMeteringAction.Builder.from(mPoint1,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.cancelFocusAndMetering();
verify(mFocusMeteringControl, times(1)).cancelAfAeTrigger(true, false);
- action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AF | MeteringMode.AWB)
+ action = FocusMeteringAction.Builder.from(mPoint1,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AWB)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.cancelFocusAndMetering();
verify(mFocusMeteringControl, times(1)).cancelAfAeTrigger(true, false);
- action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AF)
+ action = FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.FLAG_AF)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
Mockito.reset(mFocusMeteringControl);
@@ -692,7 +704,8 @@
@Test
public void cancelFocusAndMetering_AFNotInvolved_cancelAfNotTriggered() {
- FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AE)
+ FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+ FocusMeteringAction.FLAG_AE)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
@@ -700,14 +713,15 @@
mFocusMeteringControl.cancelFocusAndMetering();
verify(mFocusMeteringControl, never()).cancelAfAeTrigger(true, false);
- action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AWB)
+ action = FocusMeteringAction.Builder.from(mPoint1, FocusMeteringAction.FLAG_AWB)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
Mockito.reset(mFocusMeteringControl);
mFocusMeteringControl.cancelFocusAndMetering();
verify(mFocusMeteringControl, never()).cancelAfAeTrigger(true, false);
- action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AE | MeteringMode.AWB)
+ action = FocusMeteringAction.Builder.from(mPoint1,
+ FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
.build();
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
Mockito.reset(mFocusMeteringControl);
@@ -757,7 +771,7 @@
@Test
public void startFocusMetering_AfNotInvolved_isAfAutoModeIsSet() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AE | MeteringMode.AWB).build();
+ FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB).build();
verifyAfMode(CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mFocusMeteringControl.startFocusAndMetering(action, PREVIEW_ASPECT_RATIO_4_X_3);
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpackerTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpackerTest.java
index d88c15c..c73fb57 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpackerTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/ImageCaptureOptionUnpackerTest.java
@@ -108,7 +108,7 @@
public void unpackWithValidPixel2AndMinLatency() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MINIMIZE_LATENCY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_2_API26);
@@ -126,7 +126,7 @@
public void unpackWithValidPixel2AndMaxQuality() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_2_API26);
@@ -144,7 +144,7 @@
public void unpackWithPixel2NotSupportApiLevelAndMinLatency() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MINIMIZE_LATENCY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_2_NOT_SUPPORT_API);
@@ -162,7 +162,7 @@
public void unpackWithPixel2NotSupportApiLevelAndMaxQuality() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_2_NOT_SUPPORT_API);
@@ -180,7 +180,7 @@
public void unpackWithValidPixel3AndMinLatency() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MINIMIZE_LATENCY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_3_API26);
@@ -198,7 +198,7 @@
public void unpackWithValidPixel3AndMaxQuality() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_3_API26);
@@ -216,7 +216,7 @@
public void unpackWithPixel3NotSupportApiLevelAndMinLatency() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MINIMIZE_LATENCY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_3_NOT_SUPPORT_API);
@@ -234,7 +234,7 @@
public void unpackWithPixel3NotSupportApiLevelAndMaxQuality() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_PIXEL_3_NOT_SUPPORT_API);
@@ -252,7 +252,7 @@
public void unpackWithNotSupportManufacture() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_NOT_GOOGLE);
@@ -270,7 +270,7 @@
public void unpackWithNotSupportModel() {
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
ImageCaptureConfig imageCaptureConfig = new ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.getUseCaseConfig();
mUnpacker.setDeviceProperty(PROPERTIES_NOT_SUPPORT_MODEL);
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/SupportedSurfaceCombinationTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/SupportedSurfaceCombinationTest.java
index 1a91168..e56cf99 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/SupportedSurfaceCombinationTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/impl/SupportedSurfaceCombinationTest.java
@@ -49,7 +49,6 @@
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureConfig;
import androidx.camera.core.ImageFormatConstants;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
import androidx.camera.core.SurfaceCombination;
@@ -484,7 +483,8 @@
// Ensure we are bound to a camera to ensure aspect ratio correction is applied.
FakeLifecycleOwner fakeLifecycle = new FakeLifecycleOwner();
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build();
CameraX.bindToLifecycle(fakeLifecycle, cameraSelector, preview);
PreviewConfig config = (PreviewConfig) preview.getUseCaseConfig();
@@ -1041,13 +1041,15 @@
addCamera(
LEGACY_CAMERA_ID, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY, null,
CameraCharacteristics.LENS_FACING_FRONT);
- mCameraFactory.setDefaultCameraIdForLensFacing(LensFacing.FRONT, LEGACY_CAMERA_ID);
+ mCameraFactory.setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_FRONT,
+ LEGACY_CAMERA_ID);
addCamera(
LIMITED_CAMERA_ID,
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
null, CameraCharacteristics.LENS_FACING_BACK);
- mCameraFactory.setDefaultCameraIdForLensFacing(LensFacing.BACK, LIMITED_CAMERA_ID);
+ mCameraFactory.setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_BACK,
+ LIMITED_CAMERA_ID);
addCamera(
FULL_CAMERA_ID, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL, null,
@@ -1101,7 +1103,8 @@
StreamConfigurationMapUtil.generateFakeStreamConfigurationMap(
supportedFormats, mSupportedSizes));
- @LensFacing int lensFacingEnum = CameraUtil.getLensFacingEnumFromInt(lensFacing);
+ @CameraSelector.LensFacing int lensFacingEnum = CameraUtil.getLensFacingEnumFromInt(
+ lensFacing);
mCameraFactory.insertCamera(lensFacingEnum, cameraId, () -> new FakeCamera(cameraId, null,
new Camera2CameraInfo(characteristics, mock(ZoomControl.class),
mock(TorchControl.class))));
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/CameraXTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/CameraXTest.java
index 67739a6..569b8f0 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/CameraXTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/CameraXTest.java
@@ -59,10 +59,10 @@
@MediumTest
@RunWith(AndroidJUnit4.class)
public final class CameraXTest {
- @LensFacing
- private static final int CAMERA_LENS_FACING = LensFacing.BACK;
- @LensFacing
- private static final int CAMERA_LENS_FACING_FRONT = LensFacing.FRONT;
+ @CameraSelector.LensFacing
+ private static final int CAMERA_LENS_FACING = CameraSelector.LENS_FACING_BACK;
+ @CameraSelector.LensFacing
+ private static final int CAMERA_LENS_FACING_FRONT = CameraSelector.LENS_FACING_FRONT;
private static final CameraSelector CAMERA_SELECTOR =
new CameraSelector.Builder().requireLensFacing(CAMERA_LENS_FACING).build();
private static final String CAMERA_ID = "0";
@@ -306,10 +306,12 @@
CameraX.initialize(mContext, appConfigBuilder.build());
CameraSelector frontSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build();
FakeUseCase fakeUseCase = new FakeUseCaseConfig.Builder().build();
CameraSelector backSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
FakeOtherUseCase fakeOtherUseCase = new FakeOtherUseCaseConfig.Builder().build();
boolean hasException = false;
@@ -336,7 +338,7 @@
public void bindUseCases_withNotExistedLensFacingCamera() {
initCameraX();
CameraSelector frontSelector = new CameraSelector.Builder().requireLensFacing(
- LensFacing.FRONT).build();
+ CameraSelector.LENS_FACING_FRONT).build();
FakeUseCaseConfig config0 = new FakeUseCaseConfig.Builder().getUseCaseConfig();
FakeUseCase fakeUseCase = new FakeUseCase(config0);
@@ -464,14 +466,16 @@
public void checkHasCameraTrueForExistentCamera() throws CameraInfoUnavailableException {
initCameraX();
assertThat(CameraX.hasCamera(
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build())).isTrue();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build())).isTrue();
}
@Test
public void checkHasCameraFalseForNonexistentCamera() throws CameraInfoUnavailableException {
initCameraX();
assertThat(CameraX.hasCamera(new CameraSelector.Builder().requireLensFacing(
- LensFacing.BACK).requireLensFacing(LensFacing.FRONT).build())).isFalse();
+ CameraSelector.LENS_FACING_BACK).requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build())).isFalse();
}
private void initCameraX() {
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java
index 37364e5..b24ee22 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java
@@ -115,12 +115,12 @@
@Override
@Nullable
- public Integer getLensFacing(@LensFacing Integer valueIfMissing) {
+ public Integer getLensFacing(@CameraSelector.LensFacing Integer valueIfMissing) {
return retrieveOption(OPTION_LENS_FACING, valueIfMissing);
}
@Override
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return retrieveOption(OPTION_LENS_FACING);
}
@@ -293,7 +293,7 @@
@Override
@NonNull
- public Builder setLensFacing(@LensFacing int lensFacing) {
+ public Builder setLensFacing(@CameraSelector.LensFacing int lensFacing) {
getMutableConfig().insertOption(OPTION_LENS_FACING, lensFacing);
return this;
}
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageSaverTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageSaverTest.java
index 51f196e..f24a21d 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageSaverTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageSaverTest.java
@@ -111,7 +111,7 @@
}
@Override
- public void onError(@SaveError int saveError, String message,
+ public void onError(SaveError saveError, String message,
@Nullable Throwable cause) {
mMockCallback.onError(saveError, message, cause);
mSemaphore.release();
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/UseCaseAttachStateTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/UseCaseAttachStateTest.java
index c753a5e..7d08df2 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/UseCaseAttachStateTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/UseCaseAttachStateTest.java
@@ -51,9 +51,10 @@
@RunWith(AndroidJUnit4.class)
public class UseCaseAttachStateTest {
private static final CameraSelector BACK_CAMERA_SELECTOR =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
private static final CameraSelector FRONT_CAMERA_SELECTOR =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build();
private final CameraDevice mMockCameraDevice = Mockito.mock(CameraDevice.class);
private final CameraCaptureSession mMockCameraCaptureSession =
Mockito.mock(CameraCaptureSession.class);
@@ -65,10 +66,11 @@
CameraXConfig cameraXConfig = FakeAppConfig.create();
CameraFactory cameraFactory = cameraXConfig.getCameraFactory(/*valueIfMissing=*/ null);
try {
- mCameraId = cameraFactory.cameraIdForLensFacing(LensFacing.BACK);
+ mCameraId = cameraFactory.cameraIdForLensFacing(CameraSelector.LENS_FACING_BACK);
} catch (Exception e) {
throw new IllegalArgumentException(
- "Unable to attach to camera with LensFacing " + LensFacing.BACK, e);
+ "Unable to attach to camera with LensFacing " + CameraSelector.LENS_FACING_BACK,
+ e);
}
CameraX.initialize(ApplicationProvider.getApplicationContext(), cameraXConfig);
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/AspectRatio.java b/camera/camera-core/src/main/java/androidx/camera/core/AspectRatio.java
index ba82764..3233526 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/AspectRatio.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/AspectRatio.java
@@ -17,19 +17,31 @@
package androidx.camera.core;
import androidx.annotation.IntDef;
+import androidx.annotation.RestrictTo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-/** The aspect ratio of the use case.
+/**
+ * The aspect ratio of the use case.
*
* <p>Aspect ratio is the ratio of width to height.
*/
-@IntDef({AspectRatio.RATIO_4_3, AspectRatio.RATIO_16_9})
-@Retention(RetentionPolicy.SOURCE)
-public @interface AspectRatio {
+public class AspectRatio {
/** 4:3 standard aspect ratio. */
- int RATIO_4_3 = 0;
+ public static final int RATIO_4_3 = 0;
/** 16:9 standard aspect ratio. */
- int RATIO_16_9 = 1;
+ public static final int RATIO_16_9 = 1;
+
+ private AspectRatio() {
+ }
+
+ /**
+ * @hide
+ */
+ @IntDef({RATIO_4_3, RATIO_16_9})
+ @Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public @interface Ratio {
+ }
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java
index 921e399..88cb752 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraControl.java
@@ -50,8 +50,8 @@
* a failed result and the torch state will be {@link TorchState#OFF}.
*
* <p>When the torch is enabled, the torch will remain enabled during photo capture regardless
- * of {@link FlashMode} setting. When the torch is disabled, flash will function as
- * {@link FlashMode} set by either {@link ImageCapture#setFlashMode(int)} or
+ * of the flashMode setting. When the torch is disabled, flash will function as the flash mode
+ * set by either {@link ImageCapture#setFlashMode(int)} or
* {@link ImageCapture.Builder#setFlashMode(int)}.
*
* @param torch true to turn on the torch, false to turn it off.
@@ -73,10 +73,12 @@
* {@link FocusMeteringAction} are executed in a row, only the latest one will work and
* other actions will be cancelled.
*
- * <p>If the {@link FocusMeteringAction} specifies more AF/AE/AWB regions than what is
- * supported on current device, only the first region and then in order up to the number of
- * regions supported by the device will be enabled. If it turns out no added regions can be
- * supported on the device, the returned {@link ListenableFuture} in
+ * <p>If the {@link FocusMeteringAction} specifies more AF/AE/AWB points than what is
+ * supported on current device, only the first point and then in order up to the number of
+ * points supported by the device will be enabled.
+ *
+ * <p>If none of the points with either AF/AE/AWB can be supported on the device,
+ * the returned {@link ListenableFuture} in
* {@link CameraControl#startFocusAndMetering(FocusMeteringAction)} will fail immediately.
*
* @see FocusMeteringAction
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java
index 9f34a0b..3fc7787 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraControlInternal.java
@@ -16,12 +16,15 @@
package androidx.camera.core;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_OFF;
+
import android.graphics.Rect;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
+import androidx.camera.core.ImageCapture.FlashMode;
import androidx.camera.core.impl.utils.futures.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@@ -82,7 +85,7 @@
@FlashMode
@Override
public int getFlashMode() {
- return FlashMode.OFF;
+ return FLASH_MODE_OFF;
}
@Override
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraDeviceConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraDeviceConfig.java
index e7ffede..fdba1cc 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraDeviceConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraDeviceConfig.java
@@ -75,7 +75,7 @@
* @hide
*/
@RestrictTo(Scope.LIBRARY_GROUP)
- @LensFacing
+ @CameraSelector.LensFacing
int getLensFacing();
/**
@@ -122,7 +122,7 @@
*/
@NonNull
@RestrictTo(Scope.LIBRARY_GROUP)
- B setLensFacing(@LensFacing int lensFacing);
+ B setLensFacing(@CameraSelector.LensFacing int lensFacing);
/**
* Sets the {@link CameraIdFilter} that filter out the unavailable camera ids.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraFactory.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraFactory.java
index eda17a6..c435ecd 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraFactory.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraFactory.java
@@ -41,10 +41,10 @@
* camera with specified lens facing.
*/
@Nullable
- String cameraIdForLensFacing(@LensFacing int lensFacing)
+ String cameraIdForLensFacing(@CameraSelector.LensFacing int lensFacing)
throws CameraInfoUnavailableException;
/** Gets a {@link LensFacingCameraIdFilter} with specified lens facing. */
@NonNull
- LensFacingCameraIdFilter getLensFacingCameraIdFilter(@LensFacing int lensFacing);
+ LensFacingCameraIdFilter getLensFacingCameraIdFilter(@CameraSelector.LensFacing int lensFacing);
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraSelector.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraSelector.java
index 5a17a7c..c5ba14a 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraSelector.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraSelector.java
@@ -15,11 +15,14 @@
*/
package androidx.camera.core;
+import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -27,14 +30,20 @@
* A set of requirements and priorities used to select a camera.
*/
public final class CameraSelector {
+
+ /** A camera on the device facing the same direction as the device's screen. */
+ public static final int LENS_FACING_FRONT = 0;
+ /** A camera on the device facing the opposite direction as the device's screen. */
+ public static final int LENS_FACING_BACK = 1;
+
/** A static {@link CameraSelector} that selects the default front facing camera. */
@NonNull
public static final CameraSelector DEFAULT_FRONT_CAMERA =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(LENS_FACING_FRONT).build();
/** A static {@link CameraSelector} that selects the default back facing camera. */
@NonNull
public static final CameraSelector DEFAULT_BACK_CAMERA =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(LENS_FACING_BACK).build();
private LinkedHashSet<CameraIdFilter> mCameraFilterSet;
@@ -175,4 +184,15 @@
return new CameraSelector(mCameraFilterSet);
}
}
+
+ /**
+ * The direction the camera faces relative to device screen.
+ *
+ * @hide
+ */
+ @IntDef({LENS_FACING_FRONT, LENS_FACING_BACK})
+ @Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public @interface LensFacing {
+ }
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
index ee75e83..fd76a49 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
@@ -435,7 +435,7 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@Nullable
- public static String getCameraWithLensFacing(@LensFacing int lensFacing)
+ public static String getCameraWithLensFacing(@CameraSelector.LensFacing int lensFacing)
throws CameraInfoUnavailableException {
checkInitialized();
return getCameraFactory().cameraIdForLensFacing(lensFacing);
@@ -493,12 +493,13 @@
* @hide
*/
@RestrictTo(Scope.LIBRARY_GROUP)
- @LensFacing
+ @CameraSelector.LensFacing
public static int getDefaultLensFacing() throws CameraInfoUnavailableException {
checkInitialized();
Integer lensFacingCandidate = null;
- List<Integer> lensFacingList = Arrays.asList(LensFacing.BACK, LensFacing.FRONT);
+ List<Integer> lensFacingList = Arrays.asList(CameraSelector.LENS_FACING_BACK,
+ CameraSelector.LENS_FACING_FRONT);
for (Integer lensFacing : lensFacingList) {
String cameraId = getCameraFactory().cameraIdForLensFacing(lensFacing);
if (cameraId != null) {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/DisplayOrientedMeteringPointFactory.java b/camera/camera-core/src/main/java/androidx/camera/core/DisplayOrientedMeteringPointFactory.java
index 4ed7285..fa4fc7b 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/DisplayOrientedMeteringPointFactory.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/DisplayOrientedMeteringPointFactory.java
@@ -36,7 +36,7 @@
* rotating applied, they can simply use view width and height to create the
* {@link DisplayOrientedMeteringPointFactory} and then pass {@link View} (x, y) to create a
* {@link MeteringPoint}. This factory will convert the (x, y) into the sensor (x, y) based on
- * display rotation and {@link LensFacing}.
+ * display rotation and lensFacing.
*
* <p>If camera preview is scaled, cropped or rotated in the {@link View}, it is applications'
* duty to transform the coordinates properly so that the width and height of this
@@ -145,7 +145,8 @@
float height = mHeight;
final Integer lensFacing = getLensFacing();
- boolean compensateForMirroring = (lensFacing != null && lensFacing == LensFacing.FRONT);
+ boolean compensateForMirroring =
+ (lensFacing != null && lensFacing == CameraSelector.LENS_FACING_FRONT);
int relativeCameraOrientation = getRelativeCameraOrientation(compensateForMirroring);
float outputX = x;
float outputY = y;
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/FlashMode.java b/camera/camera-core/src/main/java/androidx/camera/core/FlashMode.java
deleted file mode 100644
index 9d63b33..0000000
--- a/camera/camera-core/src/main/java/androidx/camera/core/FlashMode.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.core;
-
-import androidx.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The flash mode options when taking a picture using ImageCapture.
- *
- * <p>Applications can check if there is a flash unit via {@link CameraInfo#hasFlashUnit()} and
- * update UI component if necessary. If there is no flash unit, then the FlashMode set to
- * {@link ImageCapture#setFlashMode(int)} will take no effect for the subsequent photo capture
- * requests and they will act like {@link FlashMode#OFF}.
- *
- * <p>When the torch is enabled via {@link CameraControl#enableTorch(boolean)}, the torch
- * will remain enabled during photo capture regardless of flash mode setting. When
- * the torch is disabled, flash will function as specified by
- * {@link ImageCapture#setFlashMode(int)}.
- */
-@IntDef({FlashMode.AUTO, FlashMode.ON, FlashMode.OFF})
-@Retention(RetentionPolicy.SOURCE)
-public @interface FlashMode {
- /**
- * Auto flash. The flash will be used according to the camera system's determination when taking
- * a picture.
- */
- int AUTO = 0;
- /** Always flash. The flash will always be used when taking a picture. */
- int ON = 1;
- /** No flash. The flash will never be used when taking a picture. */
- int OFF = 2;
-}
\ No newline at end of file
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/FlashModeHelper.java b/camera/camera-core/src/main/java/androidx/camera/core/FlashModeHelper.java
index 7b2abc3..c1a8a6d 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/FlashModeHelper.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/FlashModeHelper.java
@@ -16,9 +16,14 @@
package androidx.camera.core;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_AUTO;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_OFF;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_ON;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
+import androidx.camera.core.ImageCapture.FlashMode;
/**
* Helper class that defines certain enum-like methods for {@link FlashMode}
@@ -45,11 +50,11 @@
switch (name) {
case "AUTO":
- return FlashMode.AUTO;
+ return FLASH_MODE_AUTO;
case "ON":
- return FlashMode.ON;
+ return FLASH_MODE_ON;
case "OFF":
- return FlashMode.OFF;
+ return FLASH_MODE_OFF;
default:
throw new IllegalArgumentException("Unknown flash mode name " + name);
}
@@ -64,11 +69,11 @@
@NonNull
public static String nameOf(@FlashMode final int flashMode) {
switch (flashMode) {
- case FlashMode.AUTO:
+ case FLASH_MODE_AUTO:
return "AUTO";
- case FlashMode.ON:
+ case FLASH_MODE_ON:
return "ON";
- case FlashMode.OFF:
+ case FLASH_MODE_OFF:
return "OFF";
default:
throw new IllegalArgumentException("Unknown flash mode " + flashMode);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/FocusMeteringAction.java b/camera/camera-core/src/main/java/androidx/camera/core/FocusMeteringAction.java
index 95502661..27b7778 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/FocusMeteringAction.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/FocusMeteringAction.java
@@ -19,6 +19,7 @@
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
import androidx.core.util.Preconditions;
import com.google.common.util.concurrent.ListenableFuture;
@@ -40,12 +41,11 @@
* pass it to {@link CameraControl#startFocusAndMetering(FocusMeteringAction)} to initiate the focus
* and metering action.
*
- * <p>The default {@link MeteringMode} is {@link MeteringMode#AF} | {@link MeteringMode#AE} |
- * {@link MeteringMode#AWB} which means the point is used for all AF/AE/AWB regions. Apps can set
- * the proper {@link MeteringMode} to optionally exclude some 3A regions. Multiple regions for
- * specific 3A type are also supported via {@link Builder#addPoint(MeteringPoint)} or
- * {@link Builder#addPoint(MeteringPoint, int)}. App can also this API to enable
- * different region for AF and AE respectively.
+ * <p>The default meteringMode is {@link #FLAG_AF} | {@link #FLAG_AE} | {@link #FLAG_AWB} which
+ * means the point is used for all AF/AE/AWB regions. Apps can set the proper meteringMode to
+ * optionally exclude some 3A regions. Multiple regions for specific 3A type are also supported
+ * via {@link Builder#addPoint(MeteringPoint)} or {@link Builder#addPoint(MeteringPoint, int)}.
+ * App can also this API to enable different region for AF and AE respectively.
*
* <p>If any AF points are specified, it will trigger autofocus to start a manual scan. When
* focus is locked and specified AF/AE/AWB regions are updated in capture result, the returned
@@ -64,8 +64,13 @@
* to disable auto-cancel.
*/
public final class FocusMeteringAction {
+
+ public static final int FLAG_AF = 1;
+ public static final int FLAG_AE = 1 << 1;
+ public static final int FLAG_AWB = 1 << 2;
+
@MeteringMode
- static final int DEFAULT_METERINGMODE = MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB;
+ static final int DEFAULT_METERINGMODE = FLAG_AF | FLAG_AE | FLAG_AWB;
static final long DEFAULT_AUTOCANCEL_DURATION = 5000;
private final List<MeteringPoint> mMeteringPointsAf;
private final List<MeteringPoint> mMeteringPointsAe;
@@ -121,13 +126,13 @@
/**
* Focus/Metering mode used to specify which 3A regions is activated for corresponding
* {@link MeteringPoint}.
+ *
+ * @hide
*/
- @IntDef(flag = true, value = {MeteringMode.AF, MeteringMode.AE, MeteringMode.AWB})
+ @IntDef(flag = true, value = {FLAG_AF, FLAG_AE, FLAG_AWB})
@Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public @interface MeteringMode {
- int AF = 1;
- int AE = 1 << 1;
- int AWB = 1 << 2;
}
/**
@@ -143,7 +148,7 @@
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
final List<MeteringPoint> mMeteringPointsAwb = new ArrayList<>();
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
- long mAutoCancelDurationInMillis = DEFAULT_AUTOCANCEL_DURATION;
+ long mAutoCancelDurationInMillis = DEFAULT_AUTOCANCEL_DURATION;
private Builder(@NonNull MeteringPoint point) {
this(point, DEFAULT_METERINGMODE);
@@ -155,7 +160,7 @@
/**
* Creates the Builder from a {@link MeteringPoint} with default
- * mode {@link MeteringMode#AF} | {@link MeteringMode#AE} | {@link MeteringMode#AWB}.
+ * mode {@link #FLAG_AF} | {@link #FLAG_AE} | {@link #FLAG_AWB}.
*/
@NonNull
public static Builder from(@NonNull MeteringPoint meteringPoint) {
@@ -163,23 +168,30 @@
}
/**
- * Creates the Builder from a {@link MeteringPoint} and {@link MeteringMode}
+ * Creates the Builder from a {@link MeteringPoint} and MeteringMode.
*/
@NonNull
- public static Builder from(@NonNull MeteringPoint meteringPoint,
- @MeteringMode int mode) {
+ public static Builder from(@NonNull MeteringPoint meteringPoint, @MeteringMode int mode) {
return new Builder(meteringPoint, mode);
}
/**
- * Adds another {@link MeteringPoint} with default mode {@link MeteringMode#AF} |
- * {@link MeteringMode#AE} | {@link MeteringMode#AWB}.
+ * Adds another {@link MeteringPoint} with default mode {@link #FLAG_AF} |
+ * {@link #FLAG_AE} | {@link #FLAG_AWB}.
+ *
+ * <p>The points added here will be appended in order after the point set in
+ * {@link FocusMeteringAction.Builder#from(MeteringPoint)} or
+ * {@link FocusMeteringAction.Builder#from(MeteringPoint, int)}.
*
* <p>If more points are added than what current device supports for AF/AE/AWB, only the
- * first region and then in order up to the number of regions supported by the device
- * will be enabled. If it turns out no added points can be supported on the device, the
- * returned {@link ListenableFuture} in
- * {@link CameraControl#startFocusAndMetering(FocusMeteringAction)} will fail immediately.
+ * first point and then in order up to the number of points supported on the device
+ * will be enabled.
+ *
+ * <p>If none of the points is supported on the device, this
+ * {@link FocusMeteringAction} will cause
+ * {@link CameraControl#startFocusAndMetering(FocusMeteringAction)} to fail.
+ *
+ * @see CameraControl#startFocusAndMetering(FocusMeteringAction)
*/
@NonNull
public Builder addPoint(@NonNull MeteringPoint point) {
@@ -187,30 +199,35 @@
}
/**
- * Adds another {@link MeteringPoint} with specified {@link MeteringMode}.
+ * Adds another {@link MeteringPoint} with specified meteringMode.
+ *
+ * <p>The points added here will be appended in order after the point set in
+ * {@link FocusMeteringAction.Builder#from(MeteringPoint)} or
+ * {@link FocusMeteringAction.Builder#from(MeteringPoint, int)}.
*
* <p>If more points are added than what current device supports for AF/AE/AWB, only the
- * first region and then in order up to the number of regions supported by the device
- * will be enabled. If it turns out no added points can be supported on the device, the
- * returned {@link ListenableFuture} in
- * {@link CameraControl#startFocusAndMetering(FocusMeteringAction)} will fail immediately.
+ * first point and then in order up to the number of points supported on the device
+ * will be enabled.
*
- * @param mode Must be a valid {@link MeteringMode}, otherwise an
- * {@link IllegalArgumentException} is thrown.
+ * <p>If none of the points is supported on the device, this
+ * {@link FocusMeteringAction} will cause
+ * {@link CameraControl#startFocusAndMetering(FocusMeteringAction)} to fail.
+ *
+ * @see CameraControl#startFocusAndMetering(FocusMeteringAction)
*/
@NonNull
public Builder addPoint(@NonNull MeteringPoint point, @MeteringMode int mode) {
Preconditions.checkArgument(
- (mode >= MeteringMode.AF) && (mode <= (MeteringMode.AF | MeteringMode.AE
- | MeteringMode.AWB)), "Invalid metering mode " + mode);
+ (mode >= FLAG_AF) && (mode <= (FLAG_AF | FLAG_AE | FLAG_AWB)),
+ "Invalid metering mode " + mode);
- if ((mode & MeteringMode.AF) != 0) {
+ if ((mode & FLAG_AF) != 0) {
mMeteringPointsAf.add(point);
}
- if ((mode & MeteringMode.AE) != 0) {
+ if ((mode & FLAG_AE) != 0) {
mMeteringPointsAe.add(point);
}
- if ((mode & MeteringMode.AWB) != 0) {
+ if ((mode & FLAG_AWB) != 0) {
mMeteringPointsAwb.add(point);
}
return this;
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
index 321c26a..d64bb26 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
@@ -71,11 +71,52 @@
*
* <p>The application is responsible for calling {@link ImageProxy#close()} to close the image.
* Failing to close the image will cause future images to be stalled or dropped depending on the
- * {@link BackpressureStrategy}.
+ * backpressure strategy.
*/
public final class ImageAnalysis extends UseCase {
/**
+ * Only deliver the latest image to the analyzer, dropping images as they arrive.
+ *
+ * <p>This strategy ignores the value set by {@link Builder#setImageQueueDepth(int)}.
+ * Only one image will be delivered for analysis at a time. If more images are produced
+ * while that image is being analyzed, they will be dropped and not queued for delivery.
+ * Once the image being analyzed is closed by calling {@link ImageProxy#close()}, the
+ * next latest image will be delivered.
+ *
+ * <p>Internally this strategy may make use of an internal {@link Executor} to receive
+ * and drop images from the producer. A performance-tuned executor will be created
+ * internally unless one is explicitly provided by
+ * {@link Builder#setBackgroundExecutor(Executor)}. In order to
+ * ensure smooth operation of this backpressure strategy, any user supplied
+ * {@link Executor} must be able to quickly respond to tasks posted to it, so setting
+ * the executor manually should only be considered in advanced use cases.
+ *
+ * @see Builder#setBackgroundExecutor(Executor)
+ */
+ public static final int STRATEGY_KEEP_ONLY_LATEST = 0;
+ /**
+ * Block the producer from generating new images.
+ *
+ * <p>Once the producer has produced the number of images equal to the image queue depth,
+ * and none have been closed, the producer will stop producing images. Note that images
+ * may be queued internally and not be delivered to the analyzer until the last delivered
+ * image has been closed with {@link ImageProxy#close()}. These internally queued images
+ * will count towards the total number of images that the producer can provide at any one
+ * time.
+ *
+ * <p>When the producer stops producing images, it may also stop producing images for
+ * other use cases, such as {@link Preview}, so it is important for the analyzer to keep
+ * up with frame rate, <i>on average</i>. Failure to keep up with frame rate may lead to
+ * jank in the frame stream and a diminished user experience. If more time is needed for
+ * analysis on <i>some</i> frames, consider increasing the image queue depth with
+ * {@link Builder#setImageQueueDepth(int)}.
+ *
+ * @see Builder#setImageQueueDepth(int)
+ */
+ public static final int STRATEGY_BLOCK_PRODUCER = 1;
+
+ /**
* Provides a static configuration with implementation-agnostic options.
*
* @hide
@@ -113,7 +154,7 @@
ImageAnalysisConfig combinedConfig = (ImageAnalysisConfig) getUseCaseConfig();
setImageFormat(ImageReaderFormatRecommender.chooseCombo().imageAnalysisFormat());
- if (combinedConfig.getBackpressureStrategy() == BackpressureStrategy.BLOCK_PRODUCER) {
+ if (combinedConfig.getBackpressureStrategy() == STRATEGY_BLOCK_PRODUCER) {
mImageAnalysisAbstractAnalyzer = new ImageAnalysisBlockingAnalyzer();
} else {
mImageAnalysisAbstractAnalyzer = new ImageAnalysisNonBlockingAnalyzer(
@@ -130,7 +171,7 @@
CameraXExecutors.highPriorityExecutor());
int imageQueueDepth =
- config.getBackpressureStrategy() == BackpressureStrategy.BLOCK_PRODUCER
+ config.getBackpressureStrategy() == STRATEGY_BLOCK_PRODUCER
? config.getImageQueueDepth() : NON_BLOCKING_IMAGE_DEPTH;
mImageReader =
@@ -389,51 +430,13 @@
* by calling {@link ImageProxy#close()}. However, the image will only be valid when the
* ImageAnalysis instance is bound to a camera.
*
+ * @hide
* @see Builder#setBackpressureStrategy(int)
*/
- @IntDef({BackpressureStrategy.KEEP_ONLY_LATEST, BackpressureStrategy.BLOCK_PRODUCER})
+ @IntDef({STRATEGY_KEEP_ONLY_LATEST, STRATEGY_BLOCK_PRODUCER})
@Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(Scope.LIBRARY_GROUP)
public @interface BackpressureStrategy {
- /**
- * Only deliver the latest image to the analyzer, dropping images as they arrive.
- *
- * <p>This strategy ignores the value set by {@link Builder#setImageQueueDepth(int)}.
- * Only one image will be delivered for analysis at a time. If more images are produced
- * while that image is being analyzed, they will be dropped and not queued for delivery.
- * Once the image being analyzed is closed by calling {@link ImageProxy#close()}, the
- * next latest image will be delivered.
- *
- * <p>Internally this strategy may make use of an internal {@link Executor} to receive
- * and drop images from the producer. A performance-tuned executor will be created
- * internally unless one is explicitly provided by
- * {@link Builder#setBackgroundExecutor(Executor)}. In order to
- * ensure smooth operation of this backpressure strategy, any user supplied
- * {@link Executor} must be able to quickly respond to tasks posted to it, so setting
- * the executor manually should only be considered in advanced use cases.
- *
- * @see Builder#setBackgroundExecutor(Executor)
- */
- int KEEP_ONLY_LATEST = 0;
- /**
- * Block the producer from generating new images.
- *
- * <p>Once the producer has produced the number of images equal to the image queue depth,
- * and none have been closed, the producer will stop producing images. Note that images
- * may be queued internally and not be delivered to the analyzer until the last delivered
- * image has been closed with {@link ImageProxy#close()}. These internally queued images
- * will count towards the total number of images that the producer can provide at any one
- * time.
- *
- * <p>When the producer stops producing images, it may also stop producing images for
- * other use cases, such as {@link Preview}, so it is important for the analyzer to keep
- * up with frame rate, <i>on average</i>. Failure to keep up with frame rate may lead to
- * jank in the frame stream and a diminished user experience. If more time is needed for
- * analysis on <i>some</i> frames, consider increasing the image queue depth with
- * {@link Builder#setImageQueueDepth(int)}.
- *
- * @see Builder#setImageQueueDepth(int)
- */
- int BLOCK_PRODUCER = 1;
}
/**
@@ -453,7 +456,7 @@
* <p>It is the responsibility of the application to close the image once done with it.
* If the images are not closed then it may block further images from being produced
* (causing the preview to stall) or drop images as determined by the configured
- * {@link ImageAnalysis.BackpressureStrategy}. The exact behavior is configurable via
+ * backpressure strategy. The exact behavior is configurable via
* {@link ImageAnalysis.Builder#setBackpressureStrategy(int)}.
*
* <p>Images produced here will no longer be valid after the {@link ImageAnalysis}
@@ -496,8 +499,7 @@
@RestrictTo(Scope.LIBRARY_GROUP)
public static final class Defaults implements ConfigProvider<ImageAnalysisConfig> {
@BackpressureStrategy
- private static final int DEFAULT_BACKPRESSURE_STRATEGY =
- BackpressureStrategy.KEEP_ONLY_LATEST;
+ private static final int DEFAULT_BACKPRESSURE_STRATEGY = STRATEGY_KEEP_ONLY_LATEST;
private static final int DEFAULT_IMAGE_QUEUE_DEPTH = 6;
private static final Size DEFAULT_TARGET_RESOLUTION = new Size(640, 480);
private static final Size DEFAULT_MAX_RESOLUTION = new Size(1920, 1080);
@@ -570,11 +572,11 @@
* Sets the backpressure strategy to apply to the image producer to deal with scenarios
* where images may be produced faster than they can be analyzed.
*
- * <p>The available values are {@link BackpressureStrategy#BLOCK_PRODUCER} and {@link
- * BackpressureStrategy#KEEP_ONLY_LATEST}.
+ * <p>The available values are {@link #STRATEGY_BLOCK_PRODUCER} and
+ * {@link #STRATEGY_KEEP_ONLY_LATEST}.
*
* <p>If not set, the backpressure strategy will default to
- * {@link BackpressureStrategy#KEEP_ONLY_LATEST}.
+ * {@link #STRATEGY_KEEP_ONLY_LATEST}.
*
* @param strategy The strategy to use.
* @return The current Builder.
@@ -587,24 +589,24 @@
/**
* Sets the number of images available to the camera pipeline for
- * {@link BackpressureStrategy#BLOCK_PRODUCER} mode.
+ * {@link #STRATEGY_BLOCK_PRODUCER} mode.
*
* <p>The image queue depth is the number of images available to the camera to fill with
* data. This includes the image currently being analyzed by {@link
* ImageAnalysis.Analyzer#analyze(ImageProxy, int)}. Increasing the image queue depth
- * may make camera operation smoother, depending on the {@link BackpressureStrategy}, at
+ * may make camera operation smoother, depending on the backpressure strategy, at
* the cost of increased memory usage.
*
- * <p>When the {@link BackpressureStrategy} is set to
- * {@link BackpressureStrategy#BLOCK_PRODUCER}, increasing the image queue depth may make
- * the camera pipeline run smoother on systems under high load. However, the time spent
- * analyzing an image should still be kept under a single frame period for the current
- * frame rate, <i>on average</i>, to avoid stalling the camera pipeline.
+ * <p>When the backpressure strategy is set to {@link #STRATEGY_BLOCK_PRODUCER},
+ * increasing the image queue depth may make the camera pipeline run smoother on systems
+ * under high load. However, the time spent analyzing an image should still be kept under
+ * a single frame period for the current frame rate, <i>on average</i>, to avoid stalling
+ * the camera pipeline.
*
- * <p>The value only applies to {@link BackpressureStrategy#BLOCK_PRODUCER} mode.
- * For {@link BackpressureStrategy#KEEP_ONLY_LATEST} the value is ignored.
+ * <p>The value only applies to {@link #STRATEGY_BLOCK_PRODUCER} mode.
+ * For {@link #STRATEGY_KEEP_ONLY_LATEST} the value is ignored.
*
- * <p>If not set, and this option is used by the selected {@link BackpressureStrategy},
+ * <p>If not set, and this option is used by the selected backpressure strategy,
* the default will be a queue depth of 6 images.
*
* @param depth The total number of images available to the camera.
@@ -641,7 +643,7 @@
}
/**
- * Builds an immutable {@link ImageAnalysis} from the current state.
+ * Builds an {@link ImageAnalysis} from the current state.
*
* @return A {@link ImageAnalysis} populated with the current state.
* @throws IllegalArgumentException if attempting to set both target aspect ratio and
@@ -714,7 +716,7 @@
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
@NonNull
- public Builder setLensFacing(@LensFacing int lensFacing) {
+ public Builder setLensFacing(@CameraSelector.LensFacing int lensFacing) {
getMutableConfig().insertOption(OPTION_LENS_FACING, lensFacing);
return this;
}
@@ -793,7 +795,7 @@
*/
@NonNull
@Override
- public Builder setTargetAspectRatio(@AspectRatio int aspectRatio) {
+ public Builder setTargetAspectRatio(@AspectRatio.Ratio int aspectRatio) {
getMutableConfig().insertOption(OPTION_TARGET_ASPECT_RATIO, aspectRatio);
return this;
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisConfig.java
index 6b1ec8d..c97b311 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysisConfig.java
@@ -65,8 +65,8 @@
* Retrieves the backpressure strategy applied to the image producer to deal with scenarios
* where images may be produced faster than they can be analyzed.
*
- * <p>The available values are {@link BackpressureStrategy#BLOCK_PRODUCER} and {@link
- * BackpressureStrategy#KEEP_ONLY_LATEST}.
+ * <p>The available values are {@link BackpressureStrategy#STRATEGY_BLOCK_PRODUCER} and {@link
+ * BackpressureStrategy#STRATEGY_KEEP_ONLY_LATEST}.
*
* @param valueIfMissing The value to return if this configuration option has not been set.
* @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
@@ -81,8 +81,8 @@
/**
* Returns the mode that the image is acquired from {@link ImageReader}.
*
- * <p>The available values are {@link BackpressureStrategy#BLOCK_PRODUCER} and {@link
- * BackpressureStrategy#KEEP_ONLY_LATEST}.
+ * <p>The available values are {@link BackpressureStrategy#STRATEGY_BLOCK_PRODUCER} and {@link
+ * BackpressureStrategy#STRATEGY_KEEP_ONLY_LATEST}.
*
* @return The stored value, if it exists in this configuration.
* @throws IllegalArgumentException if the option does not exist in this configuration.
@@ -250,7 +250,7 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return retrieveOption(OPTION_LENS_FACING);
}
@@ -334,7 +334,7 @@
* @return The stored value, if it exists in this configuration.
* @throws IllegalArgumentException if the option does not exist in this configuration.
*/
- @AspectRatio
+ @AspectRatio.Ratio
@Override
public int getTargetAspectRatio() {
return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index 7ed111d..42f3d67 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -117,6 +117,55 @@
public class ImageCapture extends UseCase {
/**
+ * An unknown error occurred.
+ *
+ * <p>See message parameter in onError callback or log for more details.
+ */
+ public static final int ERROR_UNKNOWN = 0;
+ /**
+ * An error occurred while attempting to read or write a file, such as when saving an image
+ * to a File.
+ */
+ public static final int ERROR_FILE_IO = 1;
+
+ /**
+ * An error reported by camera framework indicating the capture request is failed.
+ */
+ public static final int ERROR_CAPTURE_FAILED = 2;
+
+ /**
+ * An error indicating the request cannot be done due to camera is closed.
+ */
+ public static final int ERROR_CAMERA_CLOSED = 3;
+
+ /**
+ * An error indicating this ImageCapture is not bound to a valid camera.
+ */
+ public static final int ERROR_INVALID_CAMERA = 4;
+
+ /**
+ * Optimizes capture pipeline to prioritize image quality over latency. When the capture
+ * mode is set to MAX_QUALITY, images may take longer to capture.
+ */
+ public static final int CAPTURE_MODE_MAXIMIZE_QUALITY = 0;
+ /**
+ * Optimizes capture pipeline to prioritize latency over image quality. When the capture
+ * mode is set to MIN_LATENCY, images may capture faster but the image quality may be
+ * reduced.
+ */
+ public static final int CAPTURE_MODE_MINIMIZE_LATENCY = 1;
+
+ /**
+ * Auto flash. The flash will be used according to the camera system's determination when taking
+ * a picture.
+ */
+ public static final int FLASH_MODE_AUTO = 0;
+ /** Always flash. The flash will always be used when taking a picture. */
+ public static final int FLASH_MODE_ON = 1;
+ /** No flash. The flash will never be used when taking a picture. */
+ public static final int FLASH_MODE_OFF = 2;
+
+ /**
* Provides a static configuration with implementation-agnostic options.
*
* @hide
@@ -229,9 +278,9 @@
mIoExecutor = mConfig.getIoExecutor(CameraXExecutors.ioExecutor());
- if (mCaptureMode == CaptureMode.MAXIMIZE_QUALITY) {
+ if (mCaptureMode == CAPTURE_MODE_MAXIMIZE_QUALITY) {
mEnableCheck3AConverged = true; // check 3A convergence in MAX_QUALITY mode
- } else if (mCaptureMode == CaptureMode.MINIMIZE_LATENCY) {
+ } else if (mCaptureMode == CAPTURE_MODE_MINIMIZE_LATENCY) {
mEnableCheck3AConverged = false; // skip 3A convergence in MIN_LATENCY mode
}
@@ -387,7 +436,7 @@
/**
* Get the flash mode.
*
- * @return the {@link FlashMode}.
+ * @return the flashMode.
*/
@FlashMode
public int getFlashMode() {
@@ -397,17 +446,16 @@
/**
* Set the flash mode.
*
- * <p>The flash control for the subsequent photo capture requests. See
- * {@link FlashMode} for the optional settings. Applications can check if there is a flash unit
- * via {@link CameraInfo#hasFlashUnit()} and update UI component if necessary. If there is no
- * flash unit, then calling this API will take no effect for the subsequent photo capture
- * requests and they will act like {@link FlashMode#OFF}.
+ * <p>The flash control for the subsequent photo capture requests. Applications can check if
+ * there is a flash unit via {@link CameraInfo#hasFlashUnit()} and update UI component if
+ * necessary. If there is no flash unit, then calling this API will take no effect for the
+ * subsequent photo capture requests and they will act like {@link #FLASH_MODE_OFF}.
*
* <p>When the torch is enabled via {@link CameraControl#enableTorch(boolean)}, the torch
- * will remain enabled during photo capture regardless of {@link FlashMode} setting. When
+ * will remain enabled during photo capture regardless of flashMode setting. When
* the torch is disabled, flash will function as specified by {@link #setFlashMode(int)}.
*
- * @param flashMode the {@link FlashMode}.
+ * @param flashMode the flash mode.
*/
public void setFlashMode(@FlashMode int flashMode) {
this.mFlashMode = flashMode;
@@ -517,12 +565,13 @@
* Captures a new still image and saves to a file.
*
* <p>The listener's callback will be called only once for every invocation of this method.
+ *
* @param saveLocation Location to store the newly captured image.
* @param executor The executor in which the listener callback methods will be run.
* @param imageSavedCallback Callback to be called for the newly captured image.
- * Maybe remove after https://issuetracker.google.com/135275901
- * Todo: b/145130873 - Methods accepting `File` should also accept `FileDescriptor` or streams
*/
+ // Maybe remove after https://issuetracker.google.com/135275901
+ // Todo: b/145130873 - Methods accepting `File` should also accept `FileDescriptor` or streams
@SuppressLint({"LambdaLast", "StreamFiles"})
public void takePicture(@NonNull File saveLocation,
@NonNull Executor executor,
@@ -543,9 +592,9 @@
* be included in the EXIF.
* @param executor The executor in which the callback methods will be run.
* @param imageSavedCallback Callback to be called for the newly captured image.
- * Maybe remove after https://issuetracker.google.com/135275901
- * Todo: b/145130873 - Methods accepting `File` should also accept `FileDescriptor` or streams
*/
+ // Maybe remove after https://issuetracker.google.com/135275901
+ // Todo: b/145130873 - Methods accepting `File` should also accept `FileDescriptor` or streams
@SuppressLint({"LambdaLast", "StreamFiles"})
public void takePicture(
final @NonNull File saveLocation,
@@ -585,12 +634,12 @@
}
@Override
- public void onError(@ImageSaver.SaveError int error, String message,
+ public void onError(ImageSaver.SaveError error, String message,
@Nullable Throwable cause) {
- @ImageCaptureError int imageCaptureError = ImageCaptureError.UNKNOWN_ERROR;
+ @ImageCaptureError int imageCaptureError = ERROR_UNKNOWN;
switch (error) {
- case ImageSaver.SaveError.FILE_IO_FAILED:
- imageCaptureError = ImageCaptureError.FILE_IO_ERROR;
+ case FILE_IO_FAILED:
+ imageCaptureError = ERROR_FILE_IO;
break;
default:
// Keep the imageCaptureError as UNKNOWN_ERROR
@@ -668,7 +717,7 @@
cameraId = getBoundCameraId();
} catch (Throwable e) {
// Not bound. Notify callback.
- callback.onError(ImageCaptureError.INVALID_CAMERA,
+ callback.onError(ERROR_INVALID_CAMERA,
"Not bound to a valid Camera [" + ImageCapture.this + "]", e);
return;
}
@@ -757,11 +806,11 @@
@ImageCaptureError
int getError(Throwable throwable) {
if (throwable instanceof CameraClosedException) {
- return ImageCaptureError.CAMERA_CLOSED;
+ return ERROR_CAMERA_CLOSED;
} else if (throwable instanceof CaptureFailedException) {
- return ImageCaptureError.CAPTURE_FAILED;
+ return ERROR_CAPTURE_FAILED;
} else {
- return ImageCaptureError.UNKNOWN_ERROR;
+ return ERROR_UNKNOWN;
}
}
@@ -877,7 +926,7 @@
// If app is in min-latency mode and flash ALWAYS/OFF mode, it can still take picture without
// checking the capture result. Remove this check once no repeating surface issue is fixed.
private ListenableFuture<CameraCaptureResult> getPreCaptureStateIfNeeded() {
- if (mEnableCheck3AConverged || getFlashMode() == FlashMode.AUTO) {
+ if (mEnableCheck3AConverged || getFlashMode() == FLASH_MODE_AUTO) {
return mSessionCallbackChecker.checkCaptureResult(
new CaptureCallbackChecker.CaptureResultChecker<CameraCaptureResult>() {
@Override
@@ -892,11 +941,11 @@
boolean isFlashRequired(TakePictureState state) {
switch (getFlashMode()) {
- case FlashMode.ON:
+ case FLASH_MODE_ON:
return true;
- case FlashMode.AUTO:
+ case FLASH_MODE_AUTO:
return state.mPreCaptureState.getAeState() == AeState.FLASH_REQUIRED;
- case FlashMode.OFF:
+ case FLASH_MODE_OFF:
return false;
}
throw new AssertionError(getFlashMode());
@@ -1109,58 +1158,47 @@
*
* <p>This is a parameter sent to the error callback functions set in listeners such as {@link
* ImageCapture.OnImageSavedCallback#onError(int, String, Throwable)}.
+ *
+ * @hide
*/
- @IntDef({ImageCaptureError.UNKNOWN_ERROR, ImageCaptureError.FILE_IO_ERROR,
- ImageCaptureError.CAPTURE_FAILED, ImageCaptureError.CAMERA_CLOSED,
- ImageCaptureError.INVALID_CAMERA})
+ @IntDef({ERROR_UNKNOWN, ERROR_FILE_IO, ERROR_CAPTURE_FAILED, ERROR_CAMERA_CLOSED,
+ ERROR_INVALID_CAMERA})
@Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(Scope.LIBRARY_GROUP)
public @interface ImageCaptureError {
- /**
- * An unknown error occurred.
- *
- * <p>See message parameter in onError callback or log for more details.
- */
- int UNKNOWN_ERROR = 0;
- /**
- * An error occurred while attempting to read or write a file, such as when saving an image
- * to a File.
- */
- int FILE_IO_ERROR = 1;
-
- /**
- * An error reported by camera framework indicating the capture request is failed.
- */
- int CAPTURE_FAILED = 2;
-
- /**
- * An error indicating the request cannot be done due to camera is closed.
- */
- int CAMERA_CLOSED = 3;
-
- /**
- * An error indicating this ImageCapture is not bound to a valid camera.
- */
- int INVALID_CAMERA = 4;
}
/**
* Capture mode options for ImageCapture. A picture will always be taken regardless of
* mode, and the mode will be used on devices that support it.
+ *
+ * @hide
*/
- @IntDef({CaptureMode.MAXIMIZE_QUALITY, CaptureMode.MINIMIZE_LATENCY})
+ @IntDef({CAPTURE_MODE_MAXIMIZE_QUALITY, CAPTURE_MODE_MINIMIZE_LATENCY})
@Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(Scope.LIBRARY_GROUP)
public @interface CaptureMode {
- /**
- * Optimizes capture pipeline to prioritize image quality over latency. When the capture
- * mode is set to MAX_QUALITY, images may take longer to capture.
- */
- int MAXIMIZE_QUALITY = 0;
- /**
- * Optimizes capture pipeline to prioritize latency over image quality. When the capture
- * mode is set to MIN_LATENCY, images may capture faster but the image quality may be
- * reduced.
- */
- int MINIMIZE_LATENCY = 1;
+ }
+
+ /**
+ * The flash mode options when taking a picture using ImageCapture.
+ *
+ * <p>Applications can check if there is a flash unit via {@link CameraInfo#hasFlashUnit()} and
+ * update UI component if necessary. If there is no flash unit, then the FlashMode set to
+ * {@link #setFlashMode(int)} will take no effect for the subsequent photo capture requests
+ * and they will act like {@link #FLASH_MODE_OFF}.
+ *
+ * <p>When the torch is enabled via {@link CameraControl#enableTorch(boolean)}, the torch
+ * will remain enabled during photo capture regardless of flash mode setting. When
+ * the torch is disabled, flash will function as specified by
+ * {@link #setFlashMode(int)}.
+ *
+ * @hide
+ */
+ @IntDef({FLASH_MODE_AUTO, FLASH_MODE_ON, FLASH_MODE_OFF})
+ @Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public @interface FlashMode {
}
/** Listener containing callbacks for image file I/O events. */
@@ -1169,8 +1207,8 @@
* Called when an image has been successfully saved.
*
* @param file The file object which the image is saved to
- * Todo: b/145130873 - Methods accepting `File` should also accept `FileDescriptor`
*/
+ // Todo: b/145130873 - Methods accepting `File` should also accept `FileDescriptor`
@SuppressLint("StreamFiles")
void onImageSaved(@NonNull File file);
@@ -1251,9 +1289,9 @@
public static final class Defaults
implements ConfigProvider<ImageCaptureConfig> {
@CaptureMode
- private static final int DEFAULT_CAPTURE_MODE = CaptureMode.MINIMIZE_LATENCY;
+ private static final int DEFAULT_CAPTURE_MODE = CAPTURE_MODE_MINIMIZE_LATENCY;
@FlashMode
- private static final int DEFAULT_FLASH_MODE = FlashMode.OFF;
+ private static final int DEFAULT_FLASH_MODE = FLASH_MODE_OFF;
private static final int DEFAULT_SURFACE_OCCUPANCY_PRIORITY = 4;
private static final ImageCaptureConfig DEFAULT_CONFIG;
@@ -1638,11 +1676,14 @@
/**
* Sets the image capture mode.
*
- * <p>Valid capture modes are {@link CaptureMode#MINIMIZE_LATENCY}, which prioritizes
- * latency over image quality, or {@link CaptureMode#MAXIMIZE_QUALITY}, which prioritizes
+ * <p>Valid capture modes are {@link CaptureMode#CAPTURE_MODE_MINIMIZE_LATENCY}, which
+ * prioritizes
+ * latency over image quality, or {@link CaptureMode#CAPTURE_MODE_MAXIMIZE_QUALITY},
+ * which prioritizes
* image quality over latency.
*
- * <p>If not set, the capture mode will default to {@link CaptureMode#MINIMIZE_LATENCY}.
+ * <p>If not set, the capture mode will default to
+ * {@link CaptureMode#CAPTURE_MODE_MINIMIZE_LATENCY}.
*
* @param captureMode The requested image capture mode.
* @return The current Builder.
@@ -1654,9 +1695,9 @@
}
/**
- * Sets the {@link FlashMode}.
+ * Sets the flashMode.
*
- * <p>If not set, the flash mode will default to {@link FlashMode#OFF}.
+ * <p>If not set, the flash mode will default to {@link #FLASH_MODE_OFF}.
*
* <p>See {@link ImageCapture#setFlashMode(int)} for more information.
*
@@ -1794,7 +1835,7 @@
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
@NonNull
- public Builder setLensFacing(@LensFacing int lensFacing) {
+ public Builder setLensFacing(@CameraSelector.LensFacing int lensFacing) {
getMutableConfig().insertOption(OPTION_LENS_FACING, lensFacing);
return this;
}
@@ -1878,7 +1919,7 @@
*/
@NonNull
@Override
- public Builder setTargetAspectRatio(@AspectRatio int aspectRatio) {
+ public Builder setTargetAspectRatio(@AspectRatio.Ratio int aspectRatio) {
getMutableConfig().insertOption(OPTION_TARGET_ASPECT_RATIO, aspectRatio);
return this;
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureConfig.java
index 2ec8281..e960f13f 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureConfig.java
@@ -52,7 +52,7 @@
Option.create(
"camerax.core.imageCapture.captureMode", int.class);
static final Option<Integer> OPTION_FLASH_MODE =
- Option.create("camerax.core.imageCapture.flashMode", FlashMode.class);
+ Option.create("camerax.core.imageCapture.flashMode", int.class);
static final Option<CaptureBundle> OPTION_CAPTURE_BUNDLE =
Option.create("camerax.core.imageCapture.captureBundle", CaptureBundle.class);
static final Option<CaptureProcessor> OPTION_CAPTURE_PROCESSOR =
@@ -93,12 +93,12 @@
}
/**
- * Returns the {@link FlashMode}.
+ * Returns the {@link ImageCapture.FlashMode}.
*
* @return The stored value, if it exists in this configuration.
* @throws IllegalArgumentException if the option does not exist in this configuration.
*/
- @FlashMode
+ @ImageCapture.FlashMode
public int getFlashMode() {
return retrieveOption(OPTION_FLASH_MODE);
}
@@ -338,7 +338,7 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return retrieveOption(OPTION_LENS_FACING);
}
@@ -422,7 +422,7 @@
* @return The stored value, if it exists in this configuration.
* @throws IllegalArgumentException if the option does not exist in this configuration.
*/
- @AspectRatio
+ @AspectRatio.Ratio
@Override
public int getTargetAspectRatio() {
return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageOutputConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageOutputConfig.java
index 68431fa..99f6f1f 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageOutputConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageOutputConfig.java
@@ -157,7 +157,7 @@
* @return The stored value, if it exists in this configuration.
* @throws IllegalArgumentException if the option does not exist in this configuration.
*/
- @AspectRatio
+ @AspectRatio.Ratio
int getTargetAspectRatio();
/**
@@ -331,7 +331,7 @@
* @return The current Builder.
*/
@NonNull
- B setTargetAspectRatio(@AspectRatio int aspectRatio);
+ B setTargetAspectRatio(@AspectRatio.Ratio int aspectRatio);
/**
* Sets the rotation of the intended target for images from this configuration.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java
index 8500ce9..59d8ba4 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java
@@ -18,19 +18,17 @@
import android.location.Location;
-import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.camera.core.ImageUtil.CodecFailedException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
final class ImageSaver implements Runnable {
private static final String TAG = "ImageSaver";
+
@Nullable
private final Location mLocation;
// The image that was captured
@@ -71,7 +69,7 @@
@Override
public void run() {
// Finally, we save the file to disk
- Integer saveError = null;
+ SaveError saveError = null;
String errorMessage = null;
Exception exception = null;
try (ImageProxy imageToClose = mImage;
@@ -131,7 +129,7 @@
});
}
- private void postError(final @SaveError int saveError, final String message,
+ private void postError(SaveError saveError, final String message,
@Nullable final Throwable cause) {
mExecutor.execute(new Runnable() {
@Override
@@ -142,23 +140,20 @@
}
/** Type of error that occurred during save */
- @IntDef({SaveError.FILE_IO_FAILED, SaveError.ENCODE_FAILED, SaveError.CROP_FAILED,
- SaveError.UNKNOWN})
- @Retention(RetentionPolicy.SOURCE)
- public @interface SaveError {
+ public enum SaveError {
/** Failed to write to or close the file */
- int FILE_IO_FAILED = 0;
+ FILE_IO_FAILED,
/** Failure when attempting to encode image */
- int ENCODE_FAILED = 1;
+ ENCODE_FAILED,
/** Failure when attempting to crop image */
- int CROP_FAILED = 2;
- int UNKNOWN = 3;
+ CROP_FAILED,
+ UNKNOWN
}
public interface OnImageSavedCallback {
void onImageSaved(File file);
- void onError(@SaveError int saveError, String message, @Nullable Throwable cause);
+ void onError(SaveError saveError, String message, @Nullable Throwable cause);
}
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/LensFacing.java b/camera/camera-core/src/main/java/androidx/camera/core/LensFacing.java
deleted file mode 100644
index af6c7be9..0000000
--- a/camera/camera-core/src/main/java/androidx/camera/core/LensFacing.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.core;
-
-import androidx.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** The direction the camera faces relative to device screen. */
-@IntDef({LensFacing.FRONT, LensFacing.BACK})
-@Retention(RetentionPolicy.SOURCE)
-public @interface LensFacing {
- /** A camera on the device facing the same direction as the device's screen. */
- int FRONT = 0;
- /** A camera on the device facing the opposite direction as the device's screen. */
- int BACK = 1;
-}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/LensFacingCameraIdFilter.java b/camera/camera-core/src/main/java/androidx/camera/core/LensFacingCameraIdFilter.java
index 99de048..9a3ba7e 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/LensFacingCameraIdFilter.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/LensFacingCameraIdFilter.java
@@ -28,10 +28,10 @@
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class LensFacingCameraIdFilter implements CameraIdFilter {
- @LensFacing
+ @CameraSelector.LensFacing
private int mLensFacing;
- public LensFacingCameraIdFilter(@LensFacing int lensFacing) {
+ public LensFacingCameraIdFilter(@CameraSelector.LensFacing int lensFacing) {
mLensFacing = lensFacing;
}
@@ -44,7 +44,7 @@
}
/** Returns the lens facing associated with this lens facing camera id filter. */
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return mLensFacing;
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/LensFacingConverter.java b/camera/camera-core/src/main/java/androidx/camera/core/LensFacingConverter.java
index 66686b0..3f77fcb 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/LensFacingConverter.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/LensFacingConverter.java
@@ -21,7 +21,7 @@
import androidx.annotation.RestrictTo;
/**
- * Helper class that defines certain enum-like methods for {@link LensFacing}
+ * Helper class that defines certain enum-like methods for {@link CameraSelector.LensFacing}
*
* @hide
*/
@@ -32,21 +32,21 @@
}
/**
- * @return an array containing the constants of {@link LensFacing} in the order they're
- * declared.
+ * @return an array containing the constants of {@link CameraSelector.LensFacing} in the
+ * order they're declared.
*/
@NonNull
public static Integer[] values() {
- return new Integer[]{LensFacing.FRONT, LensFacing.BACK};
+ return new Integer[]{CameraSelector.LENS_FACING_FRONT, CameraSelector.LENS_FACING_BACK};
}
/**
- * Returns the {@link LensFacing} constant for the specified name
+ * Returns the {@link CameraSelector.LensFacing} constant for the specified name
*
- * @param name The name of the {@link LensFacing} to return
- * @return The {@link LensFacing} constant for the specified name
+ * @param name The name of the {@link CameraSelector.LensFacing} to return
+ * @return The {@link CameraSelector.LensFacing} constant for the specified name
*/
- @LensFacing
+ @CameraSelector.LensFacing
public static int valueOf(@Nullable final String name) {
if (name == null) {
throw new NullPointerException("name cannot be null");
@@ -54,26 +54,27 @@
switch (name) {
case "FRONT":
- return LensFacing.FRONT;
+ return CameraSelector.LENS_FACING_FRONT;
case "BACK":
- return LensFacing.BACK;
+ return CameraSelector.LENS_FACING_BACK;
default:
throw new IllegalArgumentException("Unknown len facing name " + name);
}
}
/**
- * Returns the name of the {@link LensFacing} constant, exactly as it is declared.
+ * Returns the name of the {@link CameraSelector.LensFacing} constant, exactly as it is
+ * declared.
*
- * @param lensFacing A {@link LensFacing} constant
- * @return The name of the {@link LensFacing} constant.
+ * @param lensFacing A {@link CameraSelector.LensFacing} constant
+ * @return The name of the {@link CameraSelector.LensFacing} constant.
*/
@NonNull
- public static String nameOf(@LensFacing final int lensFacing) {
+ public static String nameOf(@CameraSelector.LensFacing final int lensFacing) {
switch (lensFacing) {
- case LensFacing.FRONT:
+ case CameraSelector.LENS_FACING_FRONT:
return "FRONT";
- case LensFacing.BACK:
+ case CameraSelector.LENS_FACING_BACK:
return "BACK";
default:
throw new IllegalArgumentException("Unknown lens facing " + lensFacing);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
index 2df8769..d082b87 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
@@ -470,7 +470,7 @@
* public void onFailure(Throwable t) {
* // Should never fail
* }
- * }, CameraXExecutors.directExecutor());
+ * }, Executors.newSingleThreadExecutor());
*
* return surfaceFuture;
* }
@@ -655,7 +655,7 @@
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
@NonNull
- public Builder setLensFacing(@LensFacing int lensFacing) {
+ public Builder setLensFacing(@CameraSelector.LensFacing int lensFacing) {
getMutableConfig().insertOption(OPTION_LENS_FACING, lensFacing);
return this;
}
@@ -738,7 +738,7 @@
*/
@NonNull
@Override
- public Builder setTargetAspectRatio(@AspectRatio int aspectRatio) {
+ public Builder setTargetAspectRatio(@AspectRatio.Ratio int aspectRatio) {
getMutableConfig().insertOption(OPTION_TARGET_ASPECT_RATIO, aspectRatio);
return this;
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/PreviewConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/PreviewConfig.java
index 86e126f..2e49101 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/PreviewConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/PreviewConfig.java
@@ -188,7 +188,7 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return retrieveOption(OPTION_LENS_FACING);
}
@@ -272,7 +272,7 @@
* @return The stored value, if it exists in this configuration.
* @throws IllegalArgumentException if the option does not exist in this configuration.
*/
- @AspectRatio
+ @AspectRatio.Ratio
@Override
public int getTargetAspectRatio() {
return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/TorchState.java b/camera/camera-core/src/main/java/androidx/camera/core/TorchState.java
index 5b5462da..b91b28d 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/TorchState.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/TorchState.java
@@ -17,16 +17,27 @@
package androidx.camera.core;
import androidx.annotation.IntDef;
+import androidx.annotation.RestrictTo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** The camera flash torch state. */
-@IntDef({TorchState.OFF, TorchState.ON})
-@Retention(RetentionPolicy.SOURCE)
-public @interface TorchState {
+public class TorchState {
/** Torch is off. */
- int OFF = 0;
+ public static final int OFF = 0;
/** Torch is on. */
- int ON = 1;
+ public static final int ON = 1;
+
+ private TorchState() {
+ }
+
+ /**
+ * @hide
+ */
+ @IntDef({OFF, ON})
+ @Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public @interface State {
+ }
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
index d7e738e..00464f2 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
@@ -109,8 +109,7 @@
* the pre-populated builder. If <code>null</code> is returned, then the user-supplied
* configuration will be used directly.
*
- * @param lensFacing The {@link androidx.camera.core.LensFacing} that the default builder
- * will target to.
+ * @param lensFacing The lensFacing that the default builder will target to.
* @return A builder pre-populated with use case default options.
* @hide
*/
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
index 79844b7..0a0f265 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
@@ -68,6 +68,24 @@
public class VideoCapture extends UseCase {
/**
+ * An unknown error occurred.
+ *
+ * <p>See message parameter in onError callback or log for more details.
+ */
+ public static final int ERROR_UNKNOWN = 0;
+ /**
+ * An error occurred with encoder state, either when trying to change state or when an
+ * unexpected state change occurred.
+ */
+ public static final int ERROR_ENCODER = 1;
+ /** An error with muxer state such as during creation or when stopping. */
+ public static final int ERROR_MUXER = 2;
+ /**
+ * An error indicating start recording was called when video recording is still in progress.
+ */
+ public static final int ERROR_RECORDING_IN_PROGRESS = 3;
+
+ /**
* Provides a static configuration with implementation-agnostic options.
*
* @hide
@@ -269,7 +287,7 @@
if (!mEndOfAudioVideoSignal.get()) {
postListener.onError(
- VideoCaptureError.RECORDING_IN_PROGRESS, "It is still in video recording!",
+ ERROR_RECORDING_IN_PROGRESS, "It is still in video recording!",
null);
return;
}
@@ -278,7 +296,7 @@
// audioRecord start
mAudioRecorder.startRecording();
} catch (IllegalStateException e) {
- postListener.onError(VideoCaptureError.ENCODER_ERROR, "AudioRecorder start fail", e);
+ postListener.onError(ERROR_ENCODER, "AudioRecorder start fail", e);
return;
}
@@ -294,7 +312,7 @@
} catch (IllegalStateException e) {
setupEncoder(cameraId, resolution);
- postListener.onError(VideoCaptureError.ENCODER_ERROR, "Audio/Video encoder start fail",
+ postListener.onError(ERROR_ENCODER, "Audio/Video encoder start fail",
e);
return;
}
@@ -319,7 +337,7 @@
}
} catch (IOException e) {
setupEncoder(cameraId, resolution);
- postListener.onError(VideoCaptureError.MUXER_ERROR, "MediaMuxer creation failed!", e);
+ postListener.onError(ERROR_MUXER, "MediaMuxer creation failed!", e);
return;
}
@@ -607,7 +625,7 @@
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
if (mMuxerStarted) {
videoSavedCallback.onError(
- VideoCaptureError.ENCODER_ERROR,
+ ERROR_ENCODER,
"Unexpected change in video encoding format.",
null);
errorOccurred = true;
@@ -637,7 +655,7 @@
Log.i(TAG, "videoEncoder stop");
mVideoEncoder.stop();
} catch (IllegalStateException e) {
- videoSavedCallback.onError(VideoCaptureError.ENCODER_ERROR,
+ videoSavedCallback.onError(ERROR_ENCODER,
"Video encoder stop failed!", e);
errorOccurred = true;
}
@@ -654,7 +672,7 @@
}
}
} catch (IllegalStateException e) {
- videoSavedCallback.onError(VideoCaptureError.MUXER_ERROR, "Muxer stop failed!", e);
+ videoSavedCallback.onError(ERROR_MUXER, "Muxer stop failed!", e);
errorOccurred = true;
}
@@ -728,13 +746,13 @@
mAudioRecorder.stop();
} catch (IllegalStateException e) {
videoSavedCallback.onError(
- VideoCaptureError.ENCODER_ERROR, "Audio recorder stop failed!", e);
+ ERROR_ENCODER, "Audio recorder stop failed!", e);
}
try {
mAudioEncoder.stop();
} catch (IllegalStateException e) {
- videoSavedCallback.onError(VideoCaptureError.ENCODER_ERROR,
+ videoSavedCallback.onError(ERROR_ENCODER,
"Audio encoder stop failed!", e);
}
@@ -853,28 +871,13 @@
* VideoCapture.OnVideoSavedCallback#onError(int, String, Throwable)}.
*
* <p>See message parameter in onError callback or log for more details.
+ *
+ * @hide
*/
- @IntDef({VideoCaptureError.UNKNOWN_ERROR, VideoCaptureError.ENCODER_ERROR,
- VideoCaptureError.MUXER_ERROR, VideoCaptureError.RECORDING_IN_PROGRESS})
+ @IntDef({ERROR_UNKNOWN, ERROR_ENCODER, ERROR_MUXER, ERROR_RECORDING_IN_PROGRESS})
@Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(Scope.LIBRARY_GROUP)
public @interface VideoCaptureError {
- /**
- * An unknown error occurred.
- *
- * <p>See message parameter in onError callback or log for more details.
- */
- int UNKNOWN_ERROR = 0;
- /**
- * An error occurred with encoder state, either when trying to change state or when an
- * unexpected state change occurred.
- */
- int ENCODER_ERROR = 1;
- /** An error with muxer state such as during creation or when stopping. */
- int MUXER_ERROR = 2;
- /**
- * An error indicating start recording was called when video recording is still in progress.
- */
- int RECORDING_IN_PROGRESS = 3;
}
/** Listener containing callbacks for video file I/O events. */
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/VideoCaptureConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/VideoCaptureConfig.java
index 0a6102e..e148b70 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/VideoCaptureConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/VideoCaptureConfig.java
@@ -389,7 +389,7 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return retrieveOption(OPTION_LENS_FACING);
}
@@ -473,7 +473,7 @@
* @return The stored value, if it exists in this configuration.
* @throws IllegalArgumentException if the option does not exist in this configuration.
*/
- @AspectRatio
+ @AspectRatio.Ratio
@Override
public int getTargetAspectRatio() {
return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
@@ -957,7 +957,7 @@
@RestrictTo(Scope.LIBRARY_GROUP)
@Override
@NonNull
- public Builder setLensFacing(@LensFacing int lensFacing) {
+ public Builder setLensFacing(@CameraSelector.LensFacing int lensFacing) {
getMutableConfig().insertOption(OPTION_LENS_FACING, lensFacing);
return this;
}
@@ -1033,7 +1033,7 @@
*/
@NonNull
@Override
- public Builder setTargetAspectRatio(@AspectRatio int aspectRatio) {
+ public Builder setTargetAspectRatio(@AspectRatio.Ratio int aspectRatio) {
getMutableConfig().insertOption(OPTION_TARGET_ASPECT_RATIO, aspectRatio);
return this;
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/CameraSelectorUtil.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/CameraSelectorUtil.java
index f29c0ce..cf95b6e 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/CameraSelectorUtil.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/CameraSelectorUtil.java
@@ -28,7 +28,6 @@
import androidx.camera.core.CameraIdFilterSet;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Config;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.MutableOptionsBundle;
import androidx.camera.core.OptionsBundle;
@@ -106,7 +105,7 @@
* @throws IllegalArgumentException if the option does not exist in this configuration.
*/
@Override
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return retrieveOption(OPTION_LENS_FACING);
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/CameraExecutorTest.java b/camera/camera-core/src/test/java/androidx/camera/core/CameraExecutorTest.java
index ee0a118..239c9ae 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/CameraExecutorTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/CameraExecutorTest.java
@@ -49,10 +49,12 @@
public void setUp() {
mCameraExecutor = new CameraExecutor();
mCameraFactory = new FakeCameraFactory();
- mCameraFactory.insertCamera(LensFacing.BACK, "0",
- () -> new FakeCamera(null, new FakeCameraInfoInternal(0, LensFacing.BACK)));
- mCameraFactory.insertCamera(LensFacing.FRONT, "1",
- () -> new FakeCamera(null, new FakeCameraInfoInternal(0, LensFacing.FRONT)));
+ mCameraFactory.insertCamera(CameraSelector.LENS_FACING_BACK, "0",
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(0, CameraSelector.LENS_FACING_BACK)));
+ mCameraFactory.insertCamera(CameraSelector.LENS_FACING_FRONT, "1",
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(0, CameraSelector.LENS_FACING_FRONT)));
}
@After
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/CameraRepositoryTest.java b/camera/camera-core/src/test/java/androidx/camera/core/CameraRepositoryTest.java
index 9dc3408..66f1108 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/CameraRepositoryTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/CameraRepositoryTest.java
@@ -55,10 +55,12 @@
mCameraRepository = new CameraRepository();
FakeCameraFactory fakeCameraFactory = new FakeCameraFactory();
- fakeCameraFactory.insertCamera(LensFacing.BACK, CAMERA_ID_0,
- () -> new FakeCamera(null, new FakeCameraInfoInternal(0, LensFacing.BACK)));
- fakeCameraFactory.insertCamera(LensFacing.FRONT, CAMERA_ID_1,
- () -> new FakeCamera(null, new FakeCameraInfoInternal(0, LensFacing.FRONT)));
+ fakeCameraFactory.insertCamera(CameraSelector.LENS_FACING_BACK, CAMERA_ID_0,
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(0, CameraSelector.LENS_FACING_BACK)));
+ fakeCameraFactory.insertCamera(CameraSelector.LENS_FACING_FRONT, CAMERA_ID_1,
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(0, CameraSelector.LENS_FACING_FRONT)));
mCameraRepository.init(fakeCameraFactory);
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/CameraSelectorTest.java b/camera/camera-core/src/test/java/androidx/camera/core/CameraSelectorTest.java
index dc1cfb9..f96bc39 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/CameraSelectorTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/CameraSelectorTest.java
@@ -69,14 +69,14 @@
FakeCameraFactory cameraFactory = new FakeCameraFactory();
mRearCamera = new FakeCamera(mock(CameraControlInternal.class),
new FakeCameraInfoInternal(0,
- LensFacing.BACK));
- cameraFactory.insertCamera(LensFacing.BACK, REAR_ID, () -> mRearCamera);
- cameraFactory.setDefaultCameraIdForLensFacing(LensFacing.BACK, REAR_ID);
+ CameraSelector.LENS_FACING_BACK));
+ cameraFactory.insertCamera(CameraSelector.LENS_FACING_BACK, REAR_ID, () -> mRearCamera);
+ cameraFactory.setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_BACK, REAR_ID);
mFrontCamera = new FakeCamera(mock(CameraControlInternal.class),
new FakeCameraInfoInternal(0,
- LensFacing.FRONT));
- cameraFactory.insertCamera(LensFacing.FRONT, FRONT_ID, () -> mFrontCamera);
- cameraFactory.setDefaultCameraIdForLensFacing(LensFacing.FRONT, FRONT_ID);
+ CameraSelector.LENS_FACING_FRONT));
+ cameraFactory.insertCamera(CameraSelector.LENS_FACING_FRONT, FRONT_ID, () -> mFrontCamera);
+ cameraFactory.setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_FRONT, FRONT_ID);
CameraXConfig.Builder appConfigBuilder =
new CameraXConfig.Builder()
.setCameraFactory(cameraFactory)
@@ -95,7 +95,7 @@
@Test
public void canSelectWithLensFacing() {
CameraSelector.Builder cameraSelectorBuilder = new CameraSelector.Builder();
- cameraSelectorBuilder.requireLensFacing(LensFacing.BACK);
+ cameraSelectorBuilder.requireLensFacing(CameraSelector.LENS_FACING_BACK);
String result = cameraSelectorBuilder.build().select(mCameraIds);
assertThat(result).isEqualTo(REAR_ID);
}
@@ -103,23 +103,24 @@
@Test(expected = IllegalArgumentException.class)
public void exception_ifNoAvailableCamera() {
CameraSelector.Builder cameraSelectorBuilder = new CameraSelector.Builder();
- cameraSelectorBuilder.requireLensFacing(LensFacing.BACK).requireLensFacing(
- LensFacing.FRONT);
+ cameraSelectorBuilder.requireLensFacing(CameraSelector.LENS_FACING_BACK).requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT);
cameraSelectorBuilder.build().select(mCameraIds);
}
@Test
public void canGetLensFacing() {
CameraSelector.Builder cameraSelectorBuilder = new CameraSelector.Builder();
- cameraSelectorBuilder.requireLensFacing(LensFacing.BACK);
- assertThat(cameraSelectorBuilder.build().getLensFacing()).isEqualTo(LensFacing.BACK);
+ cameraSelectorBuilder.requireLensFacing(CameraSelector.LENS_FACING_BACK);
+ assertThat(cameraSelectorBuilder.build().getLensFacing()).isEqualTo(
+ CameraSelector.LENS_FACING_BACK);
}
@Test(expected = IllegalStateException.class)
public void exception_ifGetLensFacingConflicted() {
CameraSelector.Builder cameraSelectorBuilder = new CameraSelector.Builder();
- cameraSelectorBuilder.requireLensFacing(LensFacing.BACK).requireLensFacing(
- LensFacing.FRONT);
+ cameraSelectorBuilder.requireLensFacing(CameraSelector.LENS_FACING_BACK).requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT);
cameraSelectorBuilder.build().getLensFacing();
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/FocusMeteringActionTest.java b/camera/camera-core/src/test/java/androidx/camera/core/FocusMeteringActionTest.java
index efffed5..5ae62c87 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/FocusMeteringActionTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/FocusMeteringActionTest.java
@@ -18,7 +18,6 @@
import static com.google.common.truth.Truth.assertThat;
-import androidx.camera.core.FocusMeteringAction.MeteringMode;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -54,7 +53,8 @@
@Test
public void fromPointWithAFAEAWB() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB).build();
+ .from(mPoint1, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB).build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAwb()).containsExactly(mPoint1);
@@ -63,7 +63,7 @@
@Test
public void fromPointWithAFAE() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AF | MeteringMode.AE).build();
+ .from(mPoint1, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE).build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAwb()).isEmpty();
@@ -72,7 +72,7 @@
@Test
public void fromPointWithAFAWB() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AF | MeteringMode.AWB).build();
+ .from(mPoint1, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AWB).build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAe()).isEmpty();
assertThat(action.getMeteringPointsAwb()).containsExactly(mPoint1);
@@ -81,7 +81,7 @@
@Test
public void fromPointWithAEAWB() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AE | MeteringMode.AWB).build();
+ .from(mPoint1, FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB).build();
assertThat(action.getMeteringPointsAf()).isEmpty();
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAwb()).containsExactly(mPoint1);
@@ -90,7 +90,7 @@
@Test
public void fromPointWithAF() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AF).build();
+ .from(mPoint1, FocusMeteringAction.FLAG_AF).build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAe()).isEmpty();
assertThat(action.getMeteringPointsAwb()).isEmpty();
@@ -99,7 +99,7 @@
@Test
public void fromPointWithAE() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AE).build();
+ .from(mPoint1, FocusMeteringAction.FLAG_AE).build();
assertThat(action.getMeteringPointsAf()).isEmpty();
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAwb()).isEmpty();
@@ -108,7 +108,7 @@
@Test
public void fromPointWithAWB() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AWB).build();
+ .from(mPoint1, FocusMeteringAction.FLAG_AWB).build();
assertThat(action.getMeteringPointsAf()).isEmpty();
assertThat(action.getMeteringPointsAe()).isEmpty();
assertThat(action.getMeteringPointsAwb()).containsExactly(mPoint1);
@@ -128,9 +128,15 @@
@Test
public void multiplePointsWithSameAF_AE_AWB() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
+ .from(mPoint1,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1, mPoint2, mPoint3);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1, mPoint2, mPoint3);
@@ -140,9 +146,9 @@
@Test
public void multiplePointsWithSameAF_AE() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AF | MeteringMode.AE)
- .addPoint(mPoint2, MeteringMode.AF | MeteringMode.AE)
- .addPoint(mPoint3, MeteringMode.AF | MeteringMode.AE)
+ .from(mPoint1, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1, mPoint2, mPoint3);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1, mPoint2, mPoint3);
@@ -152,9 +158,9 @@
@Test
public void multiplePointsWithSameAE_AWB() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AE | MeteringMode.AWB)
+ .from(mPoint1, FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
.build();
assertThat(action.getMeteringPointsAf()).isEmpty();
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1, mPoint2, mPoint3);
@@ -164,9 +170,9 @@
@Test
public void multiplePointsWithSameAF_AWB() {
FocusMeteringAction action = FocusMeteringAction.Builder
- .from(mPoint1, MeteringMode.AF | MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AF | MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AF | MeteringMode.AWB)
+ .from(mPoint1, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AWB)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1, mPoint2, mPoint3);
assertThat(action.getMeteringPointsAe()).isEmpty();
@@ -175,9 +181,10 @@
@Test
public void multiplePointsWithSameAWBOnly() {
- FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1, MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AWB)
+ FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
+ FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AWB)
.build();
assertThat(action.getMeteringPointsAf()).isEmpty();
assertThat(action.getMeteringPointsAe()).isEmpty();
@@ -187,9 +194,9 @@
@Test
public void multiplePointsWithSameAEOnly() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AE)
- .addPoint(mPoint2, MeteringMode.AE)
- .addPoint(mPoint3, MeteringMode.AE)
+ FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AE)
.build();
assertThat(action.getMeteringPointsAf()).isEmpty();
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1, mPoint2, mPoint3);
@@ -199,9 +206,9 @@
@Test
public void multiplePointsWithSameAFOnly() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF)
- .addPoint(mPoint2, MeteringMode.AF)
- .addPoint(mPoint3, MeteringMode.AF)
+ FocusMeteringAction.FLAG_AF)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AF)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AF)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1, mPoint2, mPoint3);
assertThat(action.getMeteringPointsAe()).isEmpty();
@@ -211,9 +218,9 @@
@Test
public void multiplePointsWithAFOnly_AEOnly_AWBOnly() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF)
- .addPoint(mPoint2, MeteringMode.AE)
- .addPoint(mPoint3, MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AF)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AWB)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint2);
@@ -223,9 +230,9 @@
@Test
public void multiplePointsWithAFAE_AEAWB_AFAWB() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AE)
- .addPoint(mPoint2, MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AF | MeteringMode.AWB)
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AWB)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1, mPoint3);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint2, mPoint1);
@@ -235,9 +242,10 @@
@Test
public void multiplePointsWithAFAEAWB_AEAWB_AFOnly() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint2, MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AF)
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint2, FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AF)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint1, mPoint3);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1, mPoint2);
@@ -247,9 +255,11 @@
@Test
public void multiplePointsWithAEOnly_AFAWAEB_AEOnly() {
FocusMeteringAction action = FocusMeteringAction.Builder.from(mPoint1,
- MeteringMode.AE)
- .addPoint(mPoint2, MeteringMode.AF | MeteringMode.AE | MeteringMode.AWB)
- .addPoint(mPoint3, MeteringMode.AE)
+ FocusMeteringAction.FLAG_AE)
+ .addPoint(mPoint2,
+ FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE
+ | FocusMeteringAction.FLAG_AWB)
+ .addPoint(mPoint3, FocusMeteringAction.FLAG_AE)
.build();
assertThat(action.getMeteringPointsAf()).containsExactly(mPoint2);
assertThat(action.getMeteringPointsAe()).containsExactly(mPoint1, mPoint2, mPoint3);
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java b/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
index 3b27c26c..5ee4fddb 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
@@ -110,7 +110,7 @@
@Test
public void nonBlockingAnalyzerClosed_imageNotAnalyzed() {
// Arrange.
- setUpImageAnalysisWithStrategy(ImageAnalysis.BackpressureStrategy.KEEP_ONLY_LATEST);
+ setUpImageAnalysisWithStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST);
// Act.
// Receive images from camera feed.
@@ -138,7 +138,7 @@
@Test
public void blockingAnalyzerClosed_imageNotAnalyzed() {
// Arrange.
- setUpImageAnalysisWithStrategy(ImageAnalysis.BackpressureStrategy.BLOCK_PRODUCER);
+ setUpImageAnalysisWithStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER);
// Act.
// Receive images from camera feed.
@@ -158,7 +158,7 @@
@Test
public void keepOnlyLatestStrategy_doesNotBlock() {
// Arrange.
- setUpImageAnalysisWithStrategy(ImageAnalysis.BackpressureStrategy.KEEP_ONLY_LATEST);
+ setUpImageAnalysisWithStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST);
// Act.
// Receive images from camera feed.
@@ -192,7 +192,7 @@
@Test
public void blockProducerStrategy_doesNotDropFrames() {
// Arrange.
- setUpImageAnalysisWithStrategy(ImageAnalysis.BackpressureStrategy.BLOCK_PRODUCER);
+ setUpImageAnalysisWithStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER);
// Act.
// Receive images from camera feed.
@@ -229,7 +229,8 @@
FakeLifecycleOwner lifecycleOwner = new FakeLifecycleOwner();
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
CameraX.bindToLifecycle(lifecycleOwner, cameraSelector, mImageAnalysis);
lifecycleOwner.startAndResume();
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ShadowCameraX.java b/camera/camera-core/src/test/java/androidx/camera/core/ShadowCameraX.java
index 6a55e0d..b2d9d06 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ShadowCameraX.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ShadowCameraX.java
@@ -52,7 +52,7 @@
@Override
public Integer getLensFacing() {
- return LensFacing.BACK;
+ return CameraSelector.LENS_FACING_BACK;
}
@Override
@@ -72,7 +72,7 @@
@NonNull
@Override
- @TorchState
+ @TorchState.State
public LiveData<Integer> getTorchState() {
return mTorchState;
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/utils/CameraSelectorUtilTest.java b/camera/camera-core/src/test/java/androidx/camera/core/impl/utils/CameraSelectorUtilTest.java
index 8e9ca09..8702d5a 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/impl/utils/CameraSelectorUtilTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/utils/CameraSelectorUtilTest.java
@@ -32,7 +32,6 @@
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
-import androidx.camera.core.LensFacing;
import androidx.camera.testing.fakes.FakeAppConfig;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
@@ -72,21 +71,23 @@
@Test
public void convertedCameraDeviceConfig_hasFrontLensFacing() {
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build();
CameraDeviceConfig convertedConfig =
CameraSelectorUtil.toCameraDeviceConfig(cameraSelector);
- assertThat(convertedConfig.getLensFacing()).isEqualTo(LensFacing.FRONT);
+ assertThat(convertedConfig.getLensFacing()).isEqualTo(CameraSelector.LENS_FACING_FRONT);
}
@Test
public void convertedCameraDeviceConfig_hasBackLensFacing() {
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
CameraDeviceConfig convertedConfig =
CameraSelectorUtil.toCameraDeviceConfig(cameraSelector);
- assertThat(convertedConfig.getLensFacing()).isEqualTo(LensFacing.BACK);
+ assertThat(convertedConfig.getLensFacing()).isEqualTo(CameraSelector.LENS_FACING_BACK);
}
@Test(expected = IllegalArgumentException.class)
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
index e7cd516..ab61c36 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
@@ -50,7 +50,6 @@
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureConfig;
import androidx.camera.core.ImageProxy;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
@@ -94,11 +93,11 @@
private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
private EffectMode mEffectMode;
- @LensFacing
+ @CameraSelector.LensFacing
private int mLensFacing;
private FakeLifecycleOwner mLifecycleOwner;
- public ExtensionTest(EffectMode effectMode, @LensFacing int lensFacing) {
+ public ExtensionTest(EffectMode effectMode, @CameraSelector.LensFacing int lensFacing) {
mEffectMode = effectMode;
mLensFacing = lensFacing;
}
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java
index b49ce89..5a588d9 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsErrorListenerTest.java
@@ -28,10 +28,10 @@
import androidx.annotation.NonNull;
import androidx.camera.camera2.Camera2Config;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.UseCase;
import androidx.camera.extensions.ExtensionsErrorListener.ExtensionsErrorCode;
@@ -77,7 +77,7 @@
}
private EffectMode mEffectMode;
- @LensFacing
+ @CameraSelector.LensFacing
private int mLensFacing;
private CountDownLatch mLatch;
@@ -90,7 +90,8 @@
}
};
- public ExtensionsErrorListenerTest(EffectMode effectMode, @LensFacing int lensFacing) {
+ public ExtensionsErrorListenerTest(EffectMode effectMode,
+ @CameraSelector.LensFacing int lensFacing) {
mEffectMode = effectMode;
mLensFacing = lensFacing;
}
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderTest.java
index c552813..8d5db5d 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderTest.java
@@ -46,7 +46,6 @@
import androidx.camera.core.CameraX;
import androidx.camera.core.CaptureProcessor;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.extensions.ExtensionsManager.EffectMode;
import androidx.camera.extensions.impl.CaptureStageImpl;
import androidx.camera.extensions.impl.ImageCaptureExtenderImpl;
@@ -119,7 +118,7 @@
ImageCapture useCase = builder.build();
- @LensFacing int lensFacing = CameraX.getDefaultLensFacing();
+ @CameraSelector.LensFacing int lensFacing = CameraX.getDefaultLensFacing();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(lensFacing).build();
mInstrumentation.runOnMainSync(new Runnable() {
@@ -176,7 +175,7 @@
ImageCapture useCase = configBuilder.build();
- @LensFacing int lensFacing = CameraX.getDefaultLensFacing();
+ @CameraSelector.LensFacing int lensFacing = CameraX.getDefaultLensFacing();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(lensFacing).build();
mInstrumentation.runOnMainSync(new Runnable() {
@@ -224,7 +223,7 @@
// getSupportedResolutions supported since version 1.1
assumeTrue(ExtensionVersion.getRuntimeVersion().compareTo(Version.VERSION_1_1) >= 0);
- @LensFacing int lensFacing = CameraX.getDefaultLensFacing();
+ @CameraSelector.LensFacing int lensFacing = CameraX.getDefaultLensFacing();
ImageCapture.Builder builder = new ImageCapture.Builder();
ImageCaptureExtenderImpl mockImageCaptureExtenderImpl = mock(
@@ -265,7 +264,7 @@
}
private List<Pair<Integer, Size[]>> generateImageCaptureSupportedResolutions(
- @LensFacing int lensFacing)
+ @CameraSelector.LensFacing int lensFacing)
throws CameraInfoUnavailableException {
List<Pair<Integer, Size[]>> formatResolutionsPairList = new ArrayList<>();
String cameraId =
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.java
index 3fac963..f5aa758 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.java
@@ -24,8 +24,8 @@
import androidx.camera.camera2.Camera2Config;
import androidx.camera.core.CameraInfoUnavailableException;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
-import androidx.camera.core.LensFacing;
import androidx.camera.extensions.impl.ImageCaptureExtenderImpl;
import androidx.camera.extensions.util.ExtensionsTestUtil;
import androidx.camera.testing.CameraUtil;
@@ -75,7 +75,7 @@
ExtensionsTestUtil.getAllEffectLensFacingCombinations()) {
ExtensionsManager.EffectMode effectMode =
(ExtensionsManager.EffectMode) EffectLensFacingPair[0];
- @LensFacing int lensFacing = (int) EffectLensFacingPair[1];
+ @CameraSelector.LensFacing int lensFacing = (int) EffectLensFacingPair[1];
assumeTrue(CameraUtil.hasCameraWithLensFacing(lensFacing));
assumeTrue(ExtensionsManager.isExtensionAvailable(effectMode, lensFacing));
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java
index 731ac48..4362c36 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java
@@ -48,7 +48,6 @@
import androidx.camera.core.CameraInfoUnavailableException;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.extensions.ExtensionsManager.EffectMode;
import androidx.camera.extensions.impl.CaptureStageImpl;
@@ -108,7 +107,7 @@
@Before
public void setUp() throws InterruptedException, ExecutionException, TimeoutException {
assumeTrue(CameraUtil.deviceHasCamera());
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.BACK));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK));
Context context = ApplicationProvider.getApplicationContext();
CameraX.initialize(context, Camera2Config.defaultConfig(context));
@@ -143,7 +142,8 @@
FakePreviewExtender fakePreviewExtender = new FakePreviewExtender(configBuilder,
mockPreviewExtenderImpl);
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
fakePreviewExtender.enableExtension(cameraSelector);
Preview useCase = configBuilder.build();
@@ -220,7 +220,8 @@
FakePreviewExtender fakePreviewExtender = new FakePreviewExtender(configBuilder,
mockPreviewExtenderImpl);
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
fakePreviewExtender.enableExtension(cameraSelector);
Preview preview = configBuilder.build();
@@ -273,7 +274,8 @@
FakePreviewExtender fakePreviewExtender = new FakePreviewExtender(configBuilder,
mockPreviewExtenderImpl);
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
fakePreviewExtender.enableExtension(cameraSelector);
Preview preview = configBuilder.build();
mInstrumentation.runOnMainSync(new Runnable() {
@@ -299,7 +301,7 @@
// getSupportedResolutions supported since version 1.1
assumeTrue(ExtensionVersion.getRuntimeVersion().compareTo(Version.VERSION_1_1) >= 0);
- @LensFacing int lensFacing = CameraX.getDefaultLensFacing();
+ @CameraSelector.LensFacing int lensFacing = CameraX.getDefaultLensFacing();
Preview.Builder configBuilder = new Preview.Builder();
PreviewExtenderImpl mockPreviewExtenderImpl = mock(PreviewExtenderImpl.class);
@@ -342,7 +344,7 @@
}
private List<Pair<Integer, Size[]>> generatePreviewSupportedResolutions(
- @LensFacing int lensFacing) throws CameraInfoUnavailableException {
+ @CameraSelector.LensFacing int lensFacing) throws CameraInfoUnavailableException {
List<Pair<Integer, Size[]>> formatResolutionsPairList = new ArrayList<>();
String cameraId =
androidx.camera.extensions.CameraUtil.getCameraIdSetWithLensFacing(
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.java
index ccf774d..1fb4d38 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.java
@@ -24,8 +24,8 @@
import androidx.camera.camera2.Camera2Config;
import androidx.camera.core.CameraInfoUnavailableException;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
-import androidx.camera.core.LensFacing;
import androidx.camera.extensions.impl.PreviewExtenderImpl;
import androidx.camera.extensions.util.ExtensionsTestUtil;
import androidx.camera.testing.CameraUtil;
@@ -75,7 +75,7 @@
ExtensionsTestUtil.getAllEffectLensFacingCombinations()) {
ExtensionsManager.EffectMode effectMode =
(ExtensionsManager.EffectMode) EffectLensFacingPair[0];
- @LensFacing int lensFacing = (int) EffectLensFacingPair[1];
+ @CameraSelector.LensFacing int lensFacing = (int) EffectLensFacingPair[1];
assumeTrue(CameraUtil.hasCameraWithLensFacing(lensFacing));
assumeTrue(ExtensionsManager.isExtensionAvailable(effectMode, lensFacing));
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
index 1c8d39a..41ed1c2 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
@@ -29,7 +29,6 @@
import androidx.camera.core.CameraX;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureConfig;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
import androidx.camera.core.impl.utils.CameraSelectorUtil;
@@ -74,16 +73,16 @@
@NonNull
public static Collection<Object[]> getAllEffectLensFacingCombinations() {
return Arrays.asList(new Object[][]{
- {EffectMode.BOKEH, LensFacing.FRONT},
- {EffectMode.BOKEH, LensFacing.BACK},
- {EffectMode.HDR, LensFacing.FRONT},
- {EffectMode.HDR, LensFacing.BACK},
- {EffectMode.BEAUTY, LensFacing.FRONT},
- {EffectMode.BEAUTY, LensFacing.BACK},
- {EffectMode.NIGHT, LensFacing.FRONT},
- {EffectMode.NIGHT, LensFacing.BACK},
- {EffectMode.AUTO, LensFacing.FRONT},
- {EffectMode.AUTO, LensFacing.BACK}
+ {EffectMode.BOKEH, CameraSelector.LENS_FACING_FRONT},
+ {EffectMode.BOKEH, CameraSelector.LENS_FACING_BACK},
+ {EffectMode.HDR, CameraSelector.LENS_FACING_FRONT},
+ {EffectMode.HDR, CameraSelector.LENS_FACING_BACK},
+ {EffectMode.BEAUTY, CameraSelector.LENS_FACING_FRONT},
+ {EffectMode.BEAUTY, CameraSelector.LENS_FACING_BACK},
+ {EffectMode.NIGHT, CameraSelector.LENS_FACING_FRONT},
+ {EffectMode.NIGHT, CameraSelector.LENS_FACING_BACK},
+ {EffectMode.AUTO, CameraSelector.LENS_FACING_FRONT},
+ {EffectMode.AUTO, CameraSelector.LENS_FACING_BACK}
});
}
@@ -110,7 +109,7 @@
/**
* Creates an {@link ImageCapture.Builder} object for specific {@link EffectMode} and
- * {@link LensFacing}.
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -118,7 +117,7 @@
*/
@NonNull
public static ImageCapture.Builder createImageCaptureConfigBuilderWithEffect(
- @NonNull EffectMode effectMode, @LensFacing int lensFacing) {
+ @NonNull EffectMode effectMode, @CameraSelector.LensFacing int lensFacing) {
ImageCapture.Builder builder = new ImageCapture.Builder();
CameraSelector selector =
new CameraSelector.Builder().requireLensFacing(lensFacing).build();
@@ -154,7 +153,7 @@
/**
* Creates a {@link Preview.Builder} object for specific {@link EffectMode} and
- * {@link LensFacing}.
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -162,7 +161,7 @@
*/
@NonNull
public static Preview.Builder createPreviewBuilderWithEffect(@NonNull EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
Preview.Builder builder = new Preview.Builder();
CameraSelector selector =
new CameraSelector.Builder().requireLensFacing(lensFacing).build();
@@ -198,7 +197,7 @@
/**
* Creates an {@link ImageCaptureConfig} object for specific {@link EffectMode} and
- * {@link LensFacing}.
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -206,7 +205,7 @@
*/
@NonNull
public static ImageCaptureConfig createImageCaptureConfigWithEffect(
- @NonNull EffectMode effectMode, @LensFacing int lensFacing) {
+ @NonNull EffectMode effectMode, @CameraSelector.LensFacing int lensFacing) {
ImageCapture.Builder imageCaptureConfigBuilder =
createImageCaptureConfigBuilderWithEffect(effectMode, lensFacing);
return imageCaptureConfigBuilder.getUseCaseConfig();
@@ -214,7 +213,7 @@
/**
* Creates a {@link PreviewConfig} object for specific {@link EffectMode} and
- * {@link LensFacing}.
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -222,7 +221,7 @@
*/
@NonNull
public static PreviewConfig createPreviewConfigWithEffect(@NonNull EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
Preview.Builder previewBuilder =
createPreviewBuilderWithEffect(effectMode, lensFacing);
return previewBuilder.getUseCaseConfig();
@@ -230,7 +229,7 @@
/**
* Creates an {@link ImageCapture} object for specific {@link EffectMode} and
- * {@link LensFacing}.
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -238,12 +237,13 @@
*/
@NonNull
public static ImageCapture createImageCaptureWithEffect(@NonNull EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
return createImageCaptureConfigBuilderWithEffect(effectMode, lensFacing).build();
}
/**
- * Creates a {@link Preview} object for specific {@link EffectMode} and {@link LensFacing}.
+ * Creates a {@link Preview} object for specific {@link EffectMode} and
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -251,13 +251,13 @@
*/
@NonNull
public static Preview createPreviewWithEffect(@NonNull EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
return createPreviewBuilderWithEffect(effectMode, lensFacing).build();
}
/**
* Creates an {@link ImageCaptureExtenderImpl} object for specific {@link EffectMode} and
- * {@link LensFacing}.
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -265,7 +265,7 @@
*/
@NonNull
public static ImageCaptureExtenderImpl createImageCaptureExtenderImpl(
- @NonNull EffectMode effectMode, @LensFacing int lensFacing)
+ @NonNull EffectMode effectMode, @CameraSelector.LensFacing int lensFacing)
throws CameraInfoUnavailableException, CameraAccessException {
ImageCaptureExtenderImpl impl = null;
@@ -304,7 +304,7 @@
/**
* Creates a {@link PreviewExtenderImpl} object for specific {@link EffectMode} and
- * {@link LensFacing}.
+ * {@link CameraSelector.LensFacing}.
*
* @param effectMode The effect mode for the created object.
* @param lensFacing The lens facing for the created object.
@@ -312,7 +312,7 @@
*/
@NonNull
public static PreviewExtenderImpl createPreviewExtenderImpl(@NonNull EffectMode effectMode,
- @LensFacing int lensFacing)
+ @CameraSelector.LensFacing int lensFacing)
throws CameraInfoUnavailableException, CameraAccessException {
PreviewExtenderImpl impl = null;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
index 7a8e591..c4385e9 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
@@ -25,7 +25,6 @@
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.core.impl.utils.futures.Futures;
@@ -142,14 +141,15 @@
}
/**
- * Indicates whether the camera device with the {@link LensFacing} can support the specific
+ * Indicates whether the camera device with the lensFacing can support the specific
* extension function.
*
* @param effectMode The extension function to be checked.
- * @param lensFacing The {@link LensFacing} of the camera device to be checked.
+ * @param lensFacing The lensFacing of the camera device to be checked.
* @return True if the specific extension function is supported for the camera device.
*/
- public static boolean isExtensionAvailable(EffectMode effectMode, @LensFacing int lensFacing) {
+ public static boolean isExtensionAvailable(EffectMode effectMode,
+ @CameraSelector.LensFacing int lensFacing) {
boolean isImageCaptureAvailable = checkImageCaptureExtensionCapability(effectMode,
lensFacing);
boolean isPreviewAvailable = checkPreviewExtensionCapability(effectMode, lensFacing);
@@ -163,16 +163,16 @@
}
/**
- * Indicates whether the camera device with the {@link LensFacing} can support the specific
+ * Indicates whether the camera device with the lensFacing can support the specific
* extension function for specific use case.
*
* @param klass The {@link ImageCapture} or {@link Preview} class to be checked.
* @param effectMode The extension function to be checked.
- * @param lensFacing The {@link LensFacing} of the camera device to be checked.
+ * @param lensFacing The lensFacing of the camera device to be checked.
* @return True if the specific extension function is supported for the camera device.
*/
public static boolean isExtensionAvailable(
- Class<?> klass, EffectMode effectMode, @LensFacing int lensFacing) {
+ Class<?> klass, EffectMode effectMode, @CameraSelector.LensFacing int lensFacing) {
boolean isAvailable = false;
if (klass == ImageCapture.class) {
@@ -185,7 +185,7 @@
}
private static boolean checkImageCaptureExtensionCapability(EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
ImageCapture.Builder builder = new ImageCapture.Builder();
CameraSelector selector =
new CameraSelector.Builder().requireLensFacing(lensFacing).build();
@@ -243,7 +243,7 @@
}
private static boolean checkPreviewExtensionCapability(EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
Preview.Builder builder = new Preview.Builder();
CameraSelector cameraSelector =
new CameraSelector.Builder().requireLensFacing(lensFacing).build();
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/CameraUtil.java b/camera/camera-testing/src/main/java/androidx/camera/testing/CameraUtil.java
index 6df63d8..7ca9c78 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/CameraUtil.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/CameraUtil.java
@@ -34,7 +34,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.RequiresPermission;
import androidx.camera.core.CameraInternal;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.UseCase;
import androidx.concurrent.futures.CallbackToFutureAdapter;
import androidx.core.util.Preconditions;
@@ -293,7 +293,7 @@
* @return True if the device supports the lensFacing.
* @throws IllegalStateException if the CAMERA permission is not currently granted.
*/
- public static boolean hasCameraWithLensFacing(@LensFacing int lensFacing) {
+ public static boolean hasCameraWithLensFacing(@CameraSelector.LensFacing int lensFacing) {
@SupportedLensFacingInt
int lensFacingInteger = getLensFacingIntFromEnum(lensFacing);
for (String cameraId : getCameraIdListOrThrow()) {
@@ -307,13 +307,13 @@
}
/**
- * Check if the device has a flash unit with the specified {@link LensFacing}.
+ * Check if the device has a flash unit with the specified lensFacing.
*
* @param lensFacing The desired camera lensFacing.
* @return True if the device has flash unit with the specified LensFacing.
* @throws IllegalStateException if the CAMERA permission is not currently granted.
*/
- public static boolean hasFlashUnitWithLensFacing(@LensFacing int lensFacing) {
+ public static boolean hasFlashUnitWithLensFacing(@CameraSelector.LensFacing int lensFacing) {
@SupportedLensFacingInt
int lensFacingInteger = getLensFacingIntFromEnum(lensFacing);
for (String cameraId : getCameraIdListOrThrow()) {
@@ -341,20 +341,19 @@
/**
- * Converts a lens facing direction from a {@link CameraMetadata} integer to a
- * {@link LensFacing}.
+ * Converts a lens facing direction from a {@link CameraMetadata} integer to a lensFacing.
*
* @param lensFacingInteger The lens facing integer, as defined in {@link CameraMetadata}.
* @return The lens facing enum.
*/
- @LensFacing
+ @CameraSelector.LensFacing
public static int getLensFacingEnumFromInt(
@SupportedLensFacingInt int lensFacingInteger) {
switch (lensFacingInteger) {
case CameraMetadata.LENS_FACING_BACK:
- return LensFacing.BACK;
+ return CameraSelector.LENS_FACING_BACK;
case CameraMetadata.LENS_FACING_FRONT:
- return LensFacing.FRONT;
+ return CameraSelector.LENS_FACING_FRONT;
default:
throw new IllegalArgumentException(
"Unsupported lens facing integer: " + lensFacingInteger);
@@ -362,18 +361,17 @@
}
/**
- * Converts a lens facing direction from a {@link LensFacing} to a {@link CameraMetadata}
- * integer.
+ * Converts a lens facing direction from a lensFacing to a {@link CameraMetadata} integer.
*
- * @param lensFacing The lens facing enum, as defined in {@link LensFacing}.
+ * @param lensFacing The lens facing enum, as defined in {@link CameraSelector}.
* @return The lens facing integer.
*/
@SupportedLensFacingInt
- private static int getLensFacingIntFromEnum(@LensFacing int lensFacing) {
+ private static int getLensFacingIntFromEnum(@CameraSelector.LensFacing int lensFacing) {
switch (lensFacing) {
- case LensFacing.BACK:
+ case CameraSelector.LENS_FACING_BACK:
return CameraMetadata.LENS_FACING_BACK;
- case LensFacing.FRONT:
+ case CameraSelector.LENS_FACING_FRONT:
return CameraMetadata.LENS_FACING_FRONT;
default:
throw new IllegalArgumentException("Unsupported lens facing enum: " + lensFacing);
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java
index 689f653..94fa4bf 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java
@@ -33,7 +33,6 @@
import androidx.camera.core.CameraInfoUnavailableException;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
import androidx.camera.core.impl.utils.CameraSelectorUtil;
@@ -51,8 +50,8 @@
private Preview mPreview;
@Nullable
public String mCameraId = null;
- @LensFacing
- public int mLensFacing = LensFacing.BACK;
+ @CameraSelector.LensFacing
+ public int mLensFacing = CameraSelector.LENS_FACING_BACK;
@VisibleForTesting
public final CountingIdlingResource mPreviewReady = new CountingIdlingResource("PreviewReady");
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeAppConfig.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeAppConfig.java
index e35c1fd..14a504e 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeAppConfig.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeAppConfig.java
@@ -18,9 +18,9 @@
import androidx.annotation.NonNull;
import androidx.camera.core.CameraDeviceSurfaceManager;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ExtendableUseCaseConfigFactory;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.UseCaseConfigFactory;
/**
@@ -39,10 +39,12 @@
@NonNull
public static CameraXConfig create() {
FakeCameraFactory cameraFactory = new FakeCameraFactory();
- cameraFactory.insertCamera(LensFacing.BACK, CAMERA_ID_0,
- () -> new FakeCamera(null, new FakeCameraInfoInternal(0, LensFacing.BACK)));
- cameraFactory.insertCamera(LensFacing.FRONT, CAMERA_ID_1,
- () -> new FakeCamera(null, new FakeCameraInfoInternal(0, LensFacing.FRONT)));
+ cameraFactory.insertCamera(CameraSelector.LENS_FACING_BACK, CAMERA_ID_0,
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(0, CameraSelector.LENS_FACING_BACK)));
+ cameraFactory.insertCamera(CameraSelector.LENS_FACING_FRONT, CAMERA_ID_1,
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(0, CameraSelector.LENS_FACING_FRONT)));
CameraDeviceSurfaceManager surfaceManager = new FakeCameraDeviceSurfaceManager();
UseCaseConfigFactory defaultConfigFactory = new ExtendableUseCaseConfigFactory();
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java
index 19fd5ab..754813e 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraControl.java
@@ -16,6 +16,8 @@
package androidx.camera.testing.fakes;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_OFF;
+
import android.graphics.Rect;
import android.util.Log;
@@ -26,9 +28,9 @@
import androidx.camera.core.CameraCaptureResult;
import androidx.camera.core.CameraControlInternal;
import androidx.camera.core.CaptureConfig;
-import androidx.camera.core.FlashMode;
import androidx.camera.core.FocusMeteringAction;
import androidx.camera.core.FocusMeteringResult;
+import androidx.camera.core.ImageCapture;
import androidx.camera.core.SessionConfig;
import androidx.camera.core.impl.utils.futures.Futures;
@@ -46,8 +48,8 @@
private final ControlUpdateCallback mControlUpdateCallback;
private final SessionConfig.Builder mSessionConfigBuilder = new SessionConfig.Builder();
private boolean mIsTorchOn = false;
- @FlashMode
- private int mFlashMode = FlashMode.OFF;
+ @ImageCapture.FlashMode
+ private int mFlashMode = FLASH_MODE_OFF;
private ArrayList<CaptureConfig> mSubmittedCaptureRequests = new ArrayList<>();
private OnNewCaptureRequestListener mOnNewCaptureRequestListener;
@@ -96,14 +98,14 @@
Log.d(TAG, "setCropRegion(" + crop + ")");
}
- @FlashMode
+ @ImageCapture.FlashMode
@Override
public int getFlashMode() {
return mFlashMode;
}
@Override
- public void setFlashMode(@FlashMode int flashMode) {
+ public void setFlashMode(@ImageCapture.FlashMode int flashMode) {
mFlashMode = flashMode;
Log.d(TAG, "setFlashMode(" + mFlashMode + ")");
}
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
index 13b689c..06923b1 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
@@ -22,7 +22,7 @@
import androidx.annotation.RestrictTo.Scope;
import androidx.camera.core.CameraFactory;
import androidx.camera.core.CameraInternal;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.LensFacingCameraIdFilter;
import androidx.camera.core.LensFacingConverter;
import androidx.core.util.Pair;
@@ -82,7 +82,7 @@
* @param cameraId Identifier to use for the camera.
* @param cameraInternal Callable used to provide the Camera implementation.
*/
- public void insertCamera(@LensFacing int lensFacing, @NonNull String cameraId,
+ public void insertCamera(@CameraSelector.LensFacing int lensFacing, @NonNull String cameraId,
@NonNull Callable<CameraInternal> cameraInternal) {
// Invalidate caches
mCachedCameraIds = null;
@@ -97,15 +97,15 @@
* <p>This is a convenience method for calling
* {@link #insertCamera(int, String, Callable)}
* followed by {@link #setDefaultCameraIdForLensFacing(int, String)} with
- * {@link LensFacing#FRONT} for all lens facing arguments.
+ * {@link CameraSelector#LENS_FACING_FRONT} for all lens facing arguments.
*
* @param cameraId Identifier to use for the front camera.
* @param cameraInternal Camera implementation.
*/
public void insertDefaultFrontCamera(@NonNull String cameraId,
@NonNull Callable<CameraInternal> cameraInternal) {
- insertCamera(LensFacing.FRONT, cameraId, cameraInternal);
- setDefaultCameraIdForLensFacing(LensFacing.FRONT, cameraId);
+ insertCamera(CameraSelector.LENS_FACING_FRONT, cameraId, cameraInternal);
+ setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_FRONT, cameraId);
}
/**
@@ -114,30 +114,30 @@
* <p>This is a convenience method for calling
* {@link #insertCamera(int, String, Callable)}
* followed by {@link #setDefaultCameraIdForLensFacing(int, String)} with
- * {@link LensFacing#BACK} for all lens facing arguments.
+ * {@link CameraSelector#LENS_FACING_BACK} for all lens facing arguments.
*
* @param cameraId Identifier to use for the back camera.
* @param cameraInternal Camera implementation.
*/
public void insertDefaultBackCamera(@NonNull String cameraId,
@NonNull Callable<CameraInternal> cameraInternal) {
- insertCamera(LensFacing.BACK, cameraId, cameraInternal);
- setDefaultCameraIdForLensFacing(LensFacing.BACK, cameraId);
+ insertCamera(CameraSelector.LENS_FACING_BACK, cameraId, cameraInternal);
+ setDefaultCameraIdForLensFacing(CameraSelector.LENS_FACING_BACK, cameraId);
}
/**
* Sets the camera ID which will be returned by {@link #cameraIdForLensFacing(int)}.
*
- * @param lensFacing The {@link LensFacing} to set.
+ * @param lensFacing The {@link CameraSelector.LensFacing} to set.
* @param cameraId The camera ID which will be returned.
*/
- public void setDefaultCameraIdForLensFacing(@LensFacing int lensFacing,
+ public void setDefaultCameraIdForLensFacing(@CameraSelector.LensFacing int lensFacing,
@NonNull String cameraId) {
switch (lensFacing) {
- case LensFacing.FRONT:
+ case CameraSelector.LENS_FACING_FRONT:
mFrontCameraId = cameraId;
break;
- case LensFacing.BACK:
+ case CameraSelector.LENS_FACING_BACK:
mBackCameraId = cameraId;
break;
default:
@@ -159,11 +159,11 @@
@Override
@Nullable
- public String cameraIdForLensFacing(@LensFacing int lensFacing) {
+ public String cameraIdForLensFacing(@CameraSelector.LensFacing int lensFacing) {
switch (lensFacing) {
- case LensFacing.FRONT:
+ case CameraSelector.LENS_FACING_FRONT:
return mFrontCameraId;
- case LensFacing.BACK:
+ case CameraSelector.LENS_FACING_BACK:
return mBackCameraId;
default:
return null;
@@ -172,7 +172,8 @@
@Override
@NonNull
- public LensFacingCameraIdFilter getLensFacingCameraIdFilter(@LensFacing int lensFacing) {
+ public LensFacingCameraIdFilter getLensFacingCameraIdFilter(
+ @CameraSelector.LensFacing int lensFacing) {
// Lazily cache the map of LensFacing to set of camera ids. This cache will be
// invalidated anytime a new camera is added.
if (mCachedLensFacingToIdMap == null) {
@@ -201,7 +202,8 @@
@Nullable
private final Set<String> mIds;
- SettableLensFacingCameraIdFilter(@LensFacing int lensFacing, @Nullable Set<String> ids) {
+ SettableLensFacingCameraIdFilter(@CameraSelector.LensFacing int lensFacing,
+ @Nullable Set<String> ids) {
super(lensFacing);
mIds = ids;
}
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
index 7e3b65e..ec843ff 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
@@ -22,8 +22,8 @@
import androidx.annotation.Nullable;
import androidx.camera.core.CameraInfoInternal;
import androidx.camera.core.CameraOrientationUtil;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageOutputConfig.RotationValue;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.TorchState;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@@ -36,7 +36,7 @@
public final class FakeCameraInfoInternal implements CameraInfoInternal {
private final int mSensorRotation;
- @LensFacing
+ @CameraSelector.LensFacing
private final int mLensFacing;
private final boolean mHasFlashUnit = true;
private MutableLiveData<Integer> mTorchState = new MutableLiveData<>(TorchState.OFF);
@@ -47,10 +47,10 @@
public FakeCameraInfoInternal() {
- this(/*sensorRotation=*/ 0, /*lensFacing=*/ LensFacing.BACK);
+ this(/*sensorRotation=*/ 0, /*lensFacing=*/ CameraSelector.LENS_FACING_BACK);
}
- public FakeCameraInfoInternal(int sensorRotation, @LensFacing int lensFacing) {
+ public FakeCameraInfoInternal(int sensorRotation, @CameraSelector.LensFacing int lensFacing) {
mSensorRotation = sensorRotation;
mLensFacing = lensFacing;
}
@@ -68,7 +68,7 @@
// Currently this assumes that a back-facing camera is always opposite to the screen.
// This may not be the case for all devices, so in the future we may need to handle that
// scenario.
- boolean isOppositeFacingScreen = (LensFacing.BACK == getLensFacing());
+ boolean isOppositeFacingScreen = (CameraSelector.LENS_FACING_BACK == getLensFacing());
return CameraOrientationUtil.getRelativeImageRotation(
relativeRotationDegrees,
mSensorRotation,
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
index 1e4ab1e..6b54a90 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
@@ -24,10 +24,10 @@
import androidx.annotation.Nullable;
import androidx.camera.core.CameraDeviceConfig;
import androidx.camera.core.CameraIdFilter;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.CaptureConfig;
import androidx.camera.core.Config;
import androidx.camera.core.ImageOutputConfig;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.MutableConfig;
import androidx.camera.core.MutableOptionsBundle;
import androidx.camera.core.OptionsBundle;
@@ -128,7 +128,7 @@
}
@Override
- @LensFacing
+ @CameraSelector.LensFacing
public int getLensFacing() {
return retrieveOption(OPTION_LENS_FACING);
}
@@ -365,7 +365,7 @@
@Override
@NonNull
- public Builder setLensFacing(@LensFacing int lensFacing) {
+ public Builder setLensFacing(@CameraSelector.LensFacing int lensFacing) {
getMutableConfig().insertOption(OPTION_LENS_FACING, lensFacing);
return this;
}
diff --git a/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraInfoTest.java b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraInfoTest.java
index 09a6781..70839eb 100644
--- a/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraInfoTest.java
+++ b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraInfoTest.java
@@ -21,7 +21,7 @@
import android.os.Build;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.CameraSelector;
import androidx.test.filters.SmallTest;
import org.junit.Before;
@@ -38,8 +38,8 @@
public final class FakeCameraInfoTest {
private static final int SENSOR_ROTATION_DEGREES = 90;
- @LensFacing
- private static final int LENS_FACING = LensFacing.FRONT;
+ @CameraSelector.LensFacing
+ private static final int LENS_FACING = CameraSelector.LENS_FACING_FRONT;
private FakeCameraInfoInternal mFakeCameraInfo;
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
index 607f6a6..34ddbe3 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
@@ -38,7 +38,6 @@
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.DisplayOrientedMeteringPointFactory;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.MeteringPoint;
import androidx.camera.core.MeteringPointFactory;
import androidx.camera.core.Preview;
@@ -70,9 +69,10 @@
public class TextureViewMeteringPointFactoryTest {
public static final float TOLERANCE = 0.000001f;
private static final CameraSelector FRONT_CAM =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build();
private static final CameraSelector BACK_CAM =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
@Rule
public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(
Manifest.permission.CAMERA);
@@ -123,9 +123,9 @@
@Test
public void backCamera_translatedPoint_SameAsDisplayOriented() throws Throwable {
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.BACK));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK));
- startAndWaitForCameraReady(LensFacing.BACK);
+ startAndWaitForCameraReady(CameraSelector.LENS_FACING_BACK);
TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(mTextureView);
@@ -142,9 +142,9 @@
@Test
public void frontCamera_translatedPoint_SameAsDisplayOriented() throws Throwable {
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.FRONT));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_FRONT));
- startAndWaitForCameraReady(LensFacing.FRONT);
+ startAndWaitForCameraReady(CameraSelector.LENS_FACING_FRONT);
TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(mTextureView);
@@ -163,7 +163,7 @@
@Test
public void xy_OutOfRange() throws Throwable {
- startAndWaitForCameraReady(LensFacing.BACK);
+ startAndWaitForCameraReady(CameraSelector.LENS_FACING_BACK);
TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(mTextureView);
@@ -198,7 +198,7 @@
return xValid && yValid;
}
- private void startAndWaitForCameraReady(@LensFacing int lensFacing)
+ private void startAndWaitForCameraReady(@CameraSelector.LensFacing int lensFacing)
throws InterruptedException {
Preview preview = new Preview.Builder().build();
mInstrumentation.runOnMainSync(() -> {
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
index 14d1842..5bfc64b 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
@@ -51,14 +51,13 @@
import androidx.annotation.RestrictTo.Scope;
import androidx.annotation.UiThread;
import androidx.camera.core.Camera;
-import androidx.camera.core.FlashMode;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.FlashModeHelper;
import androidx.camera.core.FocusMeteringAction;
-import androidx.camera.core.FocusMeteringAction.MeteringMode;
+import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCapture.OnImageCapturedCallback;
import androidx.camera.core.ImageCapture.OnImageSavedCallback;
import androidx.camera.core.ImageProxy;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.LensFacingConverter;
import androidx.camera.core.MeteringPoint;
import androidx.camera.core.VideoCapture.OnVideoSavedCallback;
@@ -219,10 +218,10 @@
setCameraLensFacing(null);
break;
case LENS_FACING_FRONT:
- setCameraLensFacing(LensFacing.FRONT);
+ setCameraLensFacing(CameraSelector.LENS_FACING_FRONT);
break;
case LENS_FACING_BACK:
- setCameraLensFacing(LensFacing.BACK);
+ setCameraLensFacing(CameraSelector.LENS_FACING_BACK);
break;
default:
// Unhandled event.
@@ -231,13 +230,13 @@
int flashMode = a.getInt(R.styleable.CameraView_flash, 0);
switch (flashMode) {
case FLASH_MODE_AUTO:
- setFlash(FlashMode.AUTO);
+ setFlash(ImageCapture.FLASH_MODE_AUTO);
break;
case FLASH_MODE_ON:
- setFlash(FlashMode.ON);
+ setFlash(ImageCapture.FLASH_MODE_ON);
break;
case FLASH_MODE_OFF:
- setFlash(FlashMode.OFF);
+ setFlash(ImageCapture.FLASH_MODE_OFF);
break;
default:
// Unhandled event.
@@ -686,7 +685,7 @@
* @throws IllegalStateException if the CAMERA permission is not currently granted.
*/
@RequiresPermission(permission.CAMERA)
- public boolean hasCameraWithLensFacing(@LensFacing int lensFacing) {
+ public boolean hasCameraWithLensFacing(@CameraSelector.LensFacing int lensFacing) {
return mCameraModule.hasCameraWithLensFacing(lensFacing);
}
@@ -719,20 +718,20 @@
mCameraModule.setCameraLensFacing(lensFacing);
}
- /** Returns the currently selected {@link LensFacing}. */
+ /** Returns the currently selected lensFacing. */
@Nullable
public Integer getCameraLensFacing() {
return mCameraModule.getLensFacing();
}
/** Gets the active flash strategy. */
- @FlashMode
+ @ImageCapture.FlashMode
public int getFlash() {
return mCameraModule.getFlash();
}
/** Sets the active flash strategy. */
- public void setFlash(@FlashMode int flashMode) {
+ public void setFlash(@ImageCapture.FlashMode int flashMode) {
mCameraModule.setFlash(flashMode);
}
@@ -799,8 +798,8 @@
Camera camera = mCameraModule.getCamera();
if (camera != null) {
camera.getCameraControl().startFocusAndMetering(
- FocusMeteringAction.Builder.from(afPoint, MeteringMode.AF)
- .addPoint(aePoint, MeteringMode.AE)
+ FocusMeteringAction.Builder.from(afPoint, FocusMeteringAction.FLAG_AF)
+ .addPoint(aePoint, FocusMeteringAction.FLAG_AE)
.build());
} else {
Log.d(TAG, "cannot access camera");
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java
index 2e2a15b..b9b8fa7 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraXModule.java
@@ -16,6 +16,8 @@
package androidx.camera.view;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_OFF;
+
import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -36,11 +38,9 @@
import androidx.camera.core.CameraOrientationUtil;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
-import androidx.camera.core.FlashMode;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCapture.OnImageCapturedCallback;
import androidx.camera.core.ImageCapture.OnImageSavedCallback;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.LensFacingConverter;
import androidx.camera.core.Preview;
import androidx.camera.core.TorchState;
@@ -92,8 +92,8 @@
private CameraView.CaptureMode mCaptureMode = CaptureMode.IMAGE;
private long mMaxVideoDuration = CameraView.INDEFINITE_VIDEO_DURATION;
private long mMaxVideoSize = CameraView.INDEFINITE_VIDEO_SIZE;
- @FlashMode
- private int mFlash = FlashMode.OFF;
+ @ImageCapture.FlashMode
+ private int mFlash = FLASH_MODE_OFF;
@Nullable
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
Camera mCamera;
@@ -124,7 +124,7 @@
private LifecycleOwner mNewLifecycle;
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
@Nullable
- Integer mCameraLensFacing = LensFacing.BACK;
+ Integer mCameraLensFacing = CameraSelector.LENS_FACING_BACK;
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
@Nullable
ProcessCameraProvider mCameraProvider;
@@ -351,7 +351,7 @@
ImageCapture.Metadata metadata = new ImageCapture.Metadata();
metadata.setReversedHorizontal(
- mCameraLensFacing != null && mCameraLensFacing == LensFacing.FRONT);
+ mCameraLensFacing != null && mCameraLensFacing == CameraSelector.LENS_FACING_FRONT);
mImageCapture.takePicture(saveLocation, metadata, executor, callback);
}
@@ -420,7 +420,7 @@
}
@RequiresPermission(permission.CAMERA)
- public boolean hasCameraWithLensFacing(@LensFacing int lensFacing) {
+ public boolean hasCameraWithLensFacing(@CameraSelector.LensFacing int lensFacing) {
String cameraId;
try {
cameraId = CameraX.getCameraWithLensFacing(lensFacing);
@@ -450,15 +450,15 @@
return;
}
- if (mCameraLensFacing == LensFacing.BACK
- && availableCameraLensFacing.contains(LensFacing.FRONT)) {
- setCameraLensFacing(LensFacing.FRONT);
+ if (mCameraLensFacing == CameraSelector.LENS_FACING_BACK
+ && availableCameraLensFacing.contains(CameraSelector.LENS_FACING_FRONT)) {
+ setCameraLensFacing(CameraSelector.LENS_FACING_FRONT);
return;
}
- if (mCameraLensFacing == LensFacing.FRONT
- && availableCameraLensFacing.contains(LensFacing.BACK)) {
- setCameraLensFacing(LensFacing.BACK);
+ if (mCameraLensFacing == CameraSelector.LENS_FACING_FRONT
+ && availableCameraLensFacing.contains(CameraSelector.LENS_FACING_BACK)) {
+ setCameraLensFacing(CameraSelector.LENS_FACING_BACK);
return;
}
}
@@ -593,24 +593,24 @@
// If we're bound to a lifecycle, remove unavailable cameras
if (mCurrentLifecycle != null) {
- if (!hasCameraWithLensFacing(LensFacing.BACK)) {
- available.remove(LensFacing.BACK);
+ if (!hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK)) {
+ available.remove(CameraSelector.LENS_FACING_BACK);
}
- if (!hasCameraWithLensFacing(LensFacing.FRONT)) {
- available.remove(LensFacing.FRONT);
+ if (!hasCameraWithLensFacing(CameraSelector.LENS_FACING_FRONT)) {
+ available.remove(CameraSelector.LENS_FACING_FRONT);
}
}
return available;
}
- @FlashMode
+ @ImageCapture.FlashMode
public int getFlash() {
return mFlash;
}
- public void setFlash(@FlashMode int flash) {
+ public void setFlash(@ImageCapture.FlashMode int flash) {
this.mFlash = flash;
if (mImageCapture == null) {
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ToggleButtonUITest.java b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ToggleButtonUITest.java
index 0dc3561..b056335 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ToggleButtonUITest.java
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ToggleButtonUITest.java
@@ -31,9 +31,8 @@
import android.content.Intent;
import androidx.camera.core.CameraInfo;
-import androidx.camera.core.FlashMode;
+import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.TorchState;
import androidx.camera.integration.core.idlingresource.ElapsedTimeIdlingResource;
import androidx.camera.integration.core.idlingresource.WaitForViewToShow;
@@ -121,15 +120,15 @@
// There are 3 different states of flash mode: ON, OFF and AUTO.
// By pressing flash mode toggle button, the flash mode would switch to the next state.
// The flash mode would loop in following sequence: OFF -> AUTO -> ON -> OFF.
- @FlashMode int mode1 = useCase.getFlashMode();
+ @ImageCapture.FlashMode int mode1 = useCase.getFlashMode();
onView(withId(R.id.flash_toggle)).perform(click());
- @FlashMode int mode2 = useCase.getFlashMode();
+ @ImageCapture.FlashMode int mode2 = useCase.getFlashMode();
// After the switch, the mode2 should be different from mode1.
assertNotEquals(mode2, mode1);
onView(withId(R.id.flash_toggle)).perform(click());
- @FlashMode int mode3 = useCase.getFlashMode();
+ @ImageCapture.FlashMode int mode3 = useCase.getFlashMode();
// The mode3 should be different from first and second time.
assertNotEquals(mode3, mode2);
assertNotEquals(mode3, mode1);
@@ -158,7 +157,7 @@
@Test
public void testSwitchCameraToggleButton() {
- assumeTrue(CameraUtil.hasCameraWithLensFacing(LensFacing.FRONT));
+ assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_FRONT));
waitFor(new WaitForViewToShow(R.id.direction_toggle));
boolean isPreviewExist = mActivityRule.getActivity().getPreview() != null;
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
index c8c8327..2372938 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
@@ -16,6 +16,10 @@
package androidx.camera.integration.core;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_AUTO;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_OFF;
+import static androidx.camera.core.ImageCapture.FLASH_MODE_ON;
+
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -45,16 +49,13 @@
import androidx.camera.core.CameraControl;
import androidx.camera.core.CameraInfo;
import androidx.camera.core.CameraSelector;
-import androidx.camera.core.FlashMode;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.TorchState;
import androidx.camera.core.UseCase;
import androidx.camera.core.VideoCapture;
import androidx.camera.core.VideoCaptureConfig;
-import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.concurrent.futures.CallbackToFutureAdapter;
import androidx.core.app.ActivityCompat;
@@ -95,9 +96,10 @@
// Possible values for this intent key: "backward" or "forward".
private static final String INTENT_EXTRA_CAMERA_DIRECTION = "camera_direction";
static final CameraSelector BACK_SELECTOR =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
static final CameraSelector FRONT_SELECTOR =
- new CameraSelector.Builder().requireLensFacing(LensFacing.FRONT).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_FRONT).build();
private boolean mPermissionsGranted = false;
private CallbackToFutureAdapter.Completer<Boolean> mPermissionsCompleter;
@@ -106,8 +108,8 @@
private VideoFileSaver mVideoFileSaver;
/** The camera to use */
CameraSelector mCurrentCameraSelector = BACK_SELECTOR;
- @LensFacing
- int mCurrentCameraLensFacing = LensFacing.BACK;
+ @CameraSelector.LensFacing
+ int mCurrentCameraLensFacing = CameraSelector.LENS_FACING_BACK;
ProcessCameraProvider mCameraProvider;
// TODO: Move the analysis processing, capture processing to separate threads, so
@@ -119,7 +121,7 @@
private VideoCapture mVideoCapture;
private Camera mCamera;
@ImageCapture.CaptureMode
- private int mCaptureMode = ImageCapture.CaptureMode.MINIMIZE_LATENCY;
+ private int mCaptureMode = ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY;
// Synthetic Accessor
@SuppressWarnings("WeakerAccess")
TextureView mTextureView;
@@ -360,7 +362,7 @@
}
mImageAnalysis.setAnalyzer(
- CameraXExecutors.mainThreadExecutor(),
+ ContextCompat.getMainExecutor(this),
(image, rotationDegrees) -> {
// Since we set the callback handler to a main thread handler, we can call
// setValue() here. If we weren't on the main thread, we would have to call
@@ -451,7 +453,7 @@
dir,
formatter.format(Calendar.getInstance().getTime())
+ ".jpg"),
- CameraXExecutors.mainThreadExecutor(),
+ ContextCompat.getMainExecutor(CameraXActivity.this),
new ImageCapture.OnImageSavedCallback() {
@Override
public void onImageSaved(@NonNull File file) {
@@ -498,13 +500,13 @@
Button btnCaptureQuality = this.findViewById(R.id.capture_quality);
btnCaptureQuality.setVisibility(View.VISIBLE);
btnCaptureQuality.setText(
- mCaptureMode == ImageCapture.CaptureMode.MAXIMIZE_QUALITY ? "MAX" : "MIN");
+ mCaptureMode == ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY ? "MAX" : "MIN");
btnCaptureQuality.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- mCaptureMode = (mCaptureMode == ImageCapture.CaptureMode.MAXIMIZE_QUALITY
- ? ImageCapture.CaptureMode.MINIMIZE_LATENCY
- : ImageCapture.CaptureMode.MAXIMIZE_QUALITY);
+ mCaptureMode = (mCaptureMode == ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY
+ ? ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY
+ : ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY);
rebindUseCases();
}
});
@@ -533,13 +535,13 @@
flashToggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- @FlashMode int flashMode = mImageCapture.getFlashMode();
- if (flashMode == FlashMode.ON) {
- mImageCapture.setFlashMode(FlashMode.OFF);
- } else if (flashMode == FlashMode.OFF) {
- mImageCapture.setFlashMode(FlashMode.AUTO);
- } else if (flashMode == FlashMode.AUTO) {
- mImageCapture.setFlashMode(FlashMode.ON);
+ @ImageCapture.FlashMode int flashMode = mImageCapture.getFlashMode();
+ if (flashMode == FLASH_MODE_ON) {
+ mImageCapture.setFlashMode(FLASH_MODE_OFF);
+ } else if (flashMode == FLASH_MODE_OFF) {
+ mImageCapture.setFlashMode(FLASH_MODE_AUTO);
+ } else if (flashMode == FLASH_MODE_AUTO) {
+ mImageCapture.setFlashMode(FLASH_MODE_ON);
}
refreshFlashButtonIcon();
}
@@ -557,15 +559,15 @@
private void refreshFlashButtonIcon() {
ImageButton flashToggle = findViewById(R.id.flash_toggle);
- @FlashMode int flashMode = mImageCapture.getFlashMode();
+ @ImageCapture.FlashMode int flashMode = mImageCapture.getFlashMode();
switch (flashMode) {
- case FlashMode.ON:
+ case FLASH_MODE_ON:
flashToggle.setImageResource(R.drawable.ic_flash_on);
break;
- case FlashMode.OFF:
+ case FLASH_MODE_OFF:
flashToggle.setImageResource(R.drawable.ic_flash_off);
break;
- case FlashMode.AUTO:
+ case FLASH_MODE_AUTO:
flashToggle.setImageResource(R.drawable.ic_flash_auto);
break;
}
@@ -640,29 +642,26 @@
}
Button button = this.findViewById(R.id.Video);
- button.setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Button buttonView = (Button) view;
- String text = button.getText().toString();
- if (text.equals("Record") && !mVideoFileSaver.isSaving()) {
- mVideoCapture.startRecording(
- mVideoFileSaver.getNewVideoFile(),
- CameraXExecutors.mainThreadExecutor(), mVideoFileSaver);
- mVideoFileSaver.setSaving();
- buttonView.setText("Stop");
- } else if (text.equals("Stop") && mVideoFileSaver.isSaving()) {
- buttonView.setText("Record");
- mVideoCapture.stopRecording();
- } else if (text.equals("Record") && mVideoFileSaver.isSaving()) {
- buttonView.setText("Stop");
- mVideoFileSaver.setSaving();
- } else if (text.equals("Stop") && !mVideoFileSaver.isSaving()) {
- buttonView.setText("Record");
- }
- }
- });
+ button.setOnClickListener((view) -> {
+ Button buttonView = (Button) view;
+ String text = button.getText().toString();
+ if (text.equals("Record") && !mVideoFileSaver.isSaving()) {
+ mVideoCapture.startRecording(
+ mVideoFileSaver.getNewVideoFile(),
+ ContextCompat.getMainExecutor(CameraXActivity.this),
+ mVideoFileSaver);
+ mVideoFileSaver.setSaving();
+ buttonView.setText("Stop");
+ } else if (text.equals("Stop") && mVideoFileSaver.isSaving()) {
+ buttonView.setText("Record");
+ mVideoCapture.stopRecording();
+ } else if (text.equals("Record") && mVideoFileSaver.isSaving()) {
+ buttonView.setText("Stop");
+ mVideoFileSaver.setSaving();
+ } else if (text.equals("Stop") && !mVideoFileSaver.isSaving()) {
+ buttonView.setText("Record");
+ }
+ });
}
void disableVideoCapture() {
@@ -741,10 +740,10 @@
Log.d(TAG, "Camera direction: " + mCurrentCameraDirection);
if (mCurrentCameraDirection.equalsIgnoreCase("BACKWARD")) {
mCurrentCameraSelector = BACK_SELECTOR;
- mCurrentCameraLensFacing = LensFacing.BACK;
+ mCurrentCameraLensFacing = CameraSelector.LENS_FACING_BACK;
} else if (mCurrentCameraDirection.equalsIgnoreCase("FORWARD")) {
mCurrentCameraSelector = FRONT_SELECTOR;
- mCurrentCameraLensFacing = LensFacing.FRONT;
+ mCurrentCameraLensFacing = CameraSelector.LENS_FACING_FRONT;
} else {
throw new RuntimeException("Invalid camera direction: " + mCurrentCameraDirection);
}
@@ -758,12 +757,12 @@
directionToggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (mCurrentCameraLensFacing == LensFacing.BACK) {
+ if (mCurrentCameraLensFacing == CameraSelector.LENS_FACING_BACK) {
mCurrentCameraSelector = FRONT_SELECTOR;
- mCurrentCameraLensFacing = LensFacing.FRONT;
- } else if (mCurrentCameraLensFacing == LensFacing.FRONT) {
+ mCurrentCameraLensFacing = CameraSelector.LENS_FACING_FRONT;
+ } else if (mCurrentCameraLensFacing == CameraSelector.LENS_FACING_FRONT) {
mCurrentCameraSelector = BACK_SELECTOR;
- mCurrentCameraLensFacing = LensFacing.BACK;
+ mCurrentCameraLensFacing = CameraSelector.LENS_FACING_BACK;
}
Log.d(TAG, "Change camera direction: " + mCurrentCameraSelector);
diff --git a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/PreviewProcessorTimestampTest.java b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/PreviewProcessorTimestampTest.java
index 4062208..1a7a11f 100644
--- a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/PreviewProcessorTimestampTest.java
+++ b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/PreviewProcessorTimestampTest.java
@@ -42,7 +42,6 @@
import androidx.camera.core.CaptureProcessor;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
import androidx.camera.extensions.AutoImageCaptureExtender;
@@ -96,7 +95,7 @@
private FakeLifecycleOwner mLifecycleOwner;
private CameraDevice.StateCallback mCameraStatusCallback;
private ExtensionsManager.EffectMode mEffectMode;
- @LensFacing
+ @CameraSelector.LensFacing
private int mLensFacing;
private CountDownLatch mLatch;
private CountDownLatch mInputTimestampsLatch;
@@ -115,21 +114,21 @@
@Parameterized.Parameters
public static Collection<Object[]> getParameters() {
return Arrays.asList(new Object[][]{
- {ExtensionsManager.EffectMode.BOKEH, LensFacing.FRONT},
- {ExtensionsManager.EffectMode.BOKEH, LensFacing.BACK},
- {ExtensionsManager.EffectMode.HDR, LensFacing.FRONT},
- {ExtensionsManager.EffectMode.HDR, LensFacing.BACK},
- {ExtensionsManager.EffectMode.BEAUTY, LensFacing.FRONT},
- {ExtensionsManager.EffectMode.BEAUTY, LensFacing.BACK},
- {ExtensionsManager.EffectMode.NIGHT, LensFacing.FRONT},
- {ExtensionsManager.EffectMode.NIGHT, LensFacing.BACK},
- {ExtensionsManager.EffectMode.AUTO, LensFacing.FRONT},
- {ExtensionsManager.EffectMode.AUTO, LensFacing.BACK}
+ {ExtensionsManager.EffectMode.BOKEH, CameraSelector.LENS_FACING_FRONT},
+ {ExtensionsManager.EffectMode.BOKEH, CameraSelector.LENS_FACING_BACK},
+ {ExtensionsManager.EffectMode.HDR, CameraSelector.LENS_FACING_FRONT},
+ {ExtensionsManager.EffectMode.HDR, CameraSelector.LENS_FACING_BACK},
+ {ExtensionsManager.EffectMode.BEAUTY, CameraSelector.LENS_FACING_FRONT},
+ {ExtensionsManager.EffectMode.BEAUTY, CameraSelector.LENS_FACING_BACK},
+ {ExtensionsManager.EffectMode.NIGHT, CameraSelector.LENS_FACING_FRONT},
+ {ExtensionsManager.EffectMode.NIGHT, CameraSelector.LENS_FACING_BACK},
+ {ExtensionsManager.EffectMode.AUTO, CameraSelector.LENS_FACING_FRONT},
+ {ExtensionsManager.EffectMode.AUTO, CameraSelector.LENS_FACING_BACK}
});
}
public PreviewProcessorTimestampTest(ExtensionsManager.EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
mEffectMode = effectMode;
mLensFacing = lensFacing;
}
@@ -285,7 +284,7 @@
* To invoke the enableExtension() method for different effect.
*/
private void enableExtension(ExtensionsManager.EffectMode effectMode,
- @LensFacing int lensFacing) {
+ @CameraSelector.LensFacing int lensFacing) {
CameraSelector cameraSelector =
new CameraSelector.Builder().requireLensFacing(lensFacing).build();
diff --git a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
index a4723b4..f2ea111 100644
--- a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
+++ b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
@@ -35,17 +35,14 @@
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.ImageCapture;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.UseCase;
-import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.extensions.AutoImageCaptureExtender;
import androidx.camera.extensions.AutoPreviewExtender;
import androidx.camera.extensions.BeautyImageCaptureExtender;
import androidx.camera.extensions.BeautyPreviewExtender;
import androidx.camera.extensions.BokehImageCaptureExtender;
import androidx.camera.extensions.BokehPreviewExtender;
-import androidx.camera.extensions.ExtensionsErrorListener;
import androidx.camera.extensions.ExtensionsManager;
import androidx.camera.extensions.HdrImageCaptureExtender;
import androidx.camera.extensions.HdrPreviewExtender;
@@ -78,7 +75,7 @@
private static final int PERMISSIONS_REQUEST_CODE = 42;
private static final CameraSelector CAMERA_SELECTOR =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
boolean mPermissionsGranted = false;
private CallbackToFutureAdapter.Completer<Boolean> mPermissionCompleter;
@@ -284,48 +281,44 @@
Environment.DIRECTORY_PICTURES),
"ExtensionsPictures");
dir.mkdirs();
- captureButton.setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mTakePictureIdlingResource.increment();
- mImageCapture.takePicture(
- new File(
- dir,
- formatter.format(Calendar.getInstance().getTime())
- + mCurrentImageCaptureType.name()
- + ".jpg"),
- CameraXExecutors.mainThreadExecutor(),
- new ImageCapture.OnImageSavedCallback() {
- @Override
- public void onImageSaved(@NonNull File file) {
- Log.d(TAG, "Saved image to " + file);
+ captureButton.setOnClickListener((view) -> {
+ mTakePictureIdlingResource.increment();
+ mImageCapture.takePicture(
+ new File(
+ dir,
+ formatter.format(Calendar.getInstance().getTime())
+ + mCurrentImageCaptureType.name()
+ + ".jpg"),
+ ContextCompat.getMainExecutor(CameraExtensionsActivity.this),
+ new ImageCapture.OnImageSavedCallback() {
+ @Override
+ public void onImageSaved(@NonNull File file) {
+ Log.d(TAG, "Saved image to " + file);
- if (!mTakePictureIdlingResource.isIdleNow()) {
- mTakePictureIdlingResource.decrement();
- }
+ if (!mTakePictureIdlingResource.isIdleNow()) {
+ mTakePictureIdlingResource.decrement();
+ }
- // Trigger MediaScanner to scan the file
- Intent intent = new Intent(
- Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
- intent.setData(Uri.fromFile(file));
- sendBroadcast(intent);
+ // Trigger MediaScanner to scan the file
+ Intent intent = new Intent(
+ Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+ intent.setData(Uri.fromFile(file));
+ sendBroadcast(intent);
- Toast.makeText(getApplicationContext(),
- "Saved image to " + file,
- Toast.LENGTH_SHORT).show();
- }
+ Toast.makeText(getApplicationContext(),
+ "Saved image to " + file,
+ Toast.LENGTH_SHORT).show();
+ }
- @Override
- public void onError(
- @ImageCapture.ImageCaptureError int error,
- @NonNull String message,
- Throwable cause) {
- Log.e(TAG, "Failed to save image - " + message, cause);
- }
- });
- }
- });
+ @Override
+ public void onError(
+ @ImageCapture.ImageCaptureError int error,
+ @NonNull String message,
+ Throwable cause) {
+ Log.e(TAG, "Failed to save image - " + message, cause);
+ }
+ });
+ });
}
void disableImageCapture() {
@@ -341,12 +334,8 @@
/** Creates all the use cases. */
private void createUseCases() {
- ExtensionsManager.setExtensionsErrorListener(new ExtensionsErrorListener() {
- @Override
- public void onError(@NonNull ExtensionsErrorCode errorCode) {
- Log.d(TAG, "Extensions error in error code: " + errorCode);
- }
- });
+ ExtensionsManager.setExtensionsErrorListener((errorCode) ->
+ Log.d(TAG, "Extensions error in error code: " + errorCode));
createImageCapture();
createPreview();
bindUseCases();
@@ -428,11 +417,11 @@
try {
Log.d(TAG, "Camera Facing: " + mCurrentCameraFacing);
- @LensFacing int facing;
+ @CameraSelector.LensFacing int facing;
if (mCurrentCameraFacing.equalsIgnoreCase("BACK")) {
- facing = LensFacing.BACK;
+ facing = CameraSelector.LENS_FACING_BACK;
} else if (mCurrentCameraFacing.equalsIgnoreCase("FRONT")) {
- facing = LensFacing.FRONT;
+ facing = CameraSelector.LENS_FACING_FRONT;
} else {
throw new RuntimeException("Invalid lens facing: " + mCurrentCameraFacing);
}
@@ -460,7 +449,7 @@
}
},
- CameraXExecutors.mainThreadExecutor()
+ ContextCompat.getMainExecutor(CameraExtensionsActivity.this)
);
}
diff --git a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/cameracontrollers/CameraXController.kt b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/cameracontrollers/CameraXController.kt
index c16176d..a70eb41 100644
--- a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/cameracontrollers/CameraXController.kt
+++ b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/cameracontrollers/CameraXController.kt
@@ -27,7 +27,6 @@
import androidx.camera.camera2.interop.ExperimentalCamera2Interop
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
-import androidx.camera.core.LensFacing
import androidx.camera.core.Preview
import androidx.camera.core.impl.utils.executor.CameraXExecutors
import androidx.camera.integration.antelope.CameraParams
@@ -135,7 +134,11 @@
// TODO: As of 0.3.0 CameraX can only use front and back cameras.
// Update in future versions
val cameraProviderFuture = ProcessCameraProvider.getInstance(activity)
- val cameraXcameraID = if (params.id.equals("0")) LensFacing.BACK else LensFacing.FRONT
+ val cameraXcameraID = if (params.id == "0") {
+ CameraSelector.LENS_FACING_BACK
+ } else {
+ CameraSelector.LENS_FACING_FRONT
+ }
val cameraSelector = CameraSelector.Builder().requireLensFacing(cameraXcameraID).build()
when (testConfig.currentRunningTest) {
// Only the preview is required
@@ -333,8 +336,8 @@
sessionCaptureCallback: CameraCaptureSession.CaptureCallback
): ImageCapture.Builder {
- val configBuilder = ImageCapture.Builder()
- .setCaptureMode(ImageCapture.CaptureMode.MAXIMIZE_QUALITY)
+ val configBuilder =
+ ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
Camera2Interop.Extender(configBuilder)
.setDeviceStateCallback(deviceStateCallback)
.setSessionCaptureCallback(sessionCaptureCallback)
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraViewFragment.java b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraViewFragment.java
index 1c1c84d..000a7eb4 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraViewFragment.java
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraViewFragment.java
@@ -30,7 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.camera.core.LensFacing;
+import androidx.camera.core.CameraSelector;
import androidx.camera.view.CameraView;
import androidx.camera.view.CameraView.CaptureMode;
import androidx.camera.view.CameraView.ScaleType;
@@ -100,8 +100,9 @@
cameraDirectionString != null && (cameraDirectionString.equalsIgnoreCase("BACK")
|| cameraDirectionString.equalsIgnoreCase("FRONT"));
if (isCameraDirectionValid) {
- @LensFacing int lensFacing = cameraDirectionString.equalsIgnoreCase("BACK")
- ? LensFacing.BACK : LensFacing.FRONT;
+ @CameraSelector.LensFacing int lensFacing = cameraDirectionString.equalsIgnoreCase(
+ "BACK")
+ ? CameraSelector.LENS_FACING_BACK : CameraSelector.LENS_FACING_FRONT;
mCameraView.setCameraLensFacing(lensFacing);
}
@@ -133,11 +134,13 @@
if (mToggleCameraButton != null) {
mToggleCameraButton.setVisibility(
- (mCameraView.hasCameraWithLensFacing(LensFacing.BACK)
- && mCameraView.hasCameraWithLensFacing(LensFacing.FRONT))
+ (mCameraView.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK)
+ && mCameraView.hasCameraWithLensFacing(
+ CameraSelector.LENS_FACING_FRONT))
? View.VISIBLE
: View.INVISIBLE);
- mToggleCameraButton.setChecked(mCameraView.getCameraLensFacing() == LensFacing.FRONT);
+ mToggleCameraButton.setChecked(
+ mCameraView.getCameraLensFacing() == CameraSelector.LENS_FACING_FRONT);
}
// Set listeners here, or else restoring state will trigger them.
@@ -147,7 +150,8 @@
@Override
public void onCheckedChanged(CompoundButton b, boolean checked) {
mCameraView.setCameraLensFacing(
- checked ? LensFacing.FRONT : LensFacing.BACK);
+ checked ? CameraSelector.LENS_FACING_FRONT
+ : CameraSelector.LENS_FACING_BACK);
}
});
}
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java
index 6e4e506..e0360e4 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CaptureViewOnTouchListener.java
@@ -36,9 +36,9 @@
import androidx.camera.core.ImageCapture.OnImageSavedCallback;
import androidx.camera.core.VideoCapture.OnVideoSavedCallback;
import androidx.camera.core.VideoCapture.VideoCaptureError;
-import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.view.CameraView;
import androidx.camera.view.CameraView.CaptureMode;
+import androidx.core.content.ContextCompat;
import java.io.File;
import java.text.SimpleDateFormat;
@@ -104,7 +104,7 @@
if (mCameraView.getCaptureMode() == CaptureMode.IMAGE
|| mCameraView.getCaptureMode() == CaptureMode.MIXED) {
mCameraView.takePicture(createNewFile(PHOTO_EXTENSION),
- CameraXExecutors.mainThreadExecutor(), this);
+ ContextCompat.getMainExecutor(mCameraView.getContext()), this);
}
}
@@ -113,7 +113,7 @@
if (mCameraView.getCaptureMode() == CaptureMode.VIDEO
|| mCameraView.getCaptureMode() == CaptureMode.MIXED) {
mCameraView.startRecording(createNewFile(VIDEO_EXTENSION),
- CameraXExecutors.mainThreadExecutor(), this);
+ ContextCompat.getMainExecutor(mCameraView.getContext()), this);
}
}
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/PreviewViewFragment.java b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/PreviewViewFragment.java
index ed4a49a..821609b 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/PreviewViewFragment.java
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/PreviewViewFragment.java
@@ -27,7 +27,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.CameraSelector;
-import androidx.camera.core.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
@@ -106,7 +105,8 @@
preview.setPreviewSurfaceProvider(mPreviewView.getPreviewSurfaceProvider());
CameraSelector cameraSelector =
- new CameraSelector.Builder().requireLensFacing(LensFacing.BACK).build();
+ new CameraSelector.Builder().requireLensFacing(
+ CameraSelector.LENS_FACING_BACK).build();
cameraProvider.bindToLifecycle(PreviewViewFragment.this, cameraSelector, preview);
}
diff --git a/cleanBuild.sh b/cleanBuild.sh
index 0672097..6e89563 100755
--- a/cleanBuild.sh
+++ b/cleanBuild.sh
@@ -59,15 +59,17 @@
}
confirm
-export OUT_DIR=../../out
+scriptDir="$(cd $(dirname $0) && pwd)"
+checkoutDir="$(cd $scriptDir/../.. && pwd)"
+export OUT_DIR="$checkoutDir/out"
function removeCaches() {
echo removing caches
rm -rf .gradle
rm -rf buildSrc/.gradle
rm -f local.properties
- rm -rf ../../out
+ rm -rf $OUT_DIR
}
removeCaches
echo running build
-GRADLE_USER_HOME=../../out ./gradlew --no-daemon $goals
+./gradlew --no-daemon $goals
diff --git a/collection/collection-ktx/build.gradle b/collection/collection-ktx/build.gradle
index c080584..72a1cd1 100644
--- a/collection/collection-ktx/build.gradle
+++ b/collection/collection-ktx/build.gradle
@@ -25,11 +25,11 @@
}
dependencies {
- compile(project(":collection:collection"))
- compile(KOTLIN_STDLIB)
- testCompile(JUNIT)
- testCompile(TRUTH)
- testCompile(project(":internal-testutils-truth"))
+ api(project(":collection:collection"))
+ api(KOTLIN_STDLIB)
+ testImplementation(JUNIT)
+ testImplementation(TRUTH)
+ testImplementation(project(":internal-testutils-truth"))
}
androidx {
diff --git a/collection/collection/build.gradle b/collection/collection/build.gradle
index d6dc85b..376fc06 100644
--- a/collection/collection/build.gradle
+++ b/collection/collection/build.gradle
@@ -28,9 +28,9 @@
sourceCompatibility = JavaVersion.VERSION_1_7
dependencies {
- compile("androidx.annotation:annotation:1.1.0")
+ api("androidx.annotation:annotation:1.1.0")
annotationProcessor(NULLAWAY)
- testCompile(JUNIT)
+ testImplementation(JUNIT)
}
androidx {
diff --git a/concurrent/futures/build.gradle b/concurrent/futures/build.gradle
index 0fecae1..b2027a5 100644
--- a/concurrent/futures/build.gradle
+++ b/concurrent/futures/build.gradle
@@ -26,10 +26,10 @@
}
dependencies {
- compile("androidx.annotation:annotation:1.1.0")
- compile(GUAVA_LISTENABLE_FUTURE)
- testCompile(JUNIT)
- testCompile(TRUTH)
+ api("androidx.annotation:annotation:1.1.0")
+ api(GUAVA_LISTENABLE_FUTURE)
+ testImplementation(JUNIT)
+ testImplementation(TRUTH)
}
sourceCompatibility = JavaVersion.VERSION_1_7
diff --git a/development/apilint.py b/development/apilint.py
index ad3d8d5..e523d26 100755
--- a/development/apilint.py
+++ b/development/apilint.py
@@ -19,19 +19,28 @@
"""Script that will remind developers to run updateApi."""
import argparse
+import os.path
import sys
-WARNING_COLOR = '\033[93m'
+
+WARNING_COLOR = '\033[33m'
END_COLOR = '\033[0m'
-WARNING = """
+WARNING_NO_API_FILES = """
{}**********************************************************************
You changed library classes, but you have no current.txt changes.
Did you forget to run ./gradlew updateApi?
**********************************************************************{}
""".format(WARNING_COLOR, END_COLOR)
+WARNING_OLD_API_FILES = """
+{}**********************************************************************
+Your current.txt is older than your current changes in library classes.
+Did you forget to re-run ./gradlew updateApi?
+**********************************************************************{}
+""".format(WARNING_COLOR, END_COLOR)
+
def main(args=None):
parser = argparse.ArgumentParser()
@@ -40,16 +49,24 @@
args = parser.parse_args()
api_files = [f for f in args.file
if f.endswith('.txt') and '/api/' in f]
- if len(api_files) > 0:
+ source_files = [f for f in args.file
+ if (not "buildSrc/" in f and
+ "/src/main/" in f or
+ "/src/commonMain/" in f or
+ "/src/androidMain/" in f)]
+ if len(source_files) == 0:
sys.exit(0)
- for f in args.file:
- if (not "buildSrc/" in f and
- "/src/main/" in f or
- "/src/commonMain/" in f or
- "/src/androidMain/" in f):
- print(WARNING)
- sys.exit(77) # 77 is a warning code in repohooks
+ if len(api_files) == 0:
+ print(WARNING_NO_API_FILES)
+ sys.exit(77) # 77 is a warning code in repohooks
+
+ last_source_timestamp = max([os.path.getmtime(f) for f in source_files])
+ last_api_timestamp = max([os.path.getmtime(f) for f in api_files])
+
+ if last_source_timestamp > last_api_timestamp:
+ print(WARNING_OLD_API_FILES)
+ sys.exit(77) # 77 is a warning code in repohooks
sys.exit(0)
if __name__ == '__main__':
diff --git a/development/importMaven/build.gradle.kts b/development/importMaven/build.gradle.kts
index 1195623..ca40116 100644
--- a/development/importMaven/build.gradle.kts
+++ b/development/importMaven/build.gradle.kts
@@ -149,6 +149,31 @@
mavenCentral()
google()
gradlePluginPortal()
+
+ ivy {
+ setUrl("https://download.jetbrains.com/kotlin/native/builds/releases")
+ patternLayout {
+ artifact("[revision]/macos/[artifact]-[revision].[ext]")
+ }
+ metadataSources {
+ artifact()
+ }
+ content {
+ includeGroup("")
+ }
+ }
+ ivy {
+ setUrl("https://download.jetbrains.com/kotlin/native/builds/releases")
+ patternLayout {
+ artifact("[revision]/linux/[artifact]-[revision].[ext]")
+ }
+ metadataSources {
+ artifact()
+ }
+ content {
+ includeGroup("")
+ }
+ }
}
if (artifactName != null) {
@@ -386,7 +411,7 @@
val folder = if (internal) internalFolder else externalFolder
val moduleVersionId = artifact.moduleVersion.id
val group = moduleVersionId.group
- val groupPath = group.split(".").joinToString("/")
+ val groupPath = groupToPath(group)
val pathComponents = listOf(
prebuiltsLocation,
folder,
@@ -436,7 +461,7 @@
internal: Boolean = false
) {
val folder = if (internal) internalFolder else externalFolder
- val groupPath = group.split(".").joinToString("/")
+ val groupPath = groupToPath(group)
val pathComponents = listOf(
prebuiltsLocation,
folder,
@@ -476,6 +501,17 @@
}
}
+/**
+ * Given a groupId, returns a relative filepath telling where to place that group
+ */
+fun groupToPath(group: String): String {
+ if (group != "") {
+ return group.split(".").joinToString("/")
+ } else {
+ return "no-group"
+ }
+}
+
tasks {
val fetchArtifacts by creating {
doLast {
diff --git a/development/importMaven/import_maven_artifacts.py b/development/importMaven/import_maven_artifacts.py
index ea24127..319a600 100755
--- a/development/importMaven/import_maven_artifacts.py
+++ b/development/importMaven/import_maven_artifacts.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
"""
Copyright 2018 The Android Open Source Project
@@ -23,6 +23,7 @@
E.g. android.arch.work:work-runtime-ktx:1.0.0-alpha07
'''
+if sys.version_info[0] < 3: raise Exception("Python 2 is not supported by this script. If your system python calls python 2 after python 2 end-of-life on Jan 1 2020, you should probably change it.")
def main():
"""Parses the command line arguments, and executes the gradle script
@@ -35,13 +36,39 @@
required=True, dest='name')
parse_result = parser.parse_args()
artifact_name = parse_result.name
+ if ("kotlin-native-linux" in artifact_name): artifact_name = fix_kotlin_native(artifact_name)
+
command = './gradlew --build-file build.gradle.kts -PartifactName=%s' % (
artifact_name)
process = subprocess.Popen(command,
shell=True,
stdin=subprocess.PIPE)
process.communicate()
+ assert not process.returncode
+ # Generate our own .pom file so Gradle will use this artifact without also checking the internet.
+ # This can be removed once https://youtrack.jetbrains.com/issue/KT-35049 is resolved
+ if ("kotlin-native-linux" in artifact_name):
+ version = artifact_name.split("@")[0].split(":")[2]
+ output_file = open(f"../../../.././prebuilts/androidx/external/no-group/kotlin-native-linux/{version}/kotlin-native-linux-{version}.pom", 'w+')
+ output_file.write(f"""
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-native-linux</artifactId>
+ <version>{version}</version>
+ <name>kotlin-native-linux</name>
+ <url>https://download.jetbrains.com/kotlin/native/builds</url>
+</project>\n""")
+ output_file.close()
+
+#kotlin-native-linux has weird syntax requirements; needs to be :kotlin-native-linux:VERSION@tar.gz
+def fix_kotlin_native(name_arg):
+ if name_arg[0]!=":": name_arg = ":"+name_arg
+ if not name_arg.endswith("@tar.gz"): name_arg += "@tar.gz"
+ return name_arg
if __name__ == '__main__':
main()
diff --git a/exifinterface/api/1.2.0-beta01.txt b/exifinterface/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..4bbc2ba
--- /dev/null
+++ b/exifinterface/api/1.2.0-beta01.txt
@@ -0,0 +1,347 @@
+// Signature format: 3.0
+package androidx.exifinterface.media {
+
+ public class ExifInterface {
+ ctor public ExifInterface(java.io.File) throws java.io.IOException;
+ ctor public ExifInterface(String) throws java.io.IOException;
+ ctor public ExifInterface(java.io.FileDescriptor) throws java.io.IOException;
+ ctor public ExifInterface(java.io.InputStream) throws java.io.IOException;
+ ctor public ExifInterface(java.io.InputStream, int) throws java.io.IOException;
+ method public void flipHorizontally();
+ method public void flipVertically();
+ method public double getAltitude(double);
+ method public String? getAttribute(String);
+ method public byte[]? getAttributeBytes(String);
+ method public double getAttributeDouble(String, double);
+ method public int getAttributeInt(String, int);
+ method public long[]? getAttributeRange(String);
+ method @Deprecated public boolean getLatLong(float[]!);
+ method public double[]? getLatLong();
+ method public int getRotationDegrees();
+ method public byte[]? getThumbnail();
+ method public android.graphics.Bitmap? getThumbnailBitmap();
+ method public byte[]? getThumbnailBytes();
+ method public long[]? getThumbnailRange();
+ method public boolean hasAttribute(String);
+ method public boolean hasThumbnail();
+ method public boolean isFlipped();
+ method public static boolean isSupportedMimeType(String);
+ method public boolean isThumbnailCompressed();
+ method public void resetOrientation();
+ method public void rotate(int);
+ method public void saveAttributes() throws java.io.IOException;
+ method public void setAltitude(double);
+ method public void setAttribute(String, String?);
+ method public void setGpsInfo(android.location.Location!);
+ method public void setLatLong(double, double);
+ field public static final short ALTITUDE_ABOVE_SEA_LEVEL = 0; // 0x0
+ field public static final short ALTITUDE_BELOW_SEA_LEVEL = 1; // 0x1
+ field public static final int[]! BITS_PER_SAMPLE_GREYSCALE_1;
+ field public static final int[]! BITS_PER_SAMPLE_GREYSCALE_2;
+ field public static final int[]! BITS_PER_SAMPLE_RGB;
+ field public static final int COLOR_SPACE_S_RGB = 1; // 0x1
+ field public static final int COLOR_SPACE_UNCALIBRATED = 65535; // 0xffff
+ field public static final short CONTRAST_HARD = 2; // 0x2
+ field public static final short CONTRAST_NORMAL = 0; // 0x0
+ field public static final short CONTRAST_SOFT = 1; // 0x1
+ field public static final int DATA_DEFLATE_ZIP = 8; // 0x8
+ field public static final int DATA_HUFFMAN_COMPRESSED = 2; // 0x2
+ field public static final int DATA_JPEG = 6; // 0x6
+ field public static final int DATA_JPEG_COMPRESSED = 7; // 0x7
+ field public static final int DATA_LOSSY_JPEG = 34892; // 0x884c
+ field public static final int DATA_PACK_BITS_COMPRESSED = 32773; // 0x8005
+ field public static final int DATA_UNCOMPRESSED = 1; // 0x1
+ field public static final short EXPOSURE_MODE_AUTO = 0; // 0x0
+ field public static final short EXPOSURE_MODE_AUTO_BRACKET = 2; // 0x2
+ field public static final short EXPOSURE_MODE_MANUAL = 1; // 0x1
+ field public static final short EXPOSURE_PROGRAM_ACTION = 6; // 0x6
+ field public static final short EXPOSURE_PROGRAM_APERTURE_PRIORITY = 3; // 0x3
+ field public static final short EXPOSURE_PROGRAM_CREATIVE = 5; // 0x5
+ field public static final short EXPOSURE_PROGRAM_LANDSCAPE_MODE = 8; // 0x8
+ field public static final short EXPOSURE_PROGRAM_MANUAL = 1; // 0x1
+ field public static final short EXPOSURE_PROGRAM_NORMAL = 2; // 0x2
+ field public static final short EXPOSURE_PROGRAM_NOT_DEFINED = 0; // 0x0
+ field public static final short EXPOSURE_PROGRAM_PORTRAIT_MODE = 7; // 0x7
+ field public static final short EXPOSURE_PROGRAM_SHUTTER_PRIORITY = 4; // 0x4
+ field public static final short FILE_SOURCE_DSC = 3; // 0x3
+ field public static final short FILE_SOURCE_OTHER = 0; // 0x0
+ field public static final short FILE_SOURCE_REFLEX_SCANNER = 2; // 0x2
+ field public static final short FILE_SOURCE_TRANSPARENT_SCANNER = 1; // 0x1
+ field public static final short FLAG_FLASH_FIRED = 1; // 0x1
+ field public static final short FLAG_FLASH_MODE_AUTO = 24; // 0x18
+ field public static final short FLAG_FLASH_MODE_COMPULSORY_FIRING = 8; // 0x8
+ field public static final short FLAG_FLASH_MODE_COMPULSORY_SUPPRESSION = 16; // 0x10
+ field public static final short FLAG_FLASH_NO_FLASH_FUNCTION = 32; // 0x20
+ field public static final short FLAG_FLASH_RED_EYE_SUPPORTED = 64; // 0x40
+ field public static final short FLAG_FLASH_RETURN_LIGHT_DETECTED = 6; // 0x6
+ field public static final short FLAG_FLASH_RETURN_LIGHT_NOT_DETECTED = 4; // 0x4
+ field public static final short FORMAT_CHUNKY = 1; // 0x1
+ field public static final short FORMAT_PLANAR = 2; // 0x2
+ field public static final short GAIN_CONTROL_HIGH_GAIN_DOWN = 4; // 0x4
+ field public static final short GAIN_CONTROL_HIGH_GAIN_UP = 2; // 0x2
+ field public static final short GAIN_CONTROL_LOW_GAIN_DOWN = 3; // 0x3
+ field public static final short GAIN_CONTROL_LOW_GAIN_UP = 1; // 0x1
+ field public static final short GAIN_CONTROL_NONE = 0; // 0x0
+ field public static final String GPS_DIRECTION_MAGNETIC = "M";
+ field public static final String GPS_DIRECTION_TRUE = "T";
+ field public static final String GPS_DISTANCE_KILOMETERS = "K";
+ field public static final String GPS_DISTANCE_MILES = "M";
+ field public static final String GPS_DISTANCE_NAUTICAL_MILES = "N";
+ field public static final String GPS_MEASUREMENT_2D = "2";
+ field public static final String GPS_MEASUREMENT_3D = "3";
+ field public static final short GPS_MEASUREMENT_DIFFERENTIAL_CORRECTED = 1; // 0x1
+ field public static final String GPS_MEASUREMENT_INTERRUPTED = "V";
+ field public static final String GPS_MEASUREMENT_IN_PROGRESS = "A";
+ field public static final short GPS_MEASUREMENT_NO_DIFFERENTIAL = 0; // 0x0
+ field public static final String GPS_SPEED_KILOMETERS_PER_HOUR = "K";
+ field public static final String GPS_SPEED_KNOTS = "N";
+ field public static final String GPS_SPEED_MILES_PER_HOUR = "M";
+ field public static final String LATITUDE_NORTH = "N";
+ field public static final String LATITUDE_SOUTH = "S";
+ field public static final short LIGHT_SOURCE_CLOUDY_WEATHER = 10; // 0xa
+ field public static final short LIGHT_SOURCE_COOL_WHITE_FLUORESCENT = 14; // 0xe
+ field public static final short LIGHT_SOURCE_D50 = 23; // 0x17
+ field public static final short LIGHT_SOURCE_D55 = 20; // 0x14
+ field public static final short LIGHT_SOURCE_D65 = 21; // 0x15
+ field public static final short LIGHT_SOURCE_D75 = 22; // 0x16
+ field public static final short LIGHT_SOURCE_DAYLIGHT = 1; // 0x1
+ field public static final short LIGHT_SOURCE_DAYLIGHT_FLUORESCENT = 12; // 0xc
+ field public static final short LIGHT_SOURCE_DAY_WHITE_FLUORESCENT = 13; // 0xd
+ field public static final short LIGHT_SOURCE_FINE_WEATHER = 9; // 0x9
+ field public static final short LIGHT_SOURCE_FLASH = 4; // 0x4
+ field public static final short LIGHT_SOURCE_FLUORESCENT = 2; // 0x2
+ field public static final short LIGHT_SOURCE_ISO_STUDIO_TUNGSTEN = 24; // 0x18
+ field public static final short LIGHT_SOURCE_OTHER = 255; // 0xff
+ field public static final short LIGHT_SOURCE_SHADE = 11; // 0xb
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_A = 17; // 0x11
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_B = 18; // 0x12
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_C = 19; // 0x13
+ field public static final short LIGHT_SOURCE_TUNGSTEN = 3; // 0x3
+ field public static final short LIGHT_SOURCE_UNKNOWN = 0; // 0x0
+ field public static final short LIGHT_SOURCE_WARM_WHITE_FLUORESCENT = 16; // 0x10
+ field public static final short LIGHT_SOURCE_WHITE_FLUORESCENT = 15; // 0xf
+ field public static final String LONGITUDE_EAST = "E";
+ field public static final String LONGITUDE_WEST = "W";
+ field public static final short METERING_MODE_AVERAGE = 1; // 0x1
+ field public static final short METERING_MODE_CENTER_WEIGHT_AVERAGE = 2; // 0x2
+ field public static final short METERING_MODE_MULTI_SPOT = 4; // 0x4
+ field public static final short METERING_MODE_OTHER = 255; // 0xff
+ field public static final short METERING_MODE_PARTIAL = 6; // 0x6
+ field public static final short METERING_MODE_PATTERN = 5; // 0x5
+ field public static final short METERING_MODE_SPOT = 3; // 0x3
+ field public static final short METERING_MODE_UNKNOWN = 0; // 0x0
+ field public static final int ORIENTATION_FLIP_HORIZONTAL = 2; // 0x2
+ field public static final int ORIENTATION_FLIP_VERTICAL = 4; // 0x4
+ field public static final int ORIENTATION_NORMAL = 1; // 0x1
+ field public static final int ORIENTATION_ROTATE_180 = 3; // 0x3
+ field public static final int ORIENTATION_ROTATE_270 = 8; // 0x8
+ field public static final int ORIENTATION_ROTATE_90 = 6; // 0x6
+ field public static final int ORIENTATION_TRANSPOSE = 5; // 0x5
+ field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7
+ field public static final int ORIENTATION_UNDEFINED = 0; // 0x0
+ field public static final int ORIGINAL_RESOLUTION_IMAGE = 0; // 0x0
+ field public static final int PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO = 1; // 0x1
+ field public static final int PHOTOMETRIC_INTERPRETATION_RGB = 2; // 0x2
+ field public static final int PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO = 0; // 0x0
+ field public static final int PHOTOMETRIC_INTERPRETATION_YCBCR = 6; // 0x6
+ field public static final int REDUCED_RESOLUTION_IMAGE = 1; // 0x1
+ field public static final short RENDERED_PROCESS_CUSTOM = 1; // 0x1
+ field public static final short RENDERED_PROCESS_NORMAL = 0; // 0x0
+ field public static final short RESOLUTION_UNIT_CENTIMETERS = 3; // 0x3
+ field public static final short RESOLUTION_UNIT_INCHES = 2; // 0x2
+ field public static final short SATURATION_HIGH = 0; // 0x0
+ field public static final short SATURATION_LOW = 0; // 0x0
+ field public static final short SATURATION_NORMAL = 0; // 0x0
+ field public static final short SCENE_CAPTURE_TYPE_LANDSCAPE = 1; // 0x1
+ field public static final short SCENE_CAPTURE_TYPE_NIGHT = 3; // 0x3
+ field public static final short SCENE_CAPTURE_TYPE_PORTRAIT = 2; // 0x2
+ field public static final short SCENE_CAPTURE_TYPE_STANDARD = 0; // 0x0
+ field public static final short SCENE_TYPE_DIRECTLY_PHOTOGRAPHED = 1; // 0x1
+ field public static final short SENSITIVITY_TYPE_ISO_SPEED = 3; // 0x3
+ field public static final short SENSITIVITY_TYPE_REI = 2; // 0x2
+ field public static final short SENSITIVITY_TYPE_REI_AND_ISO = 6; // 0x6
+ field public static final short SENSITIVITY_TYPE_SOS = 1; // 0x1
+ field public static final short SENSITIVITY_TYPE_SOS_AND_ISO = 5; // 0x5
+ field public static final short SENSITIVITY_TYPE_SOS_AND_REI = 4; // 0x4
+ field public static final short SENSITIVITY_TYPE_SOS_AND_REI_AND_ISO = 7; // 0x7
+ field public static final short SENSITIVITY_TYPE_UNKNOWN = 0; // 0x0
+ field public static final short SENSOR_TYPE_COLOR_SEQUENTIAL = 5; // 0x5
+ field public static final short SENSOR_TYPE_COLOR_SEQUENTIAL_LINEAR = 8; // 0x8
+ field public static final short SENSOR_TYPE_NOT_DEFINED = 1; // 0x1
+ field public static final short SENSOR_TYPE_ONE_CHIP = 2; // 0x2
+ field public static final short SENSOR_TYPE_THREE_CHIP = 4; // 0x4
+ field public static final short SENSOR_TYPE_TRILINEAR = 7; // 0x7
+ field public static final short SENSOR_TYPE_TWO_CHIP = 3; // 0x3
+ field public static final short SHARPNESS_HARD = 2; // 0x2
+ field public static final short SHARPNESS_NORMAL = 0; // 0x0
+ field public static final short SHARPNESS_SOFT = 1; // 0x1
+ field public static final int STREAM_TYPE_EXIF_DATA_ONLY = 1; // 0x1
+ field public static final int STREAM_TYPE_FULL_IMAGE_DATA = 0; // 0x0
+ field public static final short SUBJECT_DISTANCE_RANGE_CLOSE_VIEW = 2; // 0x2
+ field public static final short SUBJECT_DISTANCE_RANGE_DISTANT_VIEW = 3; // 0x3
+ field public static final short SUBJECT_DISTANCE_RANGE_MACRO = 1; // 0x1
+ field public static final short SUBJECT_DISTANCE_RANGE_UNKNOWN = 0; // 0x0
+ field public static final String TAG_APERTURE_VALUE = "ApertureValue";
+ field public static final String TAG_ARTIST = "Artist";
+ field public static final String TAG_BITS_PER_SAMPLE = "BitsPerSample";
+ field public static final String TAG_BODY_SERIAL_NUMBER = "BodySerialNumber";
+ field public static final String TAG_BRIGHTNESS_VALUE = "BrightnessValue";
+ field @Deprecated public static final String TAG_CAMARA_OWNER_NAME = "CameraOwnerName";
+ field public static final String TAG_CAMERA_OWNER_NAME = "CameraOwnerName";
+ field public static final String TAG_CFA_PATTERN = "CFAPattern";
+ field public static final String TAG_COLOR_SPACE = "ColorSpace";
+ field public static final String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration";
+ field public static final String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel";
+ field public static final String TAG_COMPRESSION = "Compression";
+ field public static final String TAG_CONTRAST = "Contrast";
+ field public static final String TAG_COPYRIGHT = "Copyright";
+ field public static final String TAG_CUSTOM_RENDERED = "CustomRendered";
+ field public static final String TAG_DATETIME = "DateTime";
+ field public static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
+ field public static final String TAG_DATETIME_ORIGINAL = "DateTimeOriginal";
+ field public static final String TAG_DEFAULT_CROP_SIZE = "DefaultCropSize";
+ field public static final String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription";
+ field public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio";
+ field public static final String TAG_DNG_VERSION = "DNGVersion";
+ field public static final String TAG_EXIF_VERSION = "ExifVersion";
+ field public static final String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue";
+ field public static final String TAG_EXPOSURE_INDEX = "ExposureIndex";
+ field public static final String TAG_EXPOSURE_MODE = "ExposureMode";
+ field public static final String TAG_EXPOSURE_PROGRAM = "ExposureProgram";
+ field public static final String TAG_EXPOSURE_TIME = "ExposureTime";
+ field public static final String TAG_FILE_SOURCE = "FileSource";
+ field public static final String TAG_FLASH = "Flash";
+ field public static final String TAG_FLASHPIX_VERSION = "FlashpixVersion";
+ field public static final String TAG_FLASH_ENERGY = "FlashEnergy";
+ field public static final String TAG_FOCAL_LENGTH = "FocalLength";
+ field public static final String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm";
+ field public static final String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit";
+ field public static final String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution";
+ field public static final String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution";
+ field public static final String TAG_F_NUMBER = "FNumber";
+ field public static final String TAG_GAIN_CONTROL = "GainControl";
+ field public static final String TAG_GAMMA = "Gamma";
+ field public static final String TAG_GPS_ALTITUDE = "GPSAltitude";
+ field public static final String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef";
+ field public static final String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation";
+ field public static final String TAG_GPS_DATESTAMP = "GPSDateStamp";
+ field public static final String TAG_GPS_DEST_BEARING = "GPSDestBearing";
+ field public static final String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef";
+ field public static final String TAG_GPS_DEST_DISTANCE = "GPSDestDistance";
+ field public static final String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef";
+ field public static final String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude";
+ field public static final String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef";
+ field public static final String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude";
+ field public static final String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef";
+ field public static final String TAG_GPS_DIFFERENTIAL = "GPSDifferential";
+ field public static final String TAG_GPS_DOP = "GPSDOP";
+ field public static final String TAG_GPS_H_POSITIONING_ERROR = "GPSHPositioningError";
+ field public static final String TAG_GPS_IMG_DIRECTION = "GPSImgDirection";
+ field public static final String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef";
+ field public static final String TAG_GPS_LATITUDE = "GPSLatitude";
+ field public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
+ field public static final String TAG_GPS_LONGITUDE = "GPSLongitude";
+ field public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
+ field public static final String TAG_GPS_MAP_DATUM = "GPSMapDatum";
+ field public static final String TAG_GPS_MEASURE_MODE = "GPSMeasureMode";
+ field public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
+ field public static final String TAG_GPS_SATELLITES = "GPSSatellites";
+ field public static final String TAG_GPS_SPEED = "GPSSpeed";
+ field public static final String TAG_GPS_SPEED_REF = "GPSSpeedRef";
+ field public static final String TAG_GPS_STATUS = "GPSStatus";
+ field public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
+ field public static final String TAG_GPS_TRACK = "GPSTrack";
+ field public static final String TAG_GPS_TRACK_REF = "GPSTrackRef";
+ field public static final String TAG_GPS_VERSION_ID = "GPSVersionID";
+ field public static final String TAG_IMAGE_DESCRIPTION = "ImageDescription";
+ field public static final String TAG_IMAGE_LENGTH = "ImageLength";
+ field public static final String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID";
+ field public static final String TAG_IMAGE_WIDTH = "ImageWidth";
+ field public static final String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex";
+ field public static final String TAG_ISO_SPEED = "ISOSpeed";
+ field public static final String TAG_ISO_SPEED_LATITUDE_YYY = "ISOSpeedLatitudeyyy";
+ field public static final String TAG_ISO_SPEED_LATITUDE_ZZZ = "ISOSpeedLatitudezzz";
+ field @Deprecated public static final String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings";
+ field public static final String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat";
+ field public static final String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength";
+ field public static final String TAG_LENS_MAKE = "LensMake";
+ field public static final String TAG_LENS_MODEL = "LensModel";
+ field public static final String TAG_LENS_SERIAL_NUMBER = "LensSerialNumber";
+ field public static final String TAG_LENS_SPECIFICATION = "LensSpecification";
+ field public static final String TAG_LIGHT_SOURCE = "LightSource";
+ field public static final String TAG_MAKE = "Make";
+ field public static final String TAG_MAKER_NOTE = "MakerNote";
+ field public static final String TAG_MAX_APERTURE_VALUE = "MaxApertureValue";
+ field public static final String TAG_METERING_MODE = "MeteringMode";
+ field public static final String TAG_MODEL = "Model";
+ field public static final String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
+ field public static final String TAG_OECF = "OECF";
+ field public static final String TAG_OFFSET_TIME = "OffsetTime";
+ field public static final String TAG_OFFSET_TIME_DIGITIZED = "OffsetTimeDigitized";
+ field public static final String TAG_OFFSET_TIME_ORIGINAL = "OffsetTimeOriginal";
+ field public static final String TAG_ORF_ASPECT_FRAME = "AspectFrame";
+ field public static final String TAG_ORF_PREVIEW_IMAGE_LENGTH = "PreviewImageLength";
+ field public static final String TAG_ORF_PREVIEW_IMAGE_START = "PreviewImageStart";
+ field public static final String TAG_ORF_THUMBNAIL_IMAGE = "ThumbnailImage";
+ field public static final String TAG_ORIENTATION = "Orientation";
+ field public static final String TAG_PHOTOGRAPHIC_SENSITIVITY = "PhotographicSensitivity";
+ field public static final String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation";
+ field public static final String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
+ field public static final String TAG_PIXEL_Y_DIMENSION = "PixelYDimension";
+ field public static final String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration";
+ field public static final String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities";
+ field public static final String TAG_RECOMMENDED_EXPOSURE_INDEX = "RecommendedExposureIndex";
+ field public static final String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite";
+ field public static final String TAG_RELATED_SOUND_FILE = "RelatedSoundFile";
+ field public static final String TAG_RESOLUTION_UNIT = "ResolutionUnit";
+ field public static final String TAG_ROWS_PER_STRIP = "RowsPerStrip";
+ field public static final String TAG_RW2_ISO = "ISO";
+ field public static final String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
+ field public static final String TAG_RW2_SENSOR_BOTTOM_BORDER = "SensorBottomBorder";
+ field public static final String TAG_RW2_SENSOR_LEFT_BORDER = "SensorLeftBorder";
+ field public static final String TAG_RW2_SENSOR_RIGHT_BORDER = "SensorRightBorder";
+ field public static final String TAG_RW2_SENSOR_TOP_BORDER = "SensorTopBorder";
+ field public static final String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel";
+ field public static final String TAG_SATURATION = "Saturation";
+ field public static final String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType";
+ field public static final String TAG_SCENE_TYPE = "SceneType";
+ field public static final String TAG_SENSING_METHOD = "SensingMethod";
+ field public static final String TAG_SENSITIVITY_TYPE = "SensitivityType";
+ field public static final String TAG_SHARPNESS = "Sharpness";
+ field public static final String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue";
+ field public static final String TAG_SOFTWARE = "Software";
+ field public static final String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse";
+ field public static final String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity";
+ field public static final String TAG_STANDARD_OUTPUT_SENSITIVITY = "StandardOutputSensitivity";
+ field public static final String TAG_STRIP_BYTE_COUNTS = "StripByteCounts";
+ field public static final String TAG_STRIP_OFFSETS = "StripOffsets";
+ field public static final String TAG_SUBFILE_TYPE = "SubfileType";
+ field public static final String TAG_SUBJECT_AREA = "SubjectArea";
+ field public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance";
+ field public static final String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange";
+ field public static final String TAG_SUBJECT_LOCATION = "SubjectLocation";
+ field public static final String TAG_SUBSEC_TIME = "SubSecTime";
+ field public static final String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized";
+ field public static final String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
+ field public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
+ field public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+ field public static final String TAG_TRANSFER_FUNCTION = "TransferFunction";
+ field public static final String TAG_USER_COMMENT = "UserComment";
+ field public static final String TAG_WHITE_BALANCE = "WhiteBalance";
+ field public static final String TAG_WHITE_POINT = "WhitePoint";
+ field public static final String TAG_XMP = "Xmp";
+ field public static final String TAG_X_RESOLUTION = "XResolution";
+ field public static final String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
+ field public static final String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
+ field public static final String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling";
+ field public static final String TAG_Y_RESOLUTION = "YResolution";
+ field @Deprecated public static final int WHITEBALANCE_AUTO = 0; // 0x0
+ field @Deprecated public static final int WHITEBALANCE_MANUAL = 1; // 0x1
+ field public static final short WHITE_BALANCE_AUTO = 0; // 0x0
+ field public static final short WHITE_BALANCE_MANUAL = 1; // 0x1
+ field public static final short Y_CB_CR_POSITIONING_CENTERED = 1; // 0x1
+ field public static final short Y_CB_CR_POSITIONING_CO_SITED = 2; // 0x2
+ }
+
+}
+
diff --git a/exifinterface/api/public_plus_experimental_1.2.0-beta01.txt b/exifinterface/api/public_plus_experimental_1.2.0-beta01.txt
new file mode 100644
index 0000000..4bbc2ba
--- /dev/null
+++ b/exifinterface/api/public_plus_experimental_1.2.0-beta01.txt
@@ -0,0 +1,347 @@
+// Signature format: 3.0
+package androidx.exifinterface.media {
+
+ public class ExifInterface {
+ ctor public ExifInterface(java.io.File) throws java.io.IOException;
+ ctor public ExifInterface(String) throws java.io.IOException;
+ ctor public ExifInterface(java.io.FileDescriptor) throws java.io.IOException;
+ ctor public ExifInterface(java.io.InputStream) throws java.io.IOException;
+ ctor public ExifInterface(java.io.InputStream, int) throws java.io.IOException;
+ method public void flipHorizontally();
+ method public void flipVertically();
+ method public double getAltitude(double);
+ method public String? getAttribute(String);
+ method public byte[]? getAttributeBytes(String);
+ method public double getAttributeDouble(String, double);
+ method public int getAttributeInt(String, int);
+ method public long[]? getAttributeRange(String);
+ method @Deprecated public boolean getLatLong(float[]!);
+ method public double[]? getLatLong();
+ method public int getRotationDegrees();
+ method public byte[]? getThumbnail();
+ method public android.graphics.Bitmap? getThumbnailBitmap();
+ method public byte[]? getThumbnailBytes();
+ method public long[]? getThumbnailRange();
+ method public boolean hasAttribute(String);
+ method public boolean hasThumbnail();
+ method public boolean isFlipped();
+ method public static boolean isSupportedMimeType(String);
+ method public boolean isThumbnailCompressed();
+ method public void resetOrientation();
+ method public void rotate(int);
+ method public void saveAttributes() throws java.io.IOException;
+ method public void setAltitude(double);
+ method public void setAttribute(String, String?);
+ method public void setGpsInfo(android.location.Location!);
+ method public void setLatLong(double, double);
+ field public static final short ALTITUDE_ABOVE_SEA_LEVEL = 0; // 0x0
+ field public static final short ALTITUDE_BELOW_SEA_LEVEL = 1; // 0x1
+ field public static final int[]! BITS_PER_SAMPLE_GREYSCALE_1;
+ field public static final int[]! BITS_PER_SAMPLE_GREYSCALE_2;
+ field public static final int[]! BITS_PER_SAMPLE_RGB;
+ field public static final int COLOR_SPACE_S_RGB = 1; // 0x1
+ field public static final int COLOR_SPACE_UNCALIBRATED = 65535; // 0xffff
+ field public static final short CONTRAST_HARD = 2; // 0x2
+ field public static final short CONTRAST_NORMAL = 0; // 0x0
+ field public static final short CONTRAST_SOFT = 1; // 0x1
+ field public static final int DATA_DEFLATE_ZIP = 8; // 0x8
+ field public static final int DATA_HUFFMAN_COMPRESSED = 2; // 0x2
+ field public static final int DATA_JPEG = 6; // 0x6
+ field public static final int DATA_JPEG_COMPRESSED = 7; // 0x7
+ field public static final int DATA_LOSSY_JPEG = 34892; // 0x884c
+ field public static final int DATA_PACK_BITS_COMPRESSED = 32773; // 0x8005
+ field public static final int DATA_UNCOMPRESSED = 1; // 0x1
+ field public static final short EXPOSURE_MODE_AUTO = 0; // 0x0
+ field public static final short EXPOSURE_MODE_AUTO_BRACKET = 2; // 0x2
+ field public static final short EXPOSURE_MODE_MANUAL = 1; // 0x1
+ field public static final short EXPOSURE_PROGRAM_ACTION = 6; // 0x6
+ field public static final short EXPOSURE_PROGRAM_APERTURE_PRIORITY = 3; // 0x3
+ field public static final short EXPOSURE_PROGRAM_CREATIVE = 5; // 0x5
+ field public static final short EXPOSURE_PROGRAM_LANDSCAPE_MODE = 8; // 0x8
+ field public static final short EXPOSURE_PROGRAM_MANUAL = 1; // 0x1
+ field public static final short EXPOSURE_PROGRAM_NORMAL = 2; // 0x2
+ field public static final short EXPOSURE_PROGRAM_NOT_DEFINED = 0; // 0x0
+ field public static final short EXPOSURE_PROGRAM_PORTRAIT_MODE = 7; // 0x7
+ field public static final short EXPOSURE_PROGRAM_SHUTTER_PRIORITY = 4; // 0x4
+ field public static final short FILE_SOURCE_DSC = 3; // 0x3
+ field public static final short FILE_SOURCE_OTHER = 0; // 0x0
+ field public static final short FILE_SOURCE_REFLEX_SCANNER = 2; // 0x2
+ field public static final short FILE_SOURCE_TRANSPARENT_SCANNER = 1; // 0x1
+ field public static final short FLAG_FLASH_FIRED = 1; // 0x1
+ field public static final short FLAG_FLASH_MODE_AUTO = 24; // 0x18
+ field public static final short FLAG_FLASH_MODE_COMPULSORY_FIRING = 8; // 0x8
+ field public static final short FLAG_FLASH_MODE_COMPULSORY_SUPPRESSION = 16; // 0x10
+ field public static final short FLAG_FLASH_NO_FLASH_FUNCTION = 32; // 0x20
+ field public static final short FLAG_FLASH_RED_EYE_SUPPORTED = 64; // 0x40
+ field public static final short FLAG_FLASH_RETURN_LIGHT_DETECTED = 6; // 0x6
+ field public static final short FLAG_FLASH_RETURN_LIGHT_NOT_DETECTED = 4; // 0x4
+ field public static final short FORMAT_CHUNKY = 1; // 0x1
+ field public static final short FORMAT_PLANAR = 2; // 0x2
+ field public static final short GAIN_CONTROL_HIGH_GAIN_DOWN = 4; // 0x4
+ field public static final short GAIN_CONTROL_HIGH_GAIN_UP = 2; // 0x2
+ field public static final short GAIN_CONTROL_LOW_GAIN_DOWN = 3; // 0x3
+ field public static final short GAIN_CONTROL_LOW_GAIN_UP = 1; // 0x1
+ field public static final short GAIN_CONTROL_NONE = 0; // 0x0
+ field public static final String GPS_DIRECTION_MAGNETIC = "M";
+ field public static final String GPS_DIRECTION_TRUE = "T";
+ field public static final String GPS_DISTANCE_KILOMETERS = "K";
+ field public static final String GPS_DISTANCE_MILES = "M";
+ field public static final String GPS_DISTANCE_NAUTICAL_MILES = "N";
+ field public static final String GPS_MEASUREMENT_2D = "2";
+ field public static final String GPS_MEASUREMENT_3D = "3";
+ field public static final short GPS_MEASUREMENT_DIFFERENTIAL_CORRECTED = 1; // 0x1
+ field public static final String GPS_MEASUREMENT_INTERRUPTED = "V";
+ field public static final String GPS_MEASUREMENT_IN_PROGRESS = "A";
+ field public static final short GPS_MEASUREMENT_NO_DIFFERENTIAL = 0; // 0x0
+ field public static final String GPS_SPEED_KILOMETERS_PER_HOUR = "K";
+ field public static final String GPS_SPEED_KNOTS = "N";
+ field public static final String GPS_SPEED_MILES_PER_HOUR = "M";
+ field public static final String LATITUDE_NORTH = "N";
+ field public static final String LATITUDE_SOUTH = "S";
+ field public static final short LIGHT_SOURCE_CLOUDY_WEATHER = 10; // 0xa
+ field public static final short LIGHT_SOURCE_COOL_WHITE_FLUORESCENT = 14; // 0xe
+ field public static final short LIGHT_SOURCE_D50 = 23; // 0x17
+ field public static final short LIGHT_SOURCE_D55 = 20; // 0x14
+ field public static final short LIGHT_SOURCE_D65 = 21; // 0x15
+ field public static final short LIGHT_SOURCE_D75 = 22; // 0x16
+ field public static final short LIGHT_SOURCE_DAYLIGHT = 1; // 0x1
+ field public static final short LIGHT_SOURCE_DAYLIGHT_FLUORESCENT = 12; // 0xc
+ field public static final short LIGHT_SOURCE_DAY_WHITE_FLUORESCENT = 13; // 0xd
+ field public static final short LIGHT_SOURCE_FINE_WEATHER = 9; // 0x9
+ field public static final short LIGHT_SOURCE_FLASH = 4; // 0x4
+ field public static final short LIGHT_SOURCE_FLUORESCENT = 2; // 0x2
+ field public static final short LIGHT_SOURCE_ISO_STUDIO_TUNGSTEN = 24; // 0x18
+ field public static final short LIGHT_SOURCE_OTHER = 255; // 0xff
+ field public static final short LIGHT_SOURCE_SHADE = 11; // 0xb
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_A = 17; // 0x11
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_B = 18; // 0x12
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_C = 19; // 0x13
+ field public static final short LIGHT_SOURCE_TUNGSTEN = 3; // 0x3
+ field public static final short LIGHT_SOURCE_UNKNOWN = 0; // 0x0
+ field public static final short LIGHT_SOURCE_WARM_WHITE_FLUORESCENT = 16; // 0x10
+ field public static final short LIGHT_SOURCE_WHITE_FLUORESCENT = 15; // 0xf
+ field public static final String LONGITUDE_EAST = "E";
+ field public static final String LONGITUDE_WEST = "W";
+ field public static final short METERING_MODE_AVERAGE = 1; // 0x1
+ field public static final short METERING_MODE_CENTER_WEIGHT_AVERAGE = 2; // 0x2
+ field public static final short METERING_MODE_MULTI_SPOT = 4; // 0x4
+ field public static final short METERING_MODE_OTHER = 255; // 0xff
+ field public static final short METERING_MODE_PARTIAL = 6; // 0x6
+ field public static final short METERING_MODE_PATTERN = 5; // 0x5
+ field public static final short METERING_MODE_SPOT = 3; // 0x3
+ field public static final short METERING_MODE_UNKNOWN = 0; // 0x0
+ field public static final int ORIENTATION_FLIP_HORIZONTAL = 2; // 0x2
+ field public static final int ORIENTATION_FLIP_VERTICAL = 4; // 0x4
+ field public static final int ORIENTATION_NORMAL = 1; // 0x1
+ field public static final int ORIENTATION_ROTATE_180 = 3; // 0x3
+ field public static final int ORIENTATION_ROTATE_270 = 8; // 0x8
+ field public static final int ORIENTATION_ROTATE_90 = 6; // 0x6
+ field public static final int ORIENTATION_TRANSPOSE = 5; // 0x5
+ field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7
+ field public static final int ORIENTATION_UNDEFINED = 0; // 0x0
+ field public static final int ORIGINAL_RESOLUTION_IMAGE = 0; // 0x0
+ field public static final int PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO = 1; // 0x1
+ field public static final int PHOTOMETRIC_INTERPRETATION_RGB = 2; // 0x2
+ field public static final int PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO = 0; // 0x0
+ field public static final int PHOTOMETRIC_INTERPRETATION_YCBCR = 6; // 0x6
+ field public static final int REDUCED_RESOLUTION_IMAGE = 1; // 0x1
+ field public static final short RENDERED_PROCESS_CUSTOM = 1; // 0x1
+ field public static final short RENDERED_PROCESS_NORMAL = 0; // 0x0
+ field public static final short RESOLUTION_UNIT_CENTIMETERS = 3; // 0x3
+ field public static final short RESOLUTION_UNIT_INCHES = 2; // 0x2
+ field public static final short SATURATION_HIGH = 0; // 0x0
+ field public static final short SATURATION_LOW = 0; // 0x0
+ field public static final short SATURATION_NORMAL = 0; // 0x0
+ field public static final short SCENE_CAPTURE_TYPE_LANDSCAPE = 1; // 0x1
+ field public static final short SCENE_CAPTURE_TYPE_NIGHT = 3; // 0x3
+ field public static final short SCENE_CAPTURE_TYPE_PORTRAIT = 2; // 0x2
+ field public static final short SCENE_CAPTURE_TYPE_STANDARD = 0; // 0x0
+ field public static final short SCENE_TYPE_DIRECTLY_PHOTOGRAPHED = 1; // 0x1
+ field public static final short SENSITIVITY_TYPE_ISO_SPEED = 3; // 0x3
+ field public static final short SENSITIVITY_TYPE_REI = 2; // 0x2
+ field public static final short SENSITIVITY_TYPE_REI_AND_ISO = 6; // 0x6
+ field public static final short SENSITIVITY_TYPE_SOS = 1; // 0x1
+ field public static final short SENSITIVITY_TYPE_SOS_AND_ISO = 5; // 0x5
+ field public static final short SENSITIVITY_TYPE_SOS_AND_REI = 4; // 0x4
+ field public static final short SENSITIVITY_TYPE_SOS_AND_REI_AND_ISO = 7; // 0x7
+ field public static final short SENSITIVITY_TYPE_UNKNOWN = 0; // 0x0
+ field public static final short SENSOR_TYPE_COLOR_SEQUENTIAL = 5; // 0x5
+ field public static final short SENSOR_TYPE_COLOR_SEQUENTIAL_LINEAR = 8; // 0x8
+ field public static final short SENSOR_TYPE_NOT_DEFINED = 1; // 0x1
+ field public static final short SENSOR_TYPE_ONE_CHIP = 2; // 0x2
+ field public static final short SENSOR_TYPE_THREE_CHIP = 4; // 0x4
+ field public static final short SENSOR_TYPE_TRILINEAR = 7; // 0x7
+ field public static final short SENSOR_TYPE_TWO_CHIP = 3; // 0x3
+ field public static final short SHARPNESS_HARD = 2; // 0x2
+ field public static final short SHARPNESS_NORMAL = 0; // 0x0
+ field public static final short SHARPNESS_SOFT = 1; // 0x1
+ field public static final int STREAM_TYPE_EXIF_DATA_ONLY = 1; // 0x1
+ field public static final int STREAM_TYPE_FULL_IMAGE_DATA = 0; // 0x0
+ field public static final short SUBJECT_DISTANCE_RANGE_CLOSE_VIEW = 2; // 0x2
+ field public static final short SUBJECT_DISTANCE_RANGE_DISTANT_VIEW = 3; // 0x3
+ field public static final short SUBJECT_DISTANCE_RANGE_MACRO = 1; // 0x1
+ field public static final short SUBJECT_DISTANCE_RANGE_UNKNOWN = 0; // 0x0
+ field public static final String TAG_APERTURE_VALUE = "ApertureValue";
+ field public static final String TAG_ARTIST = "Artist";
+ field public static final String TAG_BITS_PER_SAMPLE = "BitsPerSample";
+ field public static final String TAG_BODY_SERIAL_NUMBER = "BodySerialNumber";
+ field public static final String TAG_BRIGHTNESS_VALUE = "BrightnessValue";
+ field @Deprecated public static final String TAG_CAMARA_OWNER_NAME = "CameraOwnerName";
+ field public static final String TAG_CAMERA_OWNER_NAME = "CameraOwnerName";
+ field public static final String TAG_CFA_PATTERN = "CFAPattern";
+ field public static final String TAG_COLOR_SPACE = "ColorSpace";
+ field public static final String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration";
+ field public static final String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel";
+ field public static final String TAG_COMPRESSION = "Compression";
+ field public static final String TAG_CONTRAST = "Contrast";
+ field public static final String TAG_COPYRIGHT = "Copyright";
+ field public static final String TAG_CUSTOM_RENDERED = "CustomRendered";
+ field public static final String TAG_DATETIME = "DateTime";
+ field public static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
+ field public static final String TAG_DATETIME_ORIGINAL = "DateTimeOriginal";
+ field public static final String TAG_DEFAULT_CROP_SIZE = "DefaultCropSize";
+ field public static final String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription";
+ field public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio";
+ field public static final String TAG_DNG_VERSION = "DNGVersion";
+ field public static final String TAG_EXIF_VERSION = "ExifVersion";
+ field public static final String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue";
+ field public static final String TAG_EXPOSURE_INDEX = "ExposureIndex";
+ field public static final String TAG_EXPOSURE_MODE = "ExposureMode";
+ field public static final String TAG_EXPOSURE_PROGRAM = "ExposureProgram";
+ field public static final String TAG_EXPOSURE_TIME = "ExposureTime";
+ field public static final String TAG_FILE_SOURCE = "FileSource";
+ field public static final String TAG_FLASH = "Flash";
+ field public static final String TAG_FLASHPIX_VERSION = "FlashpixVersion";
+ field public static final String TAG_FLASH_ENERGY = "FlashEnergy";
+ field public static final String TAG_FOCAL_LENGTH = "FocalLength";
+ field public static final String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm";
+ field public static final String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit";
+ field public static final String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution";
+ field public static final String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution";
+ field public static final String TAG_F_NUMBER = "FNumber";
+ field public static final String TAG_GAIN_CONTROL = "GainControl";
+ field public static final String TAG_GAMMA = "Gamma";
+ field public static final String TAG_GPS_ALTITUDE = "GPSAltitude";
+ field public static final String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef";
+ field public static final String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation";
+ field public static final String TAG_GPS_DATESTAMP = "GPSDateStamp";
+ field public static final String TAG_GPS_DEST_BEARING = "GPSDestBearing";
+ field public static final String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef";
+ field public static final String TAG_GPS_DEST_DISTANCE = "GPSDestDistance";
+ field public static final String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef";
+ field public static final String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude";
+ field public static final String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef";
+ field public static final String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude";
+ field public static final String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef";
+ field public static final String TAG_GPS_DIFFERENTIAL = "GPSDifferential";
+ field public static final String TAG_GPS_DOP = "GPSDOP";
+ field public static final String TAG_GPS_H_POSITIONING_ERROR = "GPSHPositioningError";
+ field public static final String TAG_GPS_IMG_DIRECTION = "GPSImgDirection";
+ field public static final String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef";
+ field public static final String TAG_GPS_LATITUDE = "GPSLatitude";
+ field public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
+ field public static final String TAG_GPS_LONGITUDE = "GPSLongitude";
+ field public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
+ field public static final String TAG_GPS_MAP_DATUM = "GPSMapDatum";
+ field public static final String TAG_GPS_MEASURE_MODE = "GPSMeasureMode";
+ field public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
+ field public static final String TAG_GPS_SATELLITES = "GPSSatellites";
+ field public static final String TAG_GPS_SPEED = "GPSSpeed";
+ field public static final String TAG_GPS_SPEED_REF = "GPSSpeedRef";
+ field public static final String TAG_GPS_STATUS = "GPSStatus";
+ field public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
+ field public static final String TAG_GPS_TRACK = "GPSTrack";
+ field public static final String TAG_GPS_TRACK_REF = "GPSTrackRef";
+ field public static final String TAG_GPS_VERSION_ID = "GPSVersionID";
+ field public static final String TAG_IMAGE_DESCRIPTION = "ImageDescription";
+ field public static final String TAG_IMAGE_LENGTH = "ImageLength";
+ field public static final String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID";
+ field public static final String TAG_IMAGE_WIDTH = "ImageWidth";
+ field public static final String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex";
+ field public static final String TAG_ISO_SPEED = "ISOSpeed";
+ field public static final String TAG_ISO_SPEED_LATITUDE_YYY = "ISOSpeedLatitudeyyy";
+ field public static final String TAG_ISO_SPEED_LATITUDE_ZZZ = "ISOSpeedLatitudezzz";
+ field @Deprecated public static final String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings";
+ field public static final String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat";
+ field public static final String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength";
+ field public static final String TAG_LENS_MAKE = "LensMake";
+ field public static final String TAG_LENS_MODEL = "LensModel";
+ field public static final String TAG_LENS_SERIAL_NUMBER = "LensSerialNumber";
+ field public static final String TAG_LENS_SPECIFICATION = "LensSpecification";
+ field public static final String TAG_LIGHT_SOURCE = "LightSource";
+ field public static final String TAG_MAKE = "Make";
+ field public static final String TAG_MAKER_NOTE = "MakerNote";
+ field public static final String TAG_MAX_APERTURE_VALUE = "MaxApertureValue";
+ field public static final String TAG_METERING_MODE = "MeteringMode";
+ field public static final String TAG_MODEL = "Model";
+ field public static final String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
+ field public static final String TAG_OECF = "OECF";
+ field public static final String TAG_OFFSET_TIME = "OffsetTime";
+ field public static final String TAG_OFFSET_TIME_DIGITIZED = "OffsetTimeDigitized";
+ field public static final String TAG_OFFSET_TIME_ORIGINAL = "OffsetTimeOriginal";
+ field public static final String TAG_ORF_ASPECT_FRAME = "AspectFrame";
+ field public static final String TAG_ORF_PREVIEW_IMAGE_LENGTH = "PreviewImageLength";
+ field public static final String TAG_ORF_PREVIEW_IMAGE_START = "PreviewImageStart";
+ field public static final String TAG_ORF_THUMBNAIL_IMAGE = "ThumbnailImage";
+ field public static final String TAG_ORIENTATION = "Orientation";
+ field public static final String TAG_PHOTOGRAPHIC_SENSITIVITY = "PhotographicSensitivity";
+ field public static final String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation";
+ field public static final String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
+ field public static final String TAG_PIXEL_Y_DIMENSION = "PixelYDimension";
+ field public static final String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration";
+ field public static final String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities";
+ field public static final String TAG_RECOMMENDED_EXPOSURE_INDEX = "RecommendedExposureIndex";
+ field public static final String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite";
+ field public static final String TAG_RELATED_SOUND_FILE = "RelatedSoundFile";
+ field public static final String TAG_RESOLUTION_UNIT = "ResolutionUnit";
+ field public static final String TAG_ROWS_PER_STRIP = "RowsPerStrip";
+ field public static final String TAG_RW2_ISO = "ISO";
+ field public static final String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
+ field public static final String TAG_RW2_SENSOR_BOTTOM_BORDER = "SensorBottomBorder";
+ field public static final String TAG_RW2_SENSOR_LEFT_BORDER = "SensorLeftBorder";
+ field public static final String TAG_RW2_SENSOR_RIGHT_BORDER = "SensorRightBorder";
+ field public static final String TAG_RW2_SENSOR_TOP_BORDER = "SensorTopBorder";
+ field public static final String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel";
+ field public static final String TAG_SATURATION = "Saturation";
+ field public static final String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType";
+ field public static final String TAG_SCENE_TYPE = "SceneType";
+ field public static final String TAG_SENSING_METHOD = "SensingMethod";
+ field public static final String TAG_SENSITIVITY_TYPE = "SensitivityType";
+ field public static final String TAG_SHARPNESS = "Sharpness";
+ field public static final String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue";
+ field public static final String TAG_SOFTWARE = "Software";
+ field public static final String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse";
+ field public static final String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity";
+ field public static final String TAG_STANDARD_OUTPUT_SENSITIVITY = "StandardOutputSensitivity";
+ field public static final String TAG_STRIP_BYTE_COUNTS = "StripByteCounts";
+ field public static final String TAG_STRIP_OFFSETS = "StripOffsets";
+ field public static final String TAG_SUBFILE_TYPE = "SubfileType";
+ field public static final String TAG_SUBJECT_AREA = "SubjectArea";
+ field public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance";
+ field public static final String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange";
+ field public static final String TAG_SUBJECT_LOCATION = "SubjectLocation";
+ field public static final String TAG_SUBSEC_TIME = "SubSecTime";
+ field public static final String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized";
+ field public static final String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
+ field public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
+ field public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+ field public static final String TAG_TRANSFER_FUNCTION = "TransferFunction";
+ field public static final String TAG_USER_COMMENT = "UserComment";
+ field public static final String TAG_WHITE_BALANCE = "WhiteBalance";
+ field public static final String TAG_WHITE_POINT = "WhitePoint";
+ field public static final String TAG_XMP = "Xmp";
+ field public static final String TAG_X_RESOLUTION = "XResolution";
+ field public static final String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
+ field public static final String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
+ field public static final String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling";
+ field public static final String TAG_Y_RESOLUTION = "YResolution";
+ field @Deprecated public static final int WHITEBALANCE_AUTO = 0; // 0x0
+ field @Deprecated public static final int WHITEBALANCE_MANUAL = 1; // 0x1
+ field public static final short WHITE_BALANCE_AUTO = 0; // 0x0
+ field public static final short WHITE_BALANCE_MANUAL = 1; // 0x1
+ field public static final short Y_CB_CR_POSITIONING_CENTERED = 1; // 0x1
+ field public static final short Y_CB_CR_POSITIONING_CO_SITED = 2; // 0x2
+ }
+
+}
+
diff --git a/exifinterface/api/res-1.2.0-beta01.txt b/exifinterface/api/res-1.2.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/exifinterface/api/res-1.2.0-beta01.txt
diff --git a/exifinterface/api/restricted_1.2.0-beta01.txt b/exifinterface/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..5aacfe0
--- /dev/null
+++ b/exifinterface/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1,349 @@
+// Signature format: 3.0
+package androidx.exifinterface.media {
+
+ public class ExifInterface {
+ ctor public ExifInterface(java.io.File) throws java.io.IOException;
+ ctor public ExifInterface(String) throws java.io.IOException;
+ ctor public ExifInterface(java.io.FileDescriptor) throws java.io.IOException;
+ ctor public ExifInterface(java.io.InputStream) throws java.io.IOException;
+ ctor public ExifInterface(java.io.InputStream, @androidx.exifinterface.media.ExifInterface.ExifStreamType int) throws java.io.IOException;
+ method public void flipHorizontally();
+ method public void flipVertically();
+ method public double getAltitude(double);
+ method public String? getAttribute(String);
+ method public byte[]? getAttributeBytes(String);
+ method public double getAttributeDouble(String, double);
+ method public int getAttributeInt(String, int);
+ method public long[]? getAttributeRange(String);
+ method @Deprecated public boolean getLatLong(float[]!);
+ method public double[]? getLatLong();
+ method public int getRotationDegrees();
+ method public byte[]? getThumbnail();
+ method public android.graphics.Bitmap? getThumbnailBitmap();
+ method public byte[]? getThumbnailBytes();
+ method public long[]? getThumbnailRange();
+ method public boolean hasAttribute(String);
+ method public boolean hasThumbnail();
+ method public boolean isFlipped();
+ method public static boolean isSupportedMimeType(String);
+ method public boolean isThumbnailCompressed();
+ method public void resetOrientation();
+ method public void rotate(int);
+ method public void saveAttributes() throws java.io.IOException;
+ method public void setAltitude(double);
+ method public void setAttribute(String, String?);
+ method public void setGpsInfo(android.location.Location!);
+ method public void setLatLong(double, double);
+ field public static final short ALTITUDE_ABOVE_SEA_LEVEL = 0; // 0x0
+ field public static final short ALTITUDE_BELOW_SEA_LEVEL = 1; // 0x1
+ field public static final int[]! BITS_PER_SAMPLE_GREYSCALE_1;
+ field public static final int[]! BITS_PER_SAMPLE_GREYSCALE_2;
+ field public static final int[]! BITS_PER_SAMPLE_RGB;
+ field public static final int COLOR_SPACE_S_RGB = 1; // 0x1
+ field public static final int COLOR_SPACE_UNCALIBRATED = 65535; // 0xffff
+ field public static final short CONTRAST_HARD = 2; // 0x2
+ field public static final short CONTRAST_NORMAL = 0; // 0x0
+ field public static final short CONTRAST_SOFT = 1; // 0x1
+ field public static final int DATA_DEFLATE_ZIP = 8; // 0x8
+ field public static final int DATA_HUFFMAN_COMPRESSED = 2; // 0x2
+ field public static final int DATA_JPEG = 6; // 0x6
+ field public static final int DATA_JPEG_COMPRESSED = 7; // 0x7
+ field public static final int DATA_LOSSY_JPEG = 34892; // 0x884c
+ field public static final int DATA_PACK_BITS_COMPRESSED = 32773; // 0x8005
+ field public static final int DATA_UNCOMPRESSED = 1; // 0x1
+ field public static final short EXPOSURE_MODE_AUTO = 0; // 0x0
+ field public static final short EXPOSURE_MODE_AUTO_BRACKET = 2; // 0x2
+ field public static final short EXPOSURE_MODE_MANUAL = 1; // 0x1
+ field public static final short EXPOSURE_PROGRAM_ACTION = 6; // 0x6
+ field public static final short EXPOSURE_PROGRAM_APERTURE_PRIORITY = 3; // 0x3
+ field public static final short EXPOSURE_PROGRAM_CREATIVE = 5; // 0x5
+ field public static final short EXPOSURE_PROGRAM_LANDSCAPE_MODE = 8; // 0x8
+ field public static final short EXPOSURE_PROGRAM_MANUAL = 1; // 0x1
+ field public static final short EXPOSURE_PROGRAM_NORMAL = 2; // 0x2
+ field public static final short EXPOSURE_PROGRAM_NOT_DEFINED = 0; // 0x0
+ field public static final short EXPOSURE_PROGRAM_PORTRAIT_MODE = 7; // 0x7
+ field public static final short EXPOSURE_PROGRAM_SHUTTER_PRIORITY = 4; // 0x4
+ field public static final short FILE_SOURCE_DSC = 3; // 0x3
+ field public static final short FILE_SOURCE_OTHER = 0; // 0x0
+ field public static final short FILE_SOURCE_REFLEX_SCANNER = 2; // 0x2
+ field public static final short FILE_SOURCE_TRANSPARENT_SCANNER = 1; // 0x1
+ field public static final short FLAG_FLASH_FIRED = 1; // 0x1
+ field public static final short FLAG_FLASH_MODE_AUTO = 24; // 0x18
+ field public static final short FLAG_FLASH_MODE_COMPULSORY_FIRING = 8; // 0x8
+ field public static final short FLAG_FLASH_MODE_COMPULSORY_SUPPRESSION = 16; // 0x10
+ field public static final short FLAG_FLASH_NO_FLASH_FUNCTION = 32; // 0x20
+ field public static final short FLAG_FLASH_RED_EYE_SUPPORTED = 64; // 0x40
+ field public static final short FLAG_FLASH_RETURN_LIGHT_DETECTED = 6; // 0x6
+ field public static final short FLAG_FLASH_RETURN_LIGHT_NOT_DETECTED = 4; // 0x4
+ field public static final short FORMAT_CHUNKY = 1; // 0x1
+ field public static final short FORMAT_PLANAR = 2; // 0x2
+ field public static final short GAIN_CONTROL_HIGH_GAIN_DOWN = 4; // 0x4
+ field public static final short GAIN_CONTROL_HIGH_GAIN_UP = 2; // 0x2
+ field public static final short GAIN_CONTROL_LOW_GAIN_DOWN = 3; // 0x3
+ field public static final short GAIN_CONTROL_LOW_GAIN_UP = 1; // 0x1
+ field public static final short GAIN_CONTROL_NONE = 0; // 0x0
+ field public static final String GPS_DIRECTION_MAGNETIC = "M";
+ field public static final String GPS_DIRECTION_TRUE = "T";
+ field public static final String GPS_DISTANCE_KILOMETERS = "K";
+ field public static final String GPS_DISTANCE_MILES = "M";
+ field public static final String GPS_DISTANCE_NAUTICAL_MILES = "N";
+ field public static final String GPS_MEASUREMENT_2D = "2";
+ field public static final String GPS_MEASUREMENT_3D = "3";
+ field public static final short GPS_MEASUREMENT_DIFFERENTIAL_CORRECTED = 1; // 0x1
+ field public static final String GPS_MEASUREMENT_INTERRUPTED = "V";
+ field public static final String GPS_MEASUREMENT_IN_PROGRESS = "A";
+ field public static final short GPS_MEASUREMENT_NO_DIFFERENTIAL = 0; // 0x0
+ field public static final String GPS_SPEED_KILOMETERS_PER_HOUR = "K";
+ field public static final String GPS_SPEED_KNOTS = "N";
+ field public static final String GPS_SPEED_MILES_PER_HOUR = "M";
+ field public static final String LATITUDE_NORTH = "N";
+ field public static final String LATITUDE_SOUTH = "S";
+ field public static final short LIGHT_SOURCE_CLOUDY_WEATHER = 10; // 0xa
+ field public static final short LIGHT_SOURCE_COOL_WHITE_FLUORESCENT = 14; // 0xe
+ field public static final short LIGHT_SOURCE_D50 = 23; // 0x17
+ field public static final short LIGHT_SOURCE_D55 = 20; // 0x14
+ field public static final short LIGHT_SOURCE_D65 = 21; // 0x15
+ field public static final short LIGHT_SOURCE_D75 = 22; // 0x16
+ field public static final short LIGHT_SOURCE_DAYLIGHT = 1; // 0x1
+ field public static final short LIGHT_SOURCE_DAYLIGHT_FLUORESCENT = 12; // 0xc
+ field public static final short LIGHT_SOURCE_DAY_WHITE_FLUORESCENT = 13; // 0xd
+ field public static final short LIGHT_SOURCE_FINE_WEATHER = 9; // 0x9
+ field public static final short LIGHT_SOURCE_FLASH = 4; // 0x4
+ field public static final short LIGHT_SOURCE_FLUORESCENT = 2; // 0x2
+ field public static final short LIGHT_SOURCE_ISO_STUDIO_TUNGSTEN = 24; // 0x18
+ field public static final short LIGHT_SOURCE_OTHER = 255; // 0xff
+ field public static final short LIGHT_SOURCE_SHADE = 11; // 0xb
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_A = 17; // 0x11
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_B = 18; // 0x12
+ field public static final short LIGHT_SOURCE_STANDARD_LIGHT_C = 19; // 0x13
+ field public static final short LIGHT_SOURCE_TUNGSTEN = 3; // 0x3
+ field public static final short LIGHT_SOURCE_UNKNOWN = 0; // 0x0
+ field public static final short LIGHT_SOURCE_WARM_WHITE_FLUORESCENT = 16; // 0x10
+ field public static final short LIGHT_SOURCE_WHITE_FLUORESCENT = 15; // 0xf
+ field public static final String LONGITUDE_EAST = "E";
+ field public static final String LONGITUDE_WEST = "W";
+ field public static final short METERING_MODE_AVERAGE = 1; // 0x1
+ field public static final short METERING_MODE_CENTER_WEIGHT_AVERAGE = 2; // 0x2
+ field public static final short METERING_MODE_MULTI_SPOT = 4; // 0x4
+ field public static final short METERING_MODE_OTHER = 255; // 0xff
+ field public static final short METERING_MODE_PARTIAL = 6; // 0x6
+ field public static final short METERING_MODE_PATTERN = 5; // 0x5
+ field public static final short METERING_MODE_SPOT = 3; // 0x3
+ field public static final short METERING_MODE_UNKNOWN = 0; // 0x0
+ field public static final int ORIENTATION_FLIP_HORIZONTAL = 2; // 0x2
+ field public static final int ORIENTATION_FLIP_VERTICAL = 4; // 0x4
+ field public static final int ORIENTATION_NORMAL = 1; // 0x1
+ field public static final int ORIENTATION_ROTATE_180 = 3; // 0x3
+ field public static final int ORIENTATION_ROTATE_270 = 8; // 0x8
+ field public static final int ORIENTATION_ROTATE_90 = 6; // 0x6
+ field public static final int ORIENTATION_TRANSPOSE = 5; // 0x5
+ field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7
+ field public static final int ORIENTATION_UNDEFINED = 0; // 0x0
+ field public static final int ORIGINAL_RESOLUTION_IMAGE = 0; // 0x0
+ field public static final int PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO = 1; // 0x1
+ field public static final int PHOTOMETRIC_INTERPRETATION_RGB = 2; // 0x2
+ field public static final int PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO = 0; // 0x0
+ field public static final int PHOTOMETRIC_INTERPRETATION_YCBCR = 6; // 0x6
+ field public static final int REDUCED_RESOLUTION_IMAGE = 1; // 0x1
+ field public static final short RENDERED_PROCESS_CUSTOM = 1; // 0x1
+ field public static final short RENDERED_PROCESS_NORMAL = 0; // 0x0
+ field public static final short RESOLUTION_UNIT_CENTIMETERS = 3; // 0x3
+ field public static final short RESOLUTION_UNIT_INCHES = 2; // 0x2
+ field public static final short SATURATION_HIGH = 0; // 0x0
+ field public static final short SATURATION_LOW = 0; // 0x0
+ field public static final short SATURATION_NORMAL = 0; // 0x0
+ field public static final short SCENE_CAPTURE_TYPE_LANDSCAPE = 1; // 0x1
+ field public static final short SCENE_CAPTURE_TYPE_NIGHT = 3; // 0x3
+ field public static final short SCENE_CAPTURE_TYPE_PORTRAIT = 2; // 0x2
+ field public static final short SCENE_CAPTURE_TYPE_STANDARD = 0; // 0x0
+ field public static final short SCENE_TYPE_DIRECTLY_PHOTOGRAPHED = 1; // 0x1
+ field public static final short SENSITIVITY_TYPE_ISO_SPEED = 3; // 0x3
+ field public static final short SENSITIVITY_TYPE_REI = 2; // 0x2
+ field public static final short SENSITIVITY_TYPE_REI_AND_ISO = 6; // 0x6
+ field public static final short SENSITIVITY_TYPE_SOS = 1; // 0x1
+ field public static final short SENSITIVITY_TYPE_SOS_AND_ISO = 5; // 0x5
+ field public static final short SENSITIVITY_TYPE_SOS_AND_REI = 4; // 0x4
+ field public static final short SENSITIVITY_TYPE_SOS_AND_REI_AND_ISO = 7; // 0x7
+ field public static final short SENSITIVITY_TYPE_UNKNOWN = 0; // 0x0
+ field public static final short SENSOR_TYPE_COLOR_SEQUENTIAL = 5; // 0x5
+ field public static final short SENSOR_TYPE_COLOR_SEQUENTIAL_LINEAR = 8; // 0x8
+ field public static final short SENSOR_TYPE_NOT_DEFINED = 1; // 0x1
+ field public static final short SENSOR_TYPE_ONE_CHIP = 2; // 0x2
+ field public static final short SENSOR_TYPE_THREE_CHIP = 4; // 0x4
+ field public static final short SENSOR_TYPE_TRILINEAR = 7; // 0x7
+ field public static final short SENSOR_TYPE_TWO_CHIP = 3; // 0x3
+ field public static final short SHARPNESS_HARD = 2; // 0x2
+ field public static final short SHARPNESS_NORMAL = 0; // 0x0
+ field public static final short SHARPNESS_SOFT = 1; // 0x1
+ field public static final int STREAM_TYPE_EXIF_DATA_ONLY = 1; // 0x1
+ field public static final int STREAM_TYPE_FULL_IMAGE_DATA = 0; // 0x0
+ field public static final short SUBJECT_DISTANCE_RANGE_CLOSE_VIEW = 2; // 0x2
+ field public static final short SUBJECT_DISTANCE_RANGE_DISTANT_VIEW = 3; // 0x3
+ field public static final short SUBJECT_DISTANCE_RANGE_MACRO = 1; // 0x1
+ field public static final short SUBJECT_DISTANCE_RANGE_UNKNOWN = 0; // 0x0
+ field public static final String TAG_APERTURE_VALUE = "ApertureValue";
+ field public static final String TAG_ARTIST = "Artist";
+ field public static final String TAG_BITS_PER_SAMPLE = "BitsPerSample";
+ field public static final String TAG_BODY_SERIAL_NUMBER = "BodySerialNumber";
+ field public static final String TAG_BRIGHTNESS_VALUE = "BrightnessValue";
+ field @Deprecated public static final String TAG_CAMARA_OWNER_NAME = "CameraOwnerName";
+ field public static final String TAG_CAMERA_OWNER_NAME = "CameraOwnerName";
+ field public static final String TAG_CFA_PATTERN = "CFAPattern";
+ field public static final String TAG_COLOR_SPACE = "ColorSpace";
+ field public static final String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration";
+ field public static final String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel";
+ field public static final String TAG_COMPRESSION = "Compression";
+ field public static final String TAG_CONTRAST = "Contrast";
+ field public static final String TAG_COPYRIGHT = "Copyright";
+ field public static final String TAG_CUSTOM_RENDERED = "CustomRendered";
+ field public static final String TAG_DATETIME = "DateTime";
+ field public static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
+ field public static final String TAG_DATETIME_ORIGINAL = "DateTimeOriginal";
+ field public static final String TAG_DEFAULT_CROP_SIZE = "DefaultCropSize";
+ field public static final String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription";
+ field public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio";
+ field public static final String TAG_DNG_VERSION = "DNGVersion";
+ field public static final String TAG_EXIF_VERSION = "ExifVersion";
+ field public static final String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue";
+ field public static final String TAG_EXPOSURE_INDEX = "ExposureIndex";
+ field public static final String TAG_EXPOSURE_MODE = "ExposureMode";
+ field public static final String TAG_EXPOSURE_PROGRAM = "ExposureProgram";
+ field public static final String TAG_EXPOSURE_TIME = "ExposureTime";
+ field public static final String TAG_FILE_SOURCE = "FileSource";
+ field public static final String TAG_FLASH = "Flash";
+ field public static final String TAG_FLASHPIX_VERSION = "FlashpixVersion";
+ field public static final String TAG_FLASH_ENERGY = "FlashEnergy";
+ field public static final String TAG_FOCAL_LENGTH = "FocalLength";
+ field public static final String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm";
+ field public static final String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit";
+ field public static final String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution";
+ field public static final String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution";
+ field public static final String TAG_F_NUMBER = "FNumber";
+ field public static final String TAG_GAIN_CONTROL = "GainControl";
+ field public static final String TAG_GAMMA = "Gamma";
+ field public static final String TAG_GPS_ALTITUDE = "GPSAltitude";
+ field public static final String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef";
+ field public static final String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation";
+ field public static final String TAG_GPS_DATESTAMP = "GPSDateStamp";
+ field public static final String TAG_GPS_DEST_BEARING = "GPSDestBearing";
+ field public static final String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef";
+ field public static final String TAG_GPS_DEST_DISTANCE = "GPSDestDistance";
+ field public static final String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef";
+ field public static final String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude";
+ field public static final String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef";
+ field public static final String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude";
+ field public static final String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef";
+ field public static final String TAG_GPS_DIFFERENTIAL = "GPSDifferential";
+ field public static final String TAG_GPS_DOP = "GPSDOP";
+ field public static final String TAG_GPS_H_POSITIONING_ERROR = "GPSHPositioningError";
+ field public static final String TAG_GPS_IMG_DIRECTION = "GPSImgDirection";
+ field public static final String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef";
+ field public static final String TAG_GPS_LATITUDE = "GPSLatitude";
+ field public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
+ field public static final String TAG_GPS_LONGITUDE = "GPSLongitude";
+ field public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
+ field public static final String TAG_GPS_MAP_DATUM = "GPSMapDatum";
+ field public static final String TAG_GPS_MEASURE_MODE = "GPSMeasureMode";
+ field public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
+ field public static final String TAG_GPS_SATELLITES = "GPSSatellites";
+ field public static final String TAG_GPS_SPEED = "GPSSpeed";
+ field public static final String TAG_GPS_SPEED_REF = "GPSSpeedRef";
+ field public static final String TAG_GPS_STATUS = "GPSStatus";
+ field public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
+ field public static final String TAG_GPS_TRACK = "GPSTrack";
+ field public static final String TAG_GPS_TRACK_REF = "GPSTrackRef";
+ field public static final String TAG_GPS_VERSION_ID = "GPSVersionID";
+ field public static final String TAG_IMAGE_DESCRIPTION = "ImageDescription";
+ field public static final String TAG_IMAGE_LENGTH = "ImageLength";
+ field public static final String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID";
+ field public static final String TAG_IMAGE_WIDTH = "ImageWidth";
+ field public static final String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex";
+ field public static final String TAG_ISO_SPEED = "ISOSpeed";
+ field public static final String TAG_ISO_SPEED_LATITUDE_YYY = "ISOSpeedLatitudeyyy";
+ field public static final String TAG_ISO_SPEED_LATITUDE_ZZZ = "ISOSpeedLatitudezzz";
+ field @Deprecated public static final String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings";
+ field public static final String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat";
+ field public static final String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength";
+ field public static final String TAG_LENS_MAKE = "LensMake";
+ field public static final String TAG_LENS_MODEL = "LensModel";
+ field public static final String TAG_LENS_SERIAL_NUMBER = "LensSerialNumber";
+ field public static final String TAG_LENS_SPECIFICATION = "LensSpecification";
+ field public static final String TAG_LIGHT_SOURCE = "LightSource";
+ field public static final String TAG_MAKE = "Make";
+ field public static final String TAG_MAKER_NOTE = "MakerNote";
+ field public static final String TAG_MAX_APERTURE_VALUE = "MaxApertureValue";
+ field public static final String TAG_METERING_MODE = "MeteringMode";
+ field public static final String TAG_MODEL = "Model";
+ field public static final String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
+ field public static final String TAG_OECF = "OECF";
+ field public static final String TAG_OFFSET_TIME = "OffsetTime";
+ field public static final String TAG_OFFSET_TIME_DIGITIZED = "OffsetTimeDigitized";
+ field public static final String TAG_OFFSET_TIME_ORIGINAL = "OffsetTimeOriginal";
+ field public static final String TAG_ORF_ASPECT_FRAME = "AspectFrame";
+ field public static final String TAG_ORF_PREVIEW_IMAGE_LENGTH = "PreviewImageLength";
+ field public static final String TAG_ORF_PREVIEW_IMAGE_START = "PreviewImageStart";
+ field public static final String TAG_ORF_THUMBNAIL_IMAGE = "ThumbnailImage";
+ field public static final String TAG_ORIENTATION = "Orientation";
+ field public static final String TAG_PHOTOGRAPHIC_SENSITIVITY = "PhotographicSensitivity";
+ field public static final String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation";
+ field public static final String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
+ field public static final String TAG_PIXEL_Y_DIMENSION = "PixelYDimension";
+ field public static final String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration";
+ field public static final String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities";
+ field public static final String TAG_RECOMMENDED_EXPOSURE_INDEX = "RecommendedExposureIndex";
+ field public static final String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite";
+ field public static final String TAG_RELATED_SOUND_FILE = "RelatedSoundFile";
+ field public static final String TAG_RESOLUTION_UNIT = "ResolutionUnit";
+ field public static final String TAG_ROWS_PER_STRIP = "RowsPerStrip";
+ field public static final String TAG_RW2_ISO = "ISO";
+ field public static final String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
+ field public static final String TAG_RW2_SENSOR_BOTTOM_BORDER = "SensorBottomBorder";
+ field public static final String TAG_RW2_SENSOR_LEFT_BORDER = "SensorLeftBorder";
+ field public static final String TAG_RW2_SENSOR_RIGHT_BORDER = "SensorRightBorder";
+ field public static final String TAG_RW2_SENSOR_TOP_BORDER = "SensorTopBorder";
+ field public static final String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel";
+ field public static final String TAG_SATURATION = "Saturation";
+ field public static final String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType";
+ field public static final String TAG_SCENE_TYPE = "SceneType";
+ field public static final String TAG_SENSING_METHOD = "SensingMethod";
+ field public static final String TAG_SENSITIVITY_TYPE = "SensitivityType";
+ field public static final String TAG_SHARPNESS = "Sharpness";
+ field public static final String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue";
+ field public static final String TAG_SOFTWARE = "Software";
+ field public static final String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse";
+ field public static final String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity";
+ field public static final String TAG_STANDARD_OUTPUT_SENSITIVITY = "StandardOutputSensitivity";
+ field public static final String TAG_STRIP_BYTE_COUNTS = "StripByteCounts";
+ field public static final String TAG_STRIP_OFFSETS = "StripOffsets";
+ field public static final String TAG_SUBFILE_TYPE = "SubfileType";
+ field public static final String TAG_SUBJECT_AREA = "SubjectArea";
+ field public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance";
+ field public static final String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange";
+ field public static final String TAG_SUBJECT_LOCATION = "SubjectLocation";
+ field public static final String TAG_SUBSEC_TIME = "SubSecTime";
+ field public static final String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized";
+ field public static final String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
+ field public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
+ field public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+ field public static final String TAG_TRANSFER_FUNCTION = "TransferFunction";
+ field public static final String TAG_USER_COMMENT = "UserComment";
+ field public static final String TAG_WHITE_BALANCE = "WhiteBalance";
+ field public static final String TAG_WHITE_POINT = "WhitePoint";
+ field public static final String TAG_XMP = "Xmp";
+ field public static final String TAG_X_RESOLUTION = "XResolution";
+ field public static final String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
+ field public static final String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
+ field public static final String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling";
+ field public static final String TAG_Y_RESOLUTION = "YResolution";
+ field @Deprecated public static final int WHITEBALANCE_AUTO = 0; // 0x0
+ field @Deprecated public static final int WHITEBALANCE_MANUAL = 1; // 0x1
+ field public static final short WHITE_BALANCE_AUTO = 0; // 0x0
+ field public static final short WHITE_BALANCE_MANUAL = 1; // 0x1
+ field public static final short Y_CB_CR_POSITIONING_CENTERED = 1; // 0x1
+ field public static final short Y_CB_CR_POSITIONING_CO_SITED = 2; // 0x2
+ }
+
+
+
+}
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index cf3bb85..9817e9f 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -5,4 +5,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=../../../../tools/external/gradle/gradle-5.6.2-bin.zip
+distributionUrl=../../../../tools/external/gradle/gradle-6.0-bin.zip
diff --git a/jetifier/jetifier/core/build.gradle b/jetifier/jetifier/core/build.gradle
index 0662cc0..9d8e1ef 100644
--- a/jetifier/jetifier/core/build.gradle
+++ b/jetifier/jetifier/core/build.gradle
@@ -29,10 +29,10 @@
targetCompatibility = JavaVersion.VERSION_1_7
dependencies {
- compile("com.google.code.gson:gson:2.8.0")
- compile(KOTLIN_STDLIB)
- testCompile("junit:junit:4.12")
- testCompile(TRUTH)
+ api("com.google.code.gson:gson:2.8.0")
+ api(KOTLIN_STDLIB)
+ testImplementation("junit:junit:4.12")
+ testImplementation(TRUTH)
}
androidx {
diff --git a/jetifier/jetifier/migration.config b/jetifier/jetifier/migration.config
index dae320b..5a242c3 100644
--- a/jetifier/jetifier/migration.config
+++ b/jetifier/jetifier/migration.config
@@ -31,10 +31,6 @@
"to": "ignoreInPreprocessorOnly"
},
{
- "from": "android/support/test/((.*)/)?internal/(.*)",
- "to": "ignore"
- },
- {
"from": "(.*)Parcelizer",
"to": "{0}Parcelizer"
},
@@ -409,10 +405,6 @@
{
"from": "androidx/activity/(.*)",
"to": "androidx/activity/{0}"
- },
- {
- "from": "android/support/test/(.*)",
- "to": "androidx/test/{0}"
}
],
"slRules": [
@@ -441,6 +433,10 @@
"to": "ignore"
},
{
+ "from": "androidx/test(.*)",
+ "to": "ignore"
+ },
+ {
"from": "androidx/gridlayout/widget/GridLayout(.*)",
"to": "ignore"
},
@@ -3675,107 +3671,6 @@
"android/support/multidex/MultiDexApplication": "androidx/multidex/MultiDexApplication",
"android/support/multidex/MultiDexExtractor": "androidx/multidex/MultiDexExtractor",
"android/support/multidex/ZipUtil": "androidx/multidex/ZipUtil",
- "android/support/test/InstrumentationRegistry": "androidx/test/InstrumentationRegistry",
- "android/support/test/annotation/Beta": "androidx/test/annotation/Beta",
- "android/support/test/annotation/UiThreadTest": "androidx/test/annotation/UiThreadTest",
- "android/support/test/filters/FlakyTest": "androidx/test/filters/FlakyTest",
- "android/support/test/filters/LargeTest": "androidx/test/filters/LargeTest",
- "android/support/test/filters/MediumTest": "androidx/test/filters/MediumTest",
- "android/support/test/filters/RequiresDevice": "androidx/test/filters/RequiresDevice",
- "android/support/test/filters/SdkSuppress": "androidx/test/filters/SdkSuppress",
- "android/support/test/filters/SmallTest": "androidx/test/filters/SmallTest",
- "android/support/test/filters/Suppress": "androidx/test/filters/Suppress",
- "android/support/test/jank/GfxMonitor": "androidx/test/jank/GfxMonitor",
- "android/support/test/jank/JankTest": "androidx/test/jank/JankTest",
- "android/support/test/jank/JankTestBase": "androidx/test/jank/JankTestBase",
- "android/support/test/jank/WindowAnimationFrameStatsMonitor": "androidx/test/jank/WindowAnimationFrameStatsMonitor",
- "android/support/test/jank/WindowContentFrameStatsMonitor": "androidx/test/jank/WindowContentFrameStatsMonitor",
- "android/support/test/orchestrator/callback/OrchestratorCallback": "androidx/test/orchestrator/callback/OrchestratorCallback",
- "android/support/test/orchestrator/instrumentationlistener/OrchestratedInstrumentationListener": "androidx/test/orchestrator/instrumentationlistener/OrchestratedInstrumentationListener",
- "android/support/test/orchestrator/junit/BundleJUnitUtils": "androidx/test/orchestrator/junit/BundleJUnitUtils",
- "android/support/test/orchestrator/junit/ParcelableDescription": "androidx/test/orchestrator/junit/ParcelableDescription",
- "android/support/test/orchestrator/junit/ParcelableFailure": "androidx/test/orchestrator/junit/ParcelableFailure",
- "android/support/test/orchestrator/junit/ParcelableResult": "androidx/test/orchestrator/junit/ParcelableResult",
- "android/support/test/orchestrator/listeners/OrchestrationListenerManager": "androidx/test/orchestrator/listeners/OrchestrationListenerManager",
- "android/support/test/orchestrator/listeners/OrchestrationRunListener": "androidx/test/orchestrator/listeners/OrchestrationRunListener",
- "android/support/test/orchestrator/listeners/result/ITestRunListener": "androidx/test/orchestrator/listeners/result/ITestRunListener",
- "android/support/test/orchestrator/listeners/result/TestIdentifier": "androidx/test/orchestrator/listeners/result/TestIdentifier",
- "android/support/test/orchestrator/listeners/result/TestResult": "androidx/test/orchestrator/listeners/result/TestResult",
- "android/support/test/orchestrator/listeners/result/TestRunResult": "androidx/test/orchestrator/listeners/result/TestRunResult",
- "android/support/test/rule/ActivityTestRule": "androidx/test/rule/ActivityTestRule",
- "android/support/test/rule/DisableOnAndroidDebug": "androidx/test/rule/DisableOnAndroidDebug",
- "android/support/test/rule/GrantPermissionRule": "androidx/test/rule/GrantPermissionRule",
- "android/support/test/rule/PortForwardingRule": "androidx/test/rule/PortForwardingRule",
- "android/support/test/rule/ServiceTestRule": "androidx/test/rule/ServiceTestRule",
- "android/support/test/rule/UiThreadTestRule": "androidx/test/rule/UiThreadTestRule",
- "android/support/test/rule/logging/AtraceLogger": "androidx/test/rule/logging/AtraceLogger",
- "android/support/test/rule/provider/DatabaseArgs": "androidx/test/rule/provider/DatabaseArgs",
- "android/support/test/rule/provider/DelegatingContext": "androidx/test/rule/provider/DelegatingContext",
- "android/support/test/rule/provider/ProviderArgs": "androidx/test/rule/provider/ProviderArgs",
- "android/support/test/rule/provider/ProviderTestRule": "androidx/test/rule/provider/ProviderTestRule",
- "android/support/test/runner/AndroidJUnit4": "androidx/test/runner/AndroidJUnit4",
- "android/support/test/runner/AndroidJUnitRunner": "androidx/test/runner/AndroidJUnitRunner",
- "android/support/test/runner/MonitoringInstrumentation": "androidx/test/runner/MonitoringInstrumentation",
- "android/support/test/runner/UsageTrackerFacilitator": "androidx/test/runner/UsageTrackerFacilitator",
- "android/support/test/runner/intent/IntentCallback": "androidx/test/runner/intent/IntentCallback",
- "android/support/test/runner/intent/IntentMonitor": "androidx/test/runner/intent/IntentMonitor",
- "android/support/test/runner/intent/IntentMonitorRegistry": "androidx/test/runner/intent/IntentMonitorRegistry",
- "android/support/test/runner/intent/IntentStubber": "androidx/test/runner/intent/IntentStubber",
- "android/support/test/runner/intent/IntentStubberRegistry": "androidx/test/runner/intent/IntentStubberRegistry",
- "android/support/test/runner/intercepting/InterceptingActivityFactory": "androidx/test/runner/intercepting/InterceptingActivityFactory",
- "android/support/test/runner/intercepting/SingleActivityFactory": "androidx/test/runner/intercepting/SingleActivityFactory",
- "android/support/test/runner/lifecycle/ActivityLifecycleCallback": "androidx/test/runner/lifecycle/ActivityLifecycleCallback",
- "android/support/test/runner/lifecycle/ActivityLifecycleMonitor": "androidx/test/runner/lifecycle/ActivityLifecycleMonitor",
- "android/support/test/runner/lifecycle/ActivityLifecycleMonitorRegistry": "androidx/test/runner/lifecycle/ActivityLifecycleMonitorRegistry",
- "android/support/test/runner/lifecycle/ApplicationLifecycleCallback": "androidx/test/runner/lifecycle/ApplicationLifecycleCallback",
- "android/support/test/runner/lifecycle/ApplicationLifecycleMonitor": "androidx/test/runner/lifecycle/ApplicationLifecycleMonitor",
- "android/support/test/runner/lifecycle/ApplicationLifecycleMonitorRegistry": "androidx/test/runner/lifecycle/ApplicationLifecycleMonitorRegistry",
- "android/support/test/runner/lifecycle/ApplicationStage": "androidx/test/runner/lifecycle/ApplicationStage",
- "android/support/test/runner/lifecycle/Stage": "androidx/test/runner/lifecycle/Stage",
- "android/support/test/runner/permission/GrantPermissionCallable": "androidx/test/runner/permission/GrantPermissionCallable",
- "android/support/test/runner/permission/PermissionRequester": "androidx/test/runner/permission/PermissionRequester",
- "android/support/test/runner/permission/RequestPermissionCallable": "androidx/test/runner/permission/RequestPermissionCallable",
- "android/support/test/runner/permission/ShellCommand": "androidx/test/runner/permission/ShellCommand",
- "android/support/test/runner/permission/UiAutomationShellCommand": "androidx/test/runner/permission/UiAutomationShellCommand",
- "android/support/test/runner/screenshot/BasicScreenCaptureProcessor": "androidx/test/runner/screenshot/BasicScreenCaptureProcessor",
- "android/support/test/runner/screenshot/ScreenCapture": "androidx/test/runner/screenshot/ScreenCapture",
- "android/support/test/runner/screenshot/ScreenCaptureProcessor": "androidx/test/runner/screenshot/ScreenCaptureProcessor",
- "android/support/test/runner/screenshot/Screenshot": "androidx/test/runner/screenshot/Screenshot",
- "android/support/test/runner/screenshot/TakeScreenshotCallable": "androidx/test/runner/screenshot/TakeScreenshotCallable",
- "android/support/test/runner/screenshot/UiAutomationWrapper": "androidx/test/runner/screenshot/UiAutomationWrapper",
- "android/support/test/uiautomator/AccessibilityNodeInfoDumper": "androidx/test/uiautomator/AccessibilityNodeInfoDumper",
- "android/support/test/uiautomator/AccessibilityNodeInfoHelper": "androidx/test/uiautomator/AccessibilityNodeInfoHelper",
- "android/support/test/uiautomator/By": "androidx/test/uiautomator/By",
- "android/support/test/uiautomator/ByMatcher": "androidx/test/uiautomator/ByMatcher",
- "android/support/test/uiautomator/BySelector": "androidx/test/uiautomator/BySelector",
- "android/support/test/uiautomator/Condition": "androidx/test/uiautomator/Condition",
- "android/support/test/uiautomator/Configurator": "androidx/test/uiautomator/Configurator",
- "android/support/test/uiautomator/Direction": "androidx/test/uiautomator/Direction",
- "android/support/test/uiautomator/EventCondition": "androidx/test/uiautomator/EventCondition",
- "android/support/test/uiautomator/GestureController": "androidx/test/uiautomator/GestureController",
- "android/support/test/uiautomator/Gestures": "androidx/test/uiautomator/Gestures",
- "android/support/test/uiautomator/IAutomationSupport": "androidx/test/uiautomator/IAutomationSupport",
- "android/support/test/uiautomator/InstrumentationAutomationSupport": "androidx/test/uiautomator/InstrumentationAutomationSupport",
- "android/support/test/uiautomator/InteractionController": "androidx/test/uiautomator/InteractionController",
- "android/support/test/uiautomator/PointerGesture": "androidx/test/uiautomator/PointerGesture",
- "android/support/test/uiautomator/QueryController": "androidx/test/uiautomator/QueryController",
- "android/support/test/uiautomator/SearchCondition": "androidx/test/uiautomator/SearchCondition",
- "android/support/test/uiautomator/Searchable": "androidx/test/uiautomator/Searchable",
- "android/support/test/uiautomator/StaleObjectException": "androidx/test/uiautomator/StaleObjectException",
- "android/support/test/uiautomator/Tracer": "androidx/test/uiautomator/Tracer",
- "android/support/test/uiautomator/UiAutomatorInstrumentationTestRunner": "androidx/test/uiautomator/UiAutomatorInstrumentationTestRunner",
- "android/support/test/uiautomator/UiAutomatorTestCase": "androidx/test/uiautomator/UiAutomatorTestCase",
- "android/support/test/uiautomator/UiCollection": "androidx/test/uiautomator/UiCollection",
- "android/support/test/uiautomator/UiDevice": "androidx/test/uiautomator/UiDevice",
- "android/support/test/uiautomator/UiObject": "androidx/test/uiautomator/UiObject",
- "android/support/test/uiautomator/UiObject2": "androidx/test/uiautomator/UiObject2",
- "android/support/test/uiautomator/UiObject2Condition": "androidx/test/uiautomator/UiObject2Condition",
- "android/support/test/uiautomator/UiObjectNotFoundException": "androidx/test/uiautomator/UiObjectNotFoundException",
- "android/support/test/uiautomator/UiScrollable": "androidx/test/uiautomator/UiScrollable",
- "android/support/test/uiautomator/UiSelector": "androidx/test/uiautomator/UiSelector",
- "android/support/test/uiautomator/UiWatcher": "androidx/test/uiautomator/UiWatcher",
- "android/support/test/uiautomator/Until": "androidx/test/uiautomator/Until",
- "android/support/test/uiautomator/WaitMixin": "androidx/test/uiautomator/WaitMixin",
"android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat": "androidx/core/accessibilityservice/AccessibilityServiceInfoCompat",
"android/support/v4/app/ActivityCompat": "androidx/core/app/ActivityCompat",
"android/support/v4/app/ActivityManagerCompat": "androidx/core/app/ActivityManagerCompat",
diff --git a/jetifier/jetifier/preprocessor/build.gradle b/jetifier/jetifier/preprocessor/build.gradle
index c38d52f..f478c95 100644
--- a/jetifier/jetifier/preprocessor/build.gradle
+++ b/jetifier/jetifier/preprocessor/build.gradle
@@ -26,6 +26,6 @@
mainClassName = "com.android.tools.build.jetifier.preprocessor.MainKt"
dependencies {
- compile project(':jetifier-processor')
- compile group: 'commons-cli', name: 'commons-cli', version: '1.3.1'
+ api(project(":jetifier-processor"))
+ api("commons-cli:commons-cli:1.3.1")
}
diff --git a/jetifier/jetifier/processor/build.gradle b/jetifier/jetifier/processor/build.gradle
index fd7d9c6..0fe2cfd 100644
--- a/jetifier/jetifier/processor/build.gradle
+++ b/jetifier/jetifier/processor/build.gradle
@@ -28,14 +28,14 @@
targetCompatibility = JavaVersion.VERSION_1_7
dependencies {
- compile project(':jetifier-core')
- compile("org.ow2.asm:asm:6.0")
- compile("org.ow2.asm:asm-util:6.0")
- compile("org.ow2.asm:asm-commons:6.0")
- compile("org.jdom:jdom2:2.0.6")
- compile(KOTLIN_STDLIB)
- testCompile("junit:junit:4.12")
- testCompile(TRUTH)
+ api(project(":jetifier-core"))
+ api("org.ow2.asm:asm:6.0")
+ api("org.ow2.asm:asm-util:6.0")
+ api("org.ow2.asm:asm-commons:6.0")
+ api("org.jdom:jdom2:2.0.6")
+ api(KOTLIN_STDLIB)
+ testImplementation("junit:junit:4.12")
+ testImplementation(TRUTH)
}
androidx {
diff --git a/jetifier/jetifier/standalone/build.gradle b/jetifier/jetifier/standalone/build.gradle
index 126f449..73617fc 100644
--- a/jetifier/jetifier/standalone/build.gradle
+++ b/jetifier/jetifier/standalone/build.gradle
@@ -25,8 +25,8 @@
mainClassName = "com.android.tools.build.jetifier.standalone.Main"
dependencies {
- compile project(':jetifier-processor')
- compile group: 'commons-cli', name: 'commons-cli', version: '1.3.1'
+ api(project(":jetifier-processor"))
+ api("commons-cli:commons-cli:1.3.1")
}
task dist(type: Copy) {
diff --git a/lifecycle/integration-tests/incrementality/build.gradle b/lifecycle/integration-tests/incrementality/build.gradle
index 8207fb4..f036777 100644
--- a/lifecycle/integration-tests/incrementality/build.gradle
+++ b/lifecycle/integration-tests/incrementality/build.gradle
@@ -66,4 +66,5 @@
// lifecycle-common and annotation are the dependencies of lifecycle-compiler
tasks.findByPath("test").dependsOn(tasks.findByPath(":lifecycle:lifecycle-compiler:publish"),
tasks.findByPath(":lifecycle:lifecycle-common:publish"),
+ tasks.findByPath(":lifecycle:lifecycle-runtime:publish"),
tasks.findByPath(":annotation:annotation:publish"))
diff --git a/lifecycle/lifecycle-common-java8/build.gradle b/lifecycle/lifecycle-common-java8/build.gradle
index 6c0e6e6..d0315593 100644
--- a/lifecycle/lifecycle-common-java8/build.gradle
+++ b/lifecycle/lifecycle-common-java8/build.gradle
@@ -26,11 +26,11 @@
}
dependencies {
- compile(project(":lifecycle:lifecycle-common"))
- compile("androidx.annotation:annotation:1.1.0")
+ api(project(":lifecycle:lifecycle-common"))
+ api("androidx.annotation:annotation:1.1.0")
- testCompile(JUNIT)
- testCompile(MOCKITO_CORE)
+ testImplementation(JUNIT)
+ testImplementation(MOCKITO_CORE)
}
androidx {
diff --git a/lifecycle/lifecycle-common/build.gradle b/lifecycle/lifecycle-common/build.gradle
index 2168cfa..bfae8ef 100644
--- a/lifecycle/lifecycle-common/build.gradle
+++ b/lifecycle/lifecycle-common/build.gradle
@@ -30,9 +30,10 @@
targetCompatibility = JavaVersion.VERSION_1_7
dependencies {
- testCompile(JUNIT)
- testCompile(MOCKITO_CORE)
- compile("androidx.annotation:annotation:1.1.0")
+ api("androidx.annotation:annotation:1.1.0")
+
+ testImplementation(JUNIT)
+ testImplementation(MOCKITO_CORE)
}
androidx {
diff --git a/lifecycle/lifecycle-compiler/build.gradle b/lifecycle/lifecycle-compiler/build.gradle
index 22594250..4228710 100644
--- a/lifecycle/lifecycle-compiler/build.gradle
+++ b/lifecycle/lifecycle-compiler/build.gradle
@@ -22,13 +22,13 @@
}
dependencies {
- compile(project(":lifecycle:lifecycle-common"))
- compile(KOTLIN_STDLIB)
- compile(AUTO_COMMON)
- compile(JAVAPOET)
- testCompile(GOOGLE_COMPILE_TESTING)
- testCompile(JSR250)
- testCompile files(org.gradle.internal.jvm.Jvm.current().getToolsJar())
+ implementation(project(":lifecycle:lifecycle-common"))
+ implementation(KOTLIN_STDLIB)
+ implementation(AUTO_COMMON)
+ implementation(JAVAPOET)
+ testImplementation(GOOGLE_COMPILE_TESTING)
+ testImplementation(JSR250)
+ testImplementation files(org.gradle.internal.jvm.Jvm.current().getToolsJar())
}
// we actually need to compile :lifecycle:lifecycle-common, but compileJava is easier
diff --git a/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/LaunchWhenTest.kt b/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/LaunchWhenTest.kt
index b2dc7b3..7bdc5b8 100644
--- a/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/LaunchWhenTest.kt
+++ b/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/LaunchWhenTest.kt
@@ -17,13 +17,13 @@
package androidx.lifecycle
import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
+import androidx.test.filters.MediumTest
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
-@SmallTest
+@MediumTest
@RunWith(AndroidJUnit4::class)
class LaunchWhenTest {
private val expectations = Expectations()
diff --git a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java
index d541c90..e58afc2 100644
--- a/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java
+++ b/media2/player/src/androidTest/java/androidx/media2/player/MediaPlayerTest.java
@@ -1957,6 +1957,49 @@
assertTrue(latchFor3rdItem.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
+ @Ignore("Test disabled due to flakiness, see b/144972397")
+ @Test
+ @LargeTest
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+ public void testSeekToEndOfMediaItem() throws Exception {
+ List<MediaItem> playlist = new ArrayList<>();
+ playlist.add(createMediaItem(R.raw.testmp3));
+ playlist.add(createMediaItem(R.raw.testmp3));
+ playlist.add(createMediaItem(R.raw.testmp3));
+
+ List<CountDownLatch> latches = new ArrayList<>();
+ for (int i = 0; i < playlist.size(); i++) {
+ latches.add(new CountDownLatch(1));
+ }
+
+ MediaPlayer.PlayerCallback callback = new MediaPlayer.PlayerCallback() {
+ @Override
+ public void onCurrentMediaItemChanged(@NonNull SessionPlayer player,
+ @NonNull MediaItem item) {
+ for (int i = 0; i < playlist.size(); i++) {
+ if (playlist.get(i) == item) {
+ latches.get(i).countDown();
+ break;
+ }
+ }
+ }
+ };
+ mPlayer.registerPlayerCallback(mExecutor, callback);
+
+ assertNotNull(mPlayer.setPlaylist(playlist, null));
+ assertNotNull(mPlayer.prepare());
+ assertFutureSuccess(mPlayer.play());
+
+ for (int i = 0; i < playlist.size(); i++) {
+ assertTrue("onCurrentMediaItemChanged is not called for item i=" + i,
+ latches.get(i).await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ if (i + 1 < playlist.size()) {
+ long duration = mPlayer.getDuration();
+ assertNotEquals(SessionPlayer.UNKNOWN_TIME, duration);
+ assertFutureSuccess(mPlayer.seekTo(duration));
+ }
+ }
+ }
private MediaItem createMediaItem() throws Exception {
return createMediaItem(R.raw.testvideo);
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaController.java b/media2/session/src/main/java/androidx/media2/session/MediaController.java
index 0a5d41c..9513113 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaController.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaController.java
@@ -759,10 +759,9 @@
}
/**
- * Requests that the {@link SessionPlayer} associated with the connected {@link MediaSession}
- * rates the media. This will cause the rating to be set for the
- * current user. The rating style must follow the user rating style from the session.
- * You can get the rating style from the session through the
+ * Requests that the connected {@link MediaSession} rates the media. This will cause the rating
+ * to be set for the current user. The rating style must follow the user rating style from the
+ * session.You can get the rating style from the session through the
* {@link MediaMetadata#getRating(String)} with the key
* {@link MediaMetadata#METADATA_KEY_USER_RATING}.
* <p>
diff --git a/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java b/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java
index c648c91..f074256 100644
--- a/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java
+++ b/media2/widget/src/androidTest/java/androidx/media2/widget/VideoView_WithPlayerTest.java
@@ -370,7 +370,7 @@
withAspectRatio(videoSizeFor1stItem.getWidth(), videoSizeFor1stItem.getHeight())));
// seekTo instead of skipToNextItem (b/144876689)
- playerWrapper.seekTo(Long.MAX_VALUE);
+ playerWrapper.seekTo(playerWrapper.getDurationMs());
assertTrue(latchFor2ndItem.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
onView(instanceOf(VideoSurfaceView.class)).check(matches(
withAspectRatio(videoSizeFor2ndItem.getWidth(), videoSizeFor2ndItem.getHeight())));
diff --git a/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java b/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
index ebe8698..bf3d42e 100644
--- a/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
+++ b/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
@@ -30,6 +30,7 @@
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Build;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
@@ -127,6 +128,7 @@
private boolean mUseDynamicGroup;
private boolean mAlwaysVisible;
+ private boolean mCheatSheetEnabled;
// The checked state is used when connected to a remote route.
private static final int[] CHECKED_STATE_SET = {
@@ -367,8 +369,10 @@
* button when the button is long pressed.
*/
void setCheatSheetEnabled(boolean enable) {
- TooltipCompat.setTooltipText(this,
- enable ? getContext().getString(R.string.mr_button_content_description) : null);
+ if (enable != mCheatSheetEnabled) {
+ mCheatSheetEnabled = enable;
+ updateContentDescription();
+ }
}
@Override
@@ -671,7 +675,11 @@
break;
}
- setContentDescription(getContext().getString(resId));
+ String contentDesc = getContext().getString(resId);
+ setContentDescription(contentDesc);
+
+ TooltipCompat.setTooltipText(this,
+ mCheatSheetEnabled && !TextUtils.isEmpty(contentDesc) ? contentDesc : null);
}
private final class MediaRouterCallback extends MediaRouter.Callback {
diff --git a/mediarouter/src/main/res/layout/mr_playback_control.xml b/mediarouter/src/main/res/layout/mr_playback_control.xml
index eb9d109..580a234 100644
--- a/mediarouter/src/main/res/layout/mr_playback_control.xml
+++ b/mediarouter/src/main/res/layout/mr_playback_control.xml
@@ -41,16 +41,19 @@
android:layout_toStartOf="@id/mr_control_playback_ctrl"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
+ android:importantForAccessibility="no"
android:layout_centerVertical="true">
<TextView android:id="@+id/mr_control_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MediaRouter.PrimaryText"
+ android:clickable="false"
android:singleLine="true" />
<TextView android:id="@+id/mr_control_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText"
+ android:clickable="false"
android:singleLine="true" />
</LinearLayout>
</RelativeLayout>
diff --git a/navigation/integration-tests/safeargs-testapp/build.gradle b/navigation/integration-tests/safeargs-testapp/build.gradle
index 395f8c0..19182c7 100644
--- a/navigation/integration-tests/safeargs-testapp/build.gradle
+++ b/navigation/integration-tests/safeargs-testapp/build.gradle
@@ -66,6 +66,6 @@
dependencies {
implementation "${LibraryGroups.NAVIGATION}:navigation-runtime:${LibraryVersions.NAVIGATION}"
- testCompile(JUNIT)
- testCompile(MOCKITO_CORE)
+ testImplementation(JUNIT)
+ testImplementation(MOCKITO_CORE)
}
\ No newline at end of file
diff --git a/navigation/navigation-common/build.gradle b/navigation/navigation-common/build.gradle
index 8b6c8e7..47e140b 100644
--- a/navigation/navigation-common/build.gradle
+++ b/navigation/navigation-common/build.gradle
@@ -46,7 +46,7 @@
androidTestImplementation(KOTLIN_STDLIB)
}
-//used by testCompile safe-args-generator
+//used by testImplementation safe-args-generator
android.libraryVariants.all { variant ->
def name = variant.name
def suffix = name.capitalize()
diff --git a/navigation/navigation-dynamic-features-activity/build.gradle b/navigation/navigation-dynamic-features-activity/build.gradle
index 0358704..971db09 100644
--- a/navigation/navigation-dynamic-features-activity/build.gradle
+++ b/navigation/navigation-dynamic-features-activity/build.gradle
@@ -47,7 +47,7 @@
androidTestImplementation(TRUTH)
}
-//used by testCompile safe-args-generator
+//used by testImplementation safe-args-generator
android.libraryVariants.all { variant ->
def name = variant.name
def suffix = name.capitalize()
diff --git a/navigation/navigation-dynamic-features-core/build.gradle b/navigation/navigation-dynamic-features-core/build.gradle
index 4a03282..a994947 100644
--- a/navigation/navigation-dynamic-features-core/build.gradle
+++ b/navigation/navigation-dynamic-features-core/build.gradle
@@ -48,7 +48,7 @@
androidTestImplementation(TRUTH)
}
-//used by testCompile safe-args-generator
+//used by testImplementation safe-args-generator
android.libraryVariants.all { variant ->
def name = variant.name
def suffix = name.capitalize()
diff --git a/navigation/navigation-dynamic-features-fragment/build.gradle b/navigation/navigation-dynamic-features-fragment/build.gradle
index 67faed3..b6c19b2 100644
--- a/navigation/navigation-dynamic-features-fragment/build.gradle
+++ b/navigation/navigation-dynamic-features-fragment/build.gradle
@@ -59,7 +59,7 @@
}
}
-//used by testCompile safe-args-generator
+//used by testImplementation safe-args-generator
android.libraryVariants.all { variant ->
def name = variant.name
def suffix = name.capitalize()
diff --git a/navigation/navigation-safe-args-generator/build.gradle b/navigation/navigation-safe-args-generator/build.gradle
index 325d701..7f36bfe 100644
--- a/navigation/navigation-safe-args-generator/build.gradle
+++ b/navigation/navigation-safe-args-generator/build.gradle
@@ -36,20 +36,20 @@
}
dependencies {
- compile(XPP3)
- compile(XMLPULL)
- compile(KOTLIN_STDLIB)
+ implementation(XPP3)
+ implementation(XMLPULL)
+ implementation(KOTLIN_STDLIB)
- compile(JAVAPOET)
- compile(KOTLINPOET)
+ implementation(JAVAPOET)
+ implementation(KOTLINPOET)
- testCompile(JUNIT)
- testCompile(GOOGLE_COMPILE_TESTING)
- testCompile fileTree(dir: "${SdkHelperKt.getSdkPath(project.rootDir)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
+ testImplementation(JUNIT)
+ testImplementation(GOOGLE_COMPILE_TESTING)
+ testImplementation fileTree(dir: "${SdkHelperKt.getSdkPath(project.rootDir)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
include : "android.jar")
- testCompile fileTree(dir: "${new File(project(":navigation:navigation-common").buildDir, "libJar")}",
+ testImplementation fileTree(dir: "${new File(project(":navigation:navigation-common").buildDir, "libJar")}",
include : "*.jar")
- testCompile files(Jvm.current().getToolsJar())
+ testImplementation files(Jvm.current().getToolsJar())
}
tasks.findByName("test").doFirst {
diff --git a/navigation/navigation-safe-args-gradle-plugin/build.gradle b/navigation/navigation-safe-args-gradle-plugin/build.gradle
index 9c382fa..d43cd41 100644
--- a/navigation/navigation-safe-args-gradle-plugin/build.gradle
+++ b/navigation/navigation-safe-args-gradle-plugin/build.gradle
@@ -38,13 +38,13 @@
}
dependencies {
- compile(AGP_STABLE)
- compile(KOTLIN_GRADLE_PLUGIN)
+ implementation(AGP_STABLE)
+ implementation(KOTLIN_GRADLE_PLUGIN)
compile project(":navigation:navigation-safe-args-generator")
compile gradleApi()
- compile(GSON)
- testCompile gradleTestKit()
- testCompile(JUNIT)
+ implementation(GSON)
+ testImplementation gradleTestKit()
+ testImplementation(JUNIT)
}
task generateSdkResource() {
diff --git a/paging/common/build.gradle b/paging/common/build.gradle
index 9fb3baf..7528976 100644
--- a/paging/common/build.gradle
+++ b/paging/common/build.gradle
@@ -28,13 +28,13 @@
}
dependencies {
- compile("androidx.annotation:annotation:1.1.0")
- compile("androidx.arch.core:core-common:2.0.1")
+ api("androidx.annotation:annotation:1.1.0")
+ api("androidx.arch.core:core-common:2.0.1")
api(KOTLIN_STDLIB)
api(KOTLIN_COROUTINES_CORE)
- testCompile(JUNIT)
- testCompile(MOCKITO_CORE)
+ testImplementation(JUNIT)
+ testImplementation(MOCKITO_CORE)
testImplementation MOCKITO_KOTLIN, {
exclude group: 'org.mockito' // to keep control on the mockito version
}
diff --git a/room/common/build.gradle b/room/common/build.gradle
index 3ee72ae..e10ee75 100644
--- a/room/common/build.gradle
+++ b/room/common/build.gradle
@@ -26,11 +26,11 @@
}
dependencies {
- compile("androidx.annotation:annotation:1.1.0")
- testCompile(KOTLIN_STDLIB)
- testCompile(JUNIT)
- testCompile(MOCKITO_CORE)
- testCompile(GUAVA)
+ api("androidx.annotation:annotation:1.1.0")
+ testImplementation(KOTLIN_STDLIB)
+ testImplementation(JUNIT)
+ testImplementation(MOCKITO_CORE)
+ testImplementation(GUAVA)
}
androidx {
diff --git a/room/compiler/build.gradle b/room/compiler/build.gradle
index e4adab3..a661005 100644
--- a/room/compiler/build.gradle
+++ b/room/compiler/build.gradle
@@ -46,36 +46,36 @@
}
dependencies {
- compile(project(":room:room-common"))
- compile(project(":room:room-migration"))
- compile(KOTLIN_STDLIB)
- compile(AUTO_COMMON)
- compile(AUTO_VALUE_ANNOTATIONS)
- compile(JAVAPOET)
- compile(ANTLR)
- compile(XERIAL)
- compile(KOTLIN_METADATA_JVM)
- compile(APACHE_COMMONS_CODEC)
- compile(INTELLIJ_ANNOTATIONS)
- testCompile(GOOGLE_COMPILE_TESTING)
- testCompile project(":paging:paging-common")
- testCompile(JUNIT)
- testCompile(JSR250)
- testCompile(MOCKITO_CORE)
- testCompile fileTree(dir: "${SdkHelperKt.getSdkPath(project.rootDir)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
+ implementation(project(":room:room-common"))
+ implementation(project(":room:room-migration"))
+ implementation(KOTLIN_STDLIB)
+ implementation(AUTO_COMMON)
+ implementation(AUTO_VALUE_ANNOTATIONS)
+ implementation(JAVAPOET)
+ implementation(ANTLR)
+ implementation(XERIAL)
+ implementation(KOTLIN_METADATA_JVM)
+ implementation(APACHE_COMMONS_CODEC)
+ implementation(INTELLIJ_ANNOTATIONS)
+ testImplementation(GOOGLE_COMPILE_TESTING)
+ testImplementation project(":paging:paging-common")
+ testImplementation(JUNIT)
+ testImplementation(JSR250)
+ testImplementation(MOCKITO_CORE)
+ testImplementation fileTree(dir: "${SdkHelperKt.getSdkPath(project.rootDir)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
include : "android.jar")
- testCompile fileTree(dir: "${new File(project(":room:room-runtime").buildDir, "libJar")}",
+ testImplementation fileTree(dir: "${new File(project(":room:room-runtime").buildDir, "libJar")}",
include : "*.jar")
- testCompile fileTree(dir: "${new File(project(":sqlite:sqlite").buildDir, "libJar")}",
+ testImplementation fileTree(dir: "${new File(project(":sqlite:sqlite").buildDir, "libJar")}",
include : "*.jar")
- testCompile files(Jvm.current().getToolsJar())
+ testImplementation files(Jvm.current().getToolsJar())
}
def generateAntlrTask = task('generateAntlrGrammar', type: JavaExec) {
def outFolder = file(antlrOut)
outputs.dir(outFolder)
inputs.file("$projectDir/SQLite.g4")
- classpath configurations.runtime
+ classpath configurations.compileClasspath
main "org.antlr.v4.Tool"
args "SQLite.g4", "-visitor", "-o", new File(outFolder, "androidx/room/parser").path,
"-package", "androidx.room.parser"
diff --git a/room/integration-tests/incremental-annotation-processing/build.gradle b/room/integration-tests/incremental-annotation-processing/build.gradle
index 21fe960..aeb543f 100644
--- a/room/integration-tests/incremental-annotation-processing/build.gradle
+++ b/room/integration-tests/incremental-annotation-processing/build.gradle
@@ -35,7 +35,7 @@
dependencies {
- compile(KOTLIN_STDLIB)
+ implementation(KOTLIN_STDLIB)
testImplementation(JUNIT)
testImplementation(TRUTH)
testImplementation gradleTestKit()
diff --git a/room/migration/build.gradle b/room/migration/build.gradle
index ecd8634..07b5b1b 100644
--- a/room/migration/build.gradle
+++ b/room/migration/build.gradle
@@ -26,12 +26,12 @@
}
dependencies {
- compile(project(":room:room-common"))
- compile(KOTLIN_STDLIB)
- compile(GSON)
- testCompile(JUNIT)
- testCompile(INTELLIJ_ANNOTATIONS)
- testCompile(MOCKITO_CORE)
+ implementation(project(":room:room-common"))
+ implementation(KOTLIN_STDLIB)
+ implementation(GSON)
+ testImplementation(JUNIT)
+ testImplementation(INTELLIJ_ANNOTATIONS)
+ testImplementation(MOCKITO_CORE)
}
androidx {
diff --git a/room/runtime/build.gradle b/room/runtime/build.gradle
index 0f271d7..123977a 100644
--- a/room/runtime/build.gradle
+++ b/room/runtime/build.gradle
@@ -60,7 +60,7 @@
def name = variant.name
def suffix = name.capitalize()
- // Create jar<variant> task for testCompile in room-compiler.
+ // Create jar<variant> task for testImplementation in room-compiler.
project.tasks.create(name: "jar${suffix}", type: Jar){
dependsOn variant.javaCompileProvider.get()
from variant.javaCompileProvider.get().destinationDir
diff --git a/samples/Support7Demos/src/main/res/layout/appcompat_night_mode.xml b/samples/Support7Demos/src/main/res/layout/appcompat_night_mode.xml
index cdae523..974ff3f 100644
--- a/samples/Support7Demos/src/main/res/layout/appcompat_night_mode.xml
+++ b/samples/Support7Demos/src/main/res/layout/appcompat_night_mode.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,43 +15,48 @@
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <Button
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="wrap_content"
+ android:onClick="setModeNightFollowSystem"
+ android:text="@string/mode_night_follow_system" />
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:padding="16dp">
-
- <Button android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/mode_night_follow_system"
- android:onClick="setModeNightFollowSystem"/>
-
- <Button android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/mode_night_no"
- android:onClick="setModeNightNo"/>
-
- <Button android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/mode_night_yes"
- android:onClick="setModeNightYes"/>
-
- <Button android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/mode_night_auto_time"
- android:onClick="setModeNightAutoTime"/>
-
- <Button android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/mode_night_auto_battery"
- android:onClick="setModeNightAutoBattery"/>
-
- <View
+ <Button
android:layout_width="match_parent"
- android:layout_height="100dp" />
+ android:layout_height="wrap_content"
+ android:onClick="setModeNightNo"
+ android:text="@string/mode_night_no" />
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:onClick="setModeNightYes"
+ android:text="@string/mode_night_yes" />
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:onClick="setModeNightAutoTime"
+ android:text="@string/mode_night_auto_time" />
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:onClick="setModeNightAutoBattery"
+ android:text="@string/mode_night_auto_battery" />
+
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="64dp" />
<TextView
android:id="@+id/text_night_mode"
@@ -66,6 +70,17 @@
android:layout_height="100dp"
android:background="@drawable/test_night_color_conversion_background" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/webview" />
+
+ <WebView
+ android:id="@+id/webview"
+ android:layout_width="match_parent"
+ android:layout_height="100dp" />
+
</LinearLayout>
</ScrollView>
\ No newline at end of file
diff --git a/samples/Support7Demos/src/main/res/values/strings.xml b/samples/Support7Demos/src/main/res/values/strings.xml
index 238eb78..5ba149b 100644
--- a/samples/Support7Demos/src/main/res/values/strings.xml
+++ b/samples/Support7Demos/src/main/res/values/strings.xml
@@ -276,4 +276,6 @@
<string name="menu_item_icon_tinting">AppCompat/Menu Item Icons</string>
<string name="popup_group_dividers">Display group dividers</string>
+
+ <string name="webview">WebView</string>
</resources>
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java
index 0a0a64d..b48f106 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java
@@ -179,7 +179,6 @@
/**
*/
- @NonNull
private void addText(@NonNull CharSequence text) {
addText(text, false /* isLoading */);
}
@@ -195,14 +194,12 @@
/**
*/
- @NonNull
private void addTitleText(@NonNull CharSequence text) {
addTitleText(text, false /* isLoading */);
}
/**
*/
- @NonNull
private void addTitleText(@Nullable CharSequence text, boolean isLoading) {
@Slice.SliceHint String[] hints = isLoading
? new String[] {HINT_PARTIAL, HINT_TITLE}
@@ -212,14 +209,12 @@
/**
*/
- @NonNull
private void addImage(@NonNull IconCompat image, int imageMode) {
addImage(image, imageMode, false /* isLoading */);
}
/**
*/
- @NonNull
private void addImage(@Nullable IconCompat image, int imageMode, boolean isLoading) {
ArrayList<String> hints = new ArrayList<>();
if (imageMode != ICON_IMAGE) {
@@ -236,7 +231,6 @@
/**
*/
- @NonNull
private void setContentIntent(@NonNull PendingIntent intent) {
mContentIntent = intent;
}
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java
index 8a8954c..6fffae4 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java
@@ -157,7 +157,6 @@
/**
* Add a row to list builder.
*/
- @NonNull
@Override
public void addRow(@NonNull RowBuilder builder) {
RowBuilderImpl impl = new RowBuilderImpl(createChildBuilder());
@@ -169,7 +168,6 @@
/**
* Add a row to list builder.
*/
- @NonNull
public void addRow(@NonNull RowBuilderImpl builder) {
checkRow(true, builder.hasText());
builder.getBuilder().addHints(HINT_LIST_ITEM);
@@ -178,7 +176,6 @@
/**
*/
- @NonNull
@Override
public void addGridRow(@NonNull GridRowBuilder builder) {
checkRow(false, false);
@@ -260,7 +257,6 @@
/**
*/
- @NonNull
@Override
public void setColor(@ColorInt int color) {
getBuilder().addInt(color, SUBTYPE_COLOR);
@@ -487,7 +483,6 @@
/**
*/
- @NonNull
private void setTitleItem(long timeStamp) {
mStartItem = new Slice.Builder(getBuilder())
.addTimestamp(timeStamp, null).addHints(HINT_TITLE).build();
@@ -495,14 +490,12 @@
/**
*/
- @NonNull
protected void setTitleItem(IconCompat icon, int imageMode) {
setTitleItem(icon, imageMode, false /* isLoading */);
}
/**
*/
- @NonNull
private void setTitleItem(IconCompat icon, int imageMode, boolean isLoading) {
ArrayList<String> hints = new ArrayList<>();
if (imageMode != ICON_IMAGE) {
@@ -524,7 +517,6 @@
/**
*/
- @NonNull
private void setTitleItem(@NonNull SliceAction action) {
setTitleItem(action, false /* isLoading */);
}
@@ -541,14 +533,12 @@
/**
*/
- @NonNull
private void setPrimaryAction(@NonNull SliceAction action) {
mPrimaryAction = action;
}
/**
*/
- @NonNull
private void setTitle(CharSequence title) {
setTitle(title, false /* isLoading */);
}
@@ -564,7 +554,6 @@
/**
*/
- @NonNull
protected void setSubtitle(CharSequence subtitle) {
setSubtitle(subtitle, false /* isLoading */);
}
@@ -580,7 +569,6 @@
/**
*/
- @NonNull
protected void addEndItem(long timeStamp) {
mEndItems.add(new Slice.Builder(getBuilder()).addTimestamp(timeStamp,
null, new String[0]).build());
@@ -588,14 +576,12 @@
/**
*/
- @NonNull
private void addEndItem(IconCompat icon, int imageMode) {
addEndItem(icon, imageMode, false /* isLoading */);
}
/**
*/
- @NonNull
private void addEndItem(IconCompat icon, int imageMode, boolean isLoading) {
ArrayList<String> hints = new ArrayList<>();
if (imageMode != ICON_IMAGE) {
@@ -617,7 +603,6 @@
/**
*/
- @NonNull
private void addEndItem(@NonNull SliceAction action) {
addEndItem(action, false /* isLoading */);
}
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/MessagingBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/impl/MessagingBuilder.java
index d9214c9..4285eae 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/MessagingBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/MessagingBuilder.java
@@ -41,7 +41,7 @@
/**
*/
- public interface MessageBuilder {
+ interface MessageBuilder {
/**
* Add the icon used to display contact in the messaging experience
diff --git a/sqlite/sqlite/build.gradle b/sqlite/sqlite/build.gradle
index 648b276..1ef1d1c 100644
--- a/sqlite/sqlite/build.gradle
+++ b/sqlite/sqlite/build.gradle
@@ -31,7 +31,7 @@
testImplementation(MOCKITO_CORE)
}
-// Used by testCompile in room-compiler
+// Used by testImplementation in room-compiler
android.libraryVariants.all { variant ->
def name = variant.name
def suffix = name.capitalize()
diff --git a/test/screenshot/proto/build.gradle b/test/screenshot/proto/build.gradle
index 728f34c..80b5a2a 100644
--- a/test/screenshot/proto/build.gradle
+++ b/test/screenshot/proto/build.gradle
@@ -30,7 +30,7 @@
apply(plugin: "com.google.protobuf")
dependencies {
- compile(PROTOBUF)
+ implementation(PROTOBUF)
}
tasks.withType(Jar) {
diff --git a/ui/gradle/wrapper/gradle-wrapper.properties b/ui/gradle/wrapper/gradle-wrapper.properties
index c62ad8a..ec9defd 100644
--- a/ui/gradle/wrapper/gradle-wrapper.properties
+++ b/ui/gradle/wrapper/gradle-wrapper.properties
@@ -5,4 +5,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=../../../../../tools/external/gradle/gradle-5.6.2-bin.zip
+distributionUrl=../../../../../tools/external/gradle/gradle-6.0-bin.zip
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RadioGroupBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RadioGroupBenchmark.kt
new file mode 100644
index 0000000..36ed034
--- /dev/null
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RadioGroupBenchmark.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.benchmark.test
+
+import androidx.compose.Composable
+import androidx.compose.Model
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.ui.benchmark.ComposeBenchmarkRule
+import androidx.ui.benchmark.benchmarkFirstCompose
+import androidx.ui.benchmark.benchmarkFirstDraw
+import androidx.ui.benchmark.benchmarkFirstLayout
+import androidx.ui.benchmark.benchmarkFirstMeasure
+import androidx.ui.benchmark.toggleStateBenchmarkDraw
+import androidx.ui.benchmark.toggleStateBenchmarkLayout
+import androidx.ui.benchmark.toggleStateBenchmarkMeasure
+import androidx.ui.benchmark.toggleStateBenchmarkRecompose
+import androidx.ui.layout.Column
+import androidx.ui.material.MaterialTheme
+import androidx.ui.material.RadioGroup
+import androidx.ui.test.ComposeTestCase
+import androidx.ui.test.ToggleableTestCase
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Benchmark for [RadioGroup].
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class RadioGroupBenchmark {
+
+ @get:Rule
+ val benchmarkRule = ComposeBenchmarkRule()
+
+ private val radioCaseFactory = { RadioGroupTestCase() }
+
+ @Test
+ fun first_compose() {
+ benchmarkRule.benchmarkFirstCompose(radioCaseFactory)
+ }
+
+ @Test
+ fun first_measure() {
+ benchmarkRule.benchmarkFirstMeasure(radioCaseFactory)
+ }
+
+ @Test
+ fun first_layout() {
+ benchmarkRule.benchmarkFirstLayout(radioCaseFactory)
+ }
+
+ @Test
+ fun first_draw() {
+ benchmarkRule.benchmarkFirstDraw(radioCaseFactory)
+ }
+
+ @Test
+ fun toggleRadio_recompose() {
+ benchmarkRule.toggleStateBenchmarkRecompose(radioCaseFactory)
+ }
+
+ @Test
+ fun toggleRadio_measure() {
+ benchmarkRule.toggleStateBenchmarkMeasure(radioCaseFactory)
+ }
+
+ @Test
+ fun toggleRadio_layout() {
+ benchmarkRule.toggleStateBenchmarkLayout(radioCaseFactory)
+ }
+
+ @Test
+ fun toggleRadio_draw() {
+ benchmarkRule.toggleStateBenchmarkDraw(radioCaseFactory)
+ }
+}
+
+@Model
+internal class RadioGroupSelectedState<T>(var selected: T)
+
+internal class RadioGroupTestCase : ComposeTestCase, ToggleableTestCase {
+
+ private val radiosCount = 10
+ private val options = (0 until radiosCount).toList()
+ private val select = RadioGroupSelectedState(0)
+
+ override fun toggleState() {
+ select.selected = (select.selected + 1) % radiosCount
+ }
+
+ @Composable
+ override fun emitContent() {
+ MaterialTheme {
+ RadioGroup {
+ Column {
+ options.forEach { item ->
+ RadioGroupTextItem(
+ text = item.toString(),
+ selected = (select.selected == item),
+ onSelect = { select.selected = item })
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt
index af313d2..c84a1c9 100644
--- a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt
@@ -26,6 +26,7 @@
import androidx.ui.benchmark.toggleStateBenchmarkMeasureLayout
import androidx.ui.core.Placeable.PlacementScope.place
import androidx.ui.layout.Container
+import androidx.ui.layout.Size
import androidx.ui.layout.Spacer
import androidx.ui.test.ComposeTestCase
import androidx.ui.test.ToggleableTestCase
@@ -66,7 +67,7 @@
val size = +state { 200.dp }
this.state = size
Container(width = 300.dp, height = 300.dp) {
- Spacer(androidx.ui.layout.Size(width = size.value, height = size.value))
+ Spacer(Size(width = size.value, height = size.value))
}
}
@@ -85,7 +86,7 @@
this.state = size
WithConstraints {
Container(width = 300.dp, height = 300.dp) {
- Spacer(androidx.ui.layout.Size(width = size.value, height = size.value))
+ Spacer(Size(width = size.value, height = size.value))
}
}
}
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/test/TextBenchmarkHelper.kt b/ui/integration-tests/test/src/main/java/androidx/ui/test/TextBenchmarkHelper.kt
index 8c03978..34dfb00 100644
--- a/ui/integration-tests/test/src/main/java/androidx/ui/test/TextBenchmarkHelper.kt
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/test/TextBenchmarkHelper.kt
@@ -123,7 +123,7 @@
AnnotatedString.Item(
start = start,
end = end,
- style = textStyleList[styleIndex++ % textStyleList.size]
+ item = textStyleList[styleIndex++ % textStyleList.size]
)
}
}
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/ColorPaletteTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/ColorPaletteTestCase.kt
index 907e572..8745eee 100644
--- a/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/ColorPaletteTestCase.kt
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/test/cases/ColorPaletteTestCase.kt
@@ -24,6 +24,7 @@
import androidx.ui.graphics.Color
import androidx.ui.material.ColorPalette
import androidx.ui.material.MaterialTheme
+import androidx.ui.material.lightColorPalette
import androidx.ui.test.ComposeTestCase
import androidx.ui.test.ToggleableTestCase
@@ -65,7 +66,7 @@
*/
class ObservableColorPaletteTestCase : ColorPaletteTestCase() {
override fun createPalette(primary: Color): ColorPalette {
- return ColorPalette(primary = primary)
+ return lightColorPalette(primary = primary)
}
}
@@ -89,6 +90,7 @@
override val onBackground = Color.Black
override val onSurface = Color.Black
override val onError = Color.Black
+ override val isLight = true
}
}
diff --git a/ui/ui-animation/api/0.1.0-dev03.txt b/ui/ui-animation/api/0.1.0-dev03.txt
index e1311a3..fc57f9b 100644
--- a/ui/ui-animation/api/0.1.0-dev03.txt
+++ b/ui/ui-animation/api/0.1.0-dev03.txt
@@ -35,7 +35,7 @@
public final class TransitionKt {
ctor public TransitionKt();
- method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+ method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), T? initState = toState, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
method public static boolean getTransitionsEnabled();
method public static void setTransitionsEnabled(boolean p);
}
diff --git a/ui/ui-animation/api/current.txt b/ui/ui-animation/api/current.txt
index e1311a3..fc57f9b 100644
--- a/ui/ui-animation/api/current.txt
+++ b/ui/ui-animation/api/current.txt
@@ -35,7 +35,7 @@
public final class TransitionKt {
ctor public TransitionKt();
- method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+ method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), T? initState = toState, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
method public static boolean getTransitionsEnabled();
method public static void setTransitionsEnabled(boolean p);
}
diff --git a/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt
index e1311a3..fc57f9b 100644
--- a/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt
@@ -35,7 +35,7 @@
public final class TransitionKt {
ctor public TransitionKt();
- method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+ method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), T? initState = toState, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
method public static boolean getTransitionsEnabled();
method public static void setTransitionsEnabled(boolean p);
}
diff --git a/ui/ui-animation/api/public_plus_experimental_current.txt b/ui/ui-animation/api/public_plus_experimental_current.txt
index e1311a3..fc57f9b 100644
--- a/ui/ui-animation/api/public_plus_experimental_current.txt
+++ b/ui/ui-animation/api/public_plus_experimental_current.txt
@@ -35,7 +35,7 @@
public final class TransitionKt {
ctor public TransitionKt();
- method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+ method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), T? initState = toState, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
method public static boolean getTransitionsEnabled();
method public static void setTransitionsEnabled(boolean p);
}
diff --git a/ui/ui-animation/api/restricted_0.1.0-dev03.txt b/ui/ui-animation/api/restricted_0.1.0-dev03.txt
index e1311a3..fc57f9b 100644
--- a/ui/ui-animation/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-animation/api/restricted_0.1.0-dev03.txt
@@ -35,7 +35,7 @@
public final class TransitionKt {
ctor public TransitionKt();
- method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+ method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), T? initState = toState, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
method public static boolean getTransitionsEnabled();
method public static void setTransitionsEnabled(boolean p);
}
diff --git a/ui/ui-animation/api/restricted_current.txt b/ui/ui-animation/api/restricted_current.txt
index e1311a3..fc57f9b 100644
--- a/ui/ui-animation/api/restricted_current.txt
+++ b/ui/ui-animation/api/restricted_current.txt
@@ -35,7 +35,7 @@
public final class TransitionKt {
ctor public TransitionKt();
- method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+ method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), T? initState = toState, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onStateChangeFinished = null, kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
method public static boolean getTransitionsEnabled();
method public static void setTransitionsEnabled(boolean p);
}
diff --git a/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/TransitionSamples.kt b/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/TransitionSamples.kt
index 8205eda..f2defe1 100644
--- a/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/TransitionSamples.kt
+++ b/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/TransitionSamples.kt
@@ -43,8 +43,20 @@
@Composable
fun TransitionBasedColoredRect() {
- Transition(definition = definition, toState = State.Second) { state ->
+ // This puts the transition in State.First. Any subsequent state change will trigger a
+ // transition animation, as defined in the transition definition.
+ Transition(definition = definition, toState = State.First) { state ->
ColoredRect(color = state[ColorKey])
}
}
-}
\ No newline at end of file
+
+ @Composable
+ fun ColorRectWithInitState() {
+ // This starts the transition going from State.First to State.Second when this composable
+ // gets composed for the first time.
+ Transition(definition = definition, initState = State.First, toState = State.Second) {
+ state ->
+ ColoredRect(color = state[ColorKey])
+ }
+ }
+}
diff --git a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
index fe609ff..9c20fb4 100644
--- a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
+++ b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
@@ -30,21 +30,33 @@
import androidx.ui.core.AnimationClockAmbient
/**
- * Composable to use with TransitionDefinition-based animations.
+ * Composable to use with [TransitionDefinition]-based animations.
+ *
+ * @param definition Transition definition that defines states and transitions
+ * @param toState New state to transition to
+ * @param clock Animation clock that pulses animations when time changes. By default the clock is
+ * read from the ambient.
+ * @param initState Optional initial state for the transition. When undefined, the initial state
+ * will be set to the first [toState] seen in the transition.
+ * @param onStateChangeFinished An optional listener to get notified when state change animation
+ * has completed
+ * @param children The children composables that will be animated
*
* @sample androidx.ui.animation.samples.TransitionSample
*/
+// TODO: The list of params is getting a bit long. Consider grouping them.
@Composable
fun <T> Transition(
definition: TransitionDefinition<T>,
toState: T,
clock: AnimationClockObservable = +ambient(AnimationClockAmbient),
+ initState: T = toState,
onStateChangeFinished: ((T) -> Unit)? = null,
children: @Composable() (state: TransitionState) -> Unit
) {
if (transitionsEnabled) {
// TODO: This null is workaround for b/132148894
- val model = +memo(definition, null) { TransitionModel(definition, toState, clock) }
+ val model = +memo(definition, null) { TransitionModel(definition, initState, clock) }
model.anim.onStateChangeFinished = onStateChangeFinished
model.anim.toState(toState)
children(model)
diff --git a/ui/ui-core/api/0.1.0-dev03.txt b/ui/ui-core/api/0.1.0-dev03.txt
index 481f79e..18070d8 100644
--- a/ui/ui-core/api/0.1.0-dev03.txt
+++ b/ui/ui-core/api/0.1.0-dev03.txt
@@ -5,6 +5,7 @@
ctor public MathHelpersKt();
method public static float lerp(float start, float stop, float fraction);
method public static int lerp(int start, int stop, float fraction);
+ method public static long lerp(long start, long stop, float fraction);
method public static String toHexString(int);
method public static String toStringAsFixed(float, int digits);
}
@@ -532,7 +533,7 @@
method public default androidx.ui.core.IntPx? modifyAlignmentLine(androidx.ui.core.DensityScope, androidx.ui.core.AlignmentLine line, androidx.ui.core.IntPx? value);
method public default androidx.ui.core.Constraints modifyConstraints(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints);
method public default Object? modifyParentData(androidx.ui.core.DensityScope, Object? parentData);
- method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxPosition childPosition, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
+ method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
method public default androidx.ui.core.IntPxSize modifySize(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints, androidx.ui.core.IntPxSize childSize);
}
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index 481f79e..18070d8 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -5,6 +5,7 @@
ctor public MathHelpersKt();
method public static float lerp(float start, float stop, float fraction);
method public static int lerp(int start, int stop, float fraction);
+ method public static long lerp(long start, long stop, float fraction);
method public static String toHexString(int);
method public static String toStringAsFixed(float, int digits);
}
@@ -532,7 +533,7 @@
method public default androidx.ui.core.IntPx? modifyAlignmentLine(androidx.ui.core.DensityScope, androidx.ui.core.AlignmentLine line, androidx.ui.core.IntPx? value);
method public default androidx.ui.core.Constraints modifyConstraints(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints);
method public default Object? modifyParentData(androidx.ui.core.DensityScope, Object? parentData);
- method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxPosition childPosition, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
+ method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
method public default androidx.ui.core.IntPxSize modifySize(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints, androidx.ui.core.IntPxSize childSize);
}
diff --git a/ui/ui-core/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-core/api/public_plus_experimental_0.1.0-dev03.txt
index 481f79e..18070d8 100644
--- a/ui/ui-core/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-core/api/public_plus_experimental_0.1.0-dev03.txt
@@ -5,6 +5,7 @@
ctor public MathHelpersKt();
method public static float lerp(float start, float stop, float fraction);
method public static int lerp(int start, int stop, float fraction);
+ method public static long lerp(long start, long stop, float fraction);
method public static String toHexString(int);
method public static String toStringAsFixed(float, int digits);
}
@@ -532,7 +533,7 @@
method public default androidx.ui.core.IntPx? modifyAlignmentLine(androidx.ui.core.DensityScope, androidx.ui.core.AlignmentLine line, androidx.ui.core.IntPx? value);
method public default androidx.ui.core.Constraints modifyConstraints(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints);
method public default Object? modifyParentData(androidx.ui.core.DensityScope, Object? parentData);
- method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxPosition childPosition, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
+ method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
method public default androidx.ui.core.IntPxSize modifySize(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints, androidx.ui.core.IntPxSize childSize);
}
diff --git a/ui/ui-core/api/public_plus_experimental_current.txt b/ui/ui-core/api/public_plus_experimental_current.txt
index 481f79e..18070d8 100644
--- a/ui/ui-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-core/api/public_plus_experimental_current.txt
@@ -5,6 +5,7 @@
ctor public MathHelpersKt();
method public static float lerp(float start, float stop, float fraction);
method public static int lerp(int start, int stop, float fraction);
+ method public static long lerp(long start, long stop, float fraction);
method public static String toHexString(int);
method public static String toStringAsFixed(float, int digits);
}
@@ -532,7 +533,7 @@
method public default androidx.ui.core.IntPx? modifyAlignmentLine(androidx.ui.core.DensityScope, androidx.ui.core.AlignmentLine line, androidx.ui.core.IntPx? value);
method public default androidx.ui.core.Constraints modifyConstraints(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints);
method public default Object? modifyParentData(androidx.ui.core.DensityScope, Object? parentData);
- method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxPosition childPosition, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
+ method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
method public default androidx.ui.core.IntPxSize modifySize(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints, androidx.ui.core.IntPxSize childSize);
}
diff --git a/ui/ui-core/api/restricted_0.1.0-dev03.txt b/ui/ui-core/api/restricted_0.1.0-dev03.txt
index 481f79e..18070d8 100644
--- a/ui/ui-core/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-core/api/restricted_0.1.0-dev03.txt
@@ -5,6 +5,7 @@
ctor public MathHelpersKt();
method public static float lerp(float start, float stop, float fraction);
method public static int lerp(int start, int stop, float fraction);
+ method public static long lerp(long start, long stop, float fraction);
method public static String toHexString(int);
method public static String toStringAsFixed(float, int digits);
}
@@ -532,7 +533,7 @@
method public default androidx.ui.core.IntPx? modifyAlignmentLine(androidx.ui.core.DensityScope, androidx.ui.core.AlignmentLine line, androidx.ui.core.IntPx? value);
method public default androidx.ui.core.Constraints modifyConstraints(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints);
method public default Object? modifyParentData(androidx.ui.core.DensityScope, Object? parentData);
- method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxPosition childPosition, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
+ method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
method public default androidx.ui.core.IntPxSize modifySize(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints, androidx.ui.core.IntPxSize childSize);
}
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index 481f79e..18070d8 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -5,6 +5,7 @@
ctor public MathHelpersKt();
method public static float lerp(float start, float stop, float fraction);
method public static int lerp(int start, int stop, float fraction);
+ method public static long lerp(long start, long stop, float fraction);
method public static String toHexString(int);
method public static String toStringAsFixed(float, int digits);
}
@@ -532,7 +533,7 @@
method public default androidx.ui.core.IntPx? modifyAlignmentLine(androidx.ui.core.DensityScope, androidx.ui.core.AlignmentLine line, androidx.ui.core.IntPx? value);
method public default androidx.ui.core.Constraints modifyConstraints(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints);
method public default Object? modifyParentData(androidx.ui.core.DensityScope, Object? parentData);
- method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxPosition childPosition, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
+ method public default androidx.ui.core.IntPxPosition modifyPosition(androidx.ui.core.DensityScope, androidx.ui.core.IntPxSize childSize, androidx.ui.core.IntPxSize containerSize);
method public default androidx.ui.core.IntPxSize modifySize(androidx.ui.core.DensityScope, androidx.ui.core.Constraints constraints, androidx.ui.core.IntPxSize childSize);
}
diff --git a/ui/ui-core/src/main/java/androidx/ui/MathHelpers.kt b/ui/ui-core/src/main/java/androidx/ui/MathHelpers.kt
index 7b233d5..e707f3d 100644
--- a/ui/ui-core/src/main/java/androidx/ui/MathHelpers.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/MathHelpers.kt
@@ -16,19 +16,27 @@
package androidx.ui
import kotlin.math.roundToInt
+import kotlin.math.roundToLong
/**
* Linearly interpolate between [start] and [stop] with [fraction] fraction between them.
*/
fun lerp(start: Float, stop: Float, fraction: Float): Float {
- return start + (stop - start) * fraction
+ return (1 - fraction) * start + fraction * stop
}
/**
* Linearly interpolate between [start] and [stop] with [fraction] fraction between them.
*/
fun lerp(start: Int, stop: Int, fraction: Float): Int {
- return start + ((stop - start) * fraction).roundToInt()
+ return start + ((stop - start) * fraction.toDouble()).roundToInt()
+}
+
+/**
+ * Linearly interpolate between [start] and [stop] with [fraction] fraction between them.
+ */
+fun lerp(start: Long, stop: Long, fraction: Float): Long {
+ return start + ((stop - start) * fraction.toDouble()).roundToLong()
}
fun Float.toStringAsFixed(digits: Int) = String.format("%.${digits}f", this)
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/Dp.kt b/ui/ui-core/src/main/java/androidx/ui/core/Dp.kt
index 28ecc3f..e8917eb 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/Dp.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/Dp.kt
@@ -180,7 +180,6 @@
/**
* Ensures that this value is not less than the specified [minimumValue].
- *
* @return this value if it's greater than or equal to the [minimumValue] or the
* [minimumValue] otherwise.
*/
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/LayoutModifier.kt b/ui/ui-core/src/main/java/androidx/ui/core/LayoutModifier.kt
index 9a39c3a..8678c06 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/LayoutModifier.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/LayoutModifier.kt
@@ -77,10 +77,9 @@
* size [containerSize].
*/
fun DensityScope.modifyPosition(
- childPosition: IntPxPosition,
childSize: IntPxSize,
containerSize: IntPxSize
- ): IntPxPosition = childPosition
+ ): IntPxPosition = IntPxPosition.Origin
/**
* Returns the modified position of [line] given its unmodified [value].
diff --git a/ui/ui-core/src/test/java/androidx/ui/MathHelpersTest.kt b/ui/ui-core/src/test/java/androidx/ui/MathHelpersTest.kt
new file mode 100644
index 0000000..598938d
--- /dev/null
+++ b/ui/ui-core/src/test/java/androidx/ui/MathHelpersTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class MathHelpersTest {
+
+ // `f = 16777216f` is the first value where `f + 1 == f` due to float imprecision, so that's
+ // where testing floating point errors becomes interesting
+ val testStart = 16777216L
+ val testEnd = testStart + 1000
+
+ @Test
+ fun testLerpLargeFloats() {
+ val from = 1f
+ for (x in testStart until testEnd) {
+ val to = x.toFloat()
+ assertThat(lerp(from, to, 0f)).isEqualTo(from)
+ assertThat(lerp(from, to, 1f)).isEqualTo(to)
+ }
+ }
+
+ @Test
+ fun testLerpLargeInts() {
+ val from = 1
+ for (x in testStart until testEnd) {
+ val to = x.toInt()
+ assertThat(lerp(from, to, 0f)).isEqualTo(from)
+ assertThat(lerp(from, to, 1f)).isEqualTo(to)
+ }
+ }
+
+ @Test
+ fun testLerpLargeLongs() {
+ val from = 1L
+ for (x in testStart until testEnd) {
+ val to = x.toLong()
+ assertThat(lerp(from, to, 0f)).isEqualTo(from)
+ assertThat(lerp(from, to, 1f)).isEqualTo(to)
+ }
+ }
+
+ @Test
+ fun testLerpSimpleFloats() {
+ val from = 0f
+ for (multiplier in 1..1000) {
+ val to = (4 * multiplier).toFloat()
+ assertThat(lerp(from, to, 0.00f)).isEqualTo((0 * multiplier).toFloat())
+ assertThat(lerp(from, to, 0.25f)).isEqualTo((1 * multiplier).toFloat())
+ assertThat(lerp(from, to, 0.50f)).isEqualTo((2 * multiplier).toFloat())
+ assertThat(lerp(from, to, 0.75f)).isEqualTo((3 * multiplier).toFloat())
+ assertThat(lerp(from, to, 1.00f)).isEqualTo((4 * multiplier).toFloat())
+ }
+ }
+
+ @Test
+ fun testLerpSimpleInts() {
+ val from = 0
+ for (multiplier in 1..1000) {
+ val to = (4 * multiplier).toInt()
+ assertThat(lerp(from, to, 0.00f)).isEqualTo((0 * multiplier).toInt())
+ assertThat(lerp(from, to, 0.25f)).isEqualTo((1 * multiplier).toInt())
+ assertThat(lerp(from, to, 0.50f)).isEqualTo((2 * multiplier).toInt())
+ assertThat(lerp(from, to, 0.75f)).isEqualTo((3 * multiplier).toInt())
+ assertThat(lerp(from, to, 1.00f)).isEqualTo((4 * multiplier).toInt())
+ }
+ }
+
+ @Test
+ fun testLerpSimpleLongs() {
+ val from = 0L
+ for (multiplier in 1..1000) {
+ val to = (4 * multiplier).toLong()
+ assertThat(lerp(from, to, 0.00f)).isEqualTo((0 * multiplier).toLong())
+ assertThat(lerp(from, to, 0.25f)).isEqualTo((1 * multiplier).toLong())
+ assertThat(lerp(from, to, 0.50f)).isEqualTo((2 * multiplier).toLong())
+ assertThat(lerp(from, to, 0.75f)).isEqualTo((3 * multiplier).toLong())
+ assertThat(lerp(from, to, 1.00f)).isEqualTo((4 * multiplier).toLong())
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ScrollerTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ScrollerTest.kt
index 7f90d37..50e6c3a 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ScrollerTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ScrollerTest.kt
@@ -16,24 +16,33 @@
package androidx.ui.foundation
import android.graphics.Bitmap
-import android.os.Build
import android.os.Handler
+import android.os.Looper
import android.view.PixelCopy
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
+import androidx.annotation.RequiresApi
import androidx.compose.Composable
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.ui.core.Alignment
import androidx.ui.core.AndroidComposeView
+import androidx.ui.core.Dp
import androidx.ui.core.Draw
import androidx.ui.core.IntPx
+import androidx.ui.core.Px
+import androidx.ui.core.TestTag
+import androidx.ui.core.Text
+import androidx.ui.core.dp
import androidx.ui.core.ipx
import androidx.ui.core.px
import androidx.ui.core.setContent
+import androidx.ui.core.toPx
import androidx.ui.core.toRect
import androidx.ui.core.withDensity
+import androidx.ui.foundation.shape.DrawShape
+import androidx.ui.foundation.shape.RectangleShape
import androidx.ui.graphics.Color
import androidx.ui.graphics.Paint
import androidx.ui.graphics.PaintingStyle
@@ -43,18 +52,23 @@
import androidx.ui.layout.ConstrainedBox
import androidx.ui.layout.Container
import androidx.ui.layout.DpConstraints
-import androidx.ui.core.Text
-import androidx.ui.core.dp
-import androidx.ui.core.sp
-import androidx.ui.layout.Padding
import androidx.ui.layout.Row
+import androidx.ui.semantics.Semantics
+import androidx.ui.test.GestureScope
+import androidx.ui.test.SemanticsNodeInteraction
import androidx.ui.test.android.AndroidComposeTestRule
import androidx.ui.test.assertIsDisplayed
import androidx.ui.test.assertIsNotDisplayed
import androidx.ui.test.createComposeRule
+import androidx.ui.test.doGesture
import androidx.ui.test.doScrollTo
+import androidx.ui.test.findByTag
import androidx.ui.test.findByText
-import androidx.ui.text.TextStyle
+import androidx.ui.test.sendSwipeDown
+import androidx.ui.test.sendSwipeLeft
+import androidx.ui.test.sendSwipeRight
+import androidx.ui.test.sendSwipeUp
+import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
@@ -74,10 +88,14 @@
// TODO(malkov/pavlis) : some tests here require activity access as we need
// to take screen's bitmap, abstract it better
- val activity
+ private val activity
get() = (composeTestRule as AndroidComposeTestRule).activityTestRule.activity
- val colors = listOf(
+ private val defaultCrossAxisSize = 45.ipx
+ private val defaultMainAxisSize = 40.ipx
+ private val defaultCellSize = 5.ipx
+
+ private val colors = listOf(
Color(red = 0xFF, green = 0, blue = 0, alpha = 0xFF),
Color(red = 0xFF, green = 0xA5, blue = 0, alpha = 0xFF),
Color(red = 0xFF, green = 0xFF, blue = 0, alpha = 0xFF),
@@ -88,8 +106,8 @@
Color(red = 0xA5, green = 0, blue = 0xFF, alpha = 0xFF)
)
- var drawLatch = CountDownLatch(1)
- lateinit var handler: Handler
+ private var drawLatch = CountDownLatch(1)
+ private lateinit var handler: Handler
@Before
fun setupDrawLatch() {
@@ -99,15 +117,16 @@
}
}
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @SdkSuppress(minSdkVersion = 26)
@Test
fun verticalScroller_SmallContent() {
- composeVerticalScroller()
+ val height = 40.ipx
- validateVerticalScroller(0, 40)
+ composeVerticalScroller(height = height)
+
+ validateVerticalScroller(height = height)
}
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
@Test
fun verticalScroller_SmallContent_Unscrollable() {
val scrollerPosition = ScrollerPosition()
@@ -115,9 +134,8 @@
// latch to wait for a new max to come on layout
val newMaxLatch = CountDownLatch(1)
- composeVerticalScroller(
- scrollerPosition
- )
+ composeVerticalScroller(scrollerPosition)
+
val onGlobalLayout = object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
newMaxLatch.countDown()
@@ -133,22 +151,26 @@
}
}
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @SdkSuppress(minSdkVersion = 26)
@Test
fun verticalScroller_LargeContent_NoScroll() {
- composeVerticalScroller(height = 30.ipx)
+ val height = 30.ipx
- validateVerticalScroller(0, 30)
+ composeVerticalScroller(height = height)
+
+ validateVerticalScroller(height = height)
}
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @SdkSuppress(minSdkVersion = 26)
@Test
fun verticalScroller_LargeContent_ScrollToEnd() {
val scrollerPosition = ScrollerPosition()
+ val height = 30.ipx
+ val scrollDistance = 10.ipx
- composeVerticalScroller(scrollerPosition, height = 30.ipx)
+ composeVerticalScroller(scrollerPosition, height = height)
- validateVerticalScroller(0, 30)
+ validateVerticalScroller(height = height)
// The 'draw' method will no longer be called because only the position
// changes during scrolling. Therefore, we should just wait until the draw stage
@@ -161,40 +183,47 @@
}
composeTestRule.runOnUiThread {
activity.window.decorView.viewTreeObserver.addOnDrawListener(onDrawListener)
- assertEquals(10.px, scrollerPosition.maxPosition)
- scrollerPosition.scrollTo(10.px)
+ assertEquals(scrollDistance.toPx(), scrollerPosition.maxPosition)
+ scrollerPosition.scrollTo(scrollDistance.toPx())
}
assertTrue(latch.await(1, TimeUnit.SECONDS))
composeTestRule.runOnUiThread {
activity.window.decorView.viewTreeObserver.removeOnDrawListener(onDrawListener)
}
- validateVerticalScroller(10, 30)
+ validateVerticalScroller(offset = scrollDistance, height = height)
}
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @SdkSuppress(minSdkVersion = 26)
@Test
fun horizontalScroller_SmallContent() {
- composeHorizontalScroller()
+ val width = 40.ipx
- validateHorizontalScroller(0, 40)
+ composeHorizontalScroller(width = width)
+
+ validateHorizontalScroller(width = width)
}
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @SdkSuppress(minSdkVersion = 26)
@Test
fun horizontalScroller_LargeContent_NoScroll() {
- composeHorizontalScroller(width = 30.ipx)
+ val width = 30.ipx
- validateHorizontalScroller(0, 30)
+ composeHorizontalScroller(width = width)
+
+ validateHorizontalScroller(width = width)
}
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @SdkSuppress(minSdkVersion = 26)
@Test
fun horizontalScroller_LargeContent_ScrollToEnd() {
+ val width = 30.ipx
+ val scrollDistance = 10.ipx
+
val scrollerPosition = ScrollerPosition()
- composeHorizontalScroller(scrollerPosition, width = 30.ipx)
+ composeHorizontalScroller(scrollerPosition, width = width)
- validateHorizontalScroller(0, 30)
+ validateHorizontalScroller(width = width)
// The 'draw' method will no longer be called because only the position
// changes during scrolling. Therefore, we should just wait until the draw stage
@@ -207,14 +236,14 @@
}
composeTestRule.runOnUiThread {
activity.window.decorView.viewTreeObserver.addOnDrawListener(onDrawListener)
- assertEquals(10.px, scrollerPosition.maxPosition)
- scrollerPosition.scrollTo(10.px)
+ assertEquals(scrollDistance.toPx(), scrollerPosition.maxPosition)
+ scrollerPosition.scrollTo(scrollDistance.toPx())
}
assertTrue(latch.await(1, TimeUnit.SECONDS))
composeTestRule.runOnUiThread {
activity.window.decorView.viewTreeObserver.removeOnDrawListener(onDrawListener)
}
- validateHorizontalScroller(10, 30)
+ validateHorizontalScroller(offset = scrollDistance, width = width)
}
@Test
@@ -226,6 +255,7 @@
.doScrollTo()
.assertIsDisplayed()
}
+
@Test
fun horizontalScroller_scrollTo_scrollForward() {
createScrollableContent(isVertical = false)
@@ -250,6 +280,7 @@
.doScrollTo()
.assertIsDisplayed()
}
+
@Test
fun horizontalScroller_scrollTo_scrollBack() {
createScrollableContent(isVertical = false)
@@ -265,13 +296,60 @@
.assertIsDisplayed()
}
+ @Test
+ fun verticalScroller_swipeUp_swipeDown() {
+ swipeScrollerAndBack(true, GestureScope::sendSwipeUp, GestureScope::sendSwipeDown)
+ }
+
+ @Test
+ fun horizontalScroller_swipeLeft_swipeRight() {
+ swipeScrollerAndBack(false, GestureScope::sendSwipeLeft, GestureScope::sendSwipeRight)
+ }
+
+ private fun swipeScrollerAndBack(
+ isVertical: Boolean,
+ firstSwipe: GestureScope.() -> Unit,
+ secondSwipe: GestureScope.() -> Unit
+ ) {
+ val scrollerPosition = ScrollerPosition()
+
+ createScrollableContent(isVertical, scrollerPosition = scrollerPosition)
+ assertThat(scrollerPosition.getValueOnUiThread()).isEqualTo(0.px)
+
+ findByTag("scroller")
+ .doGesture { firstSwipe() }
+ .awaitScrollAnimation(scrollerPosition)
+
+ val scrolledValue = scrollerPosition.getValueOnUiThread()
+ assertThat(scrolledValue).isGreaterThan(0.px)
+
+ findByTag("scroller")
+ .doGesture { secondSwipe() }
+ .awaitScrollAnimation(scrollerPosition)
+
+ assertThat(scrollerPosition.getValueOnUiThread()).isLessThan(scrolledValue)
+ }
+
+ private fun ScrollerPosition.getValueOnUiThread(): Px {
+ var value = 0.px
+ val latch = CountDownLatch(1)
+ composeTestRule.runOnUiThread {
+ value = this.value
+ latch.countDown()
+ }
+ latch.await()
+ return value
+ }
+
private fun composeVerticalScroller(
scrollerPosition: ScrollerPosition = ScrollerPosition(),
- height: IntPx = 40.ipx
+ width: IntPx = defaultCrossAxisSize,
+ height: IntPx = defaultMainAxisSize,
+ rowHeight: IntPx = defaultCellSize
) {
// We assume that the height of the device is more than 45 px
withDensity(composeTestRule.density) {
- val constraints = DpConstraints.tightConstraints(45.px.toDp(), height.toDp())
+ val constraints = DpConstraints.tightConstraints(width.toDp(), height.toDp())
composeTestRule.runOnUiThread {
activity.setContent {
Align(alignment = Alignment.TopLeft) {
@@ -280,8 +358,8 @@
Column {
colors.forEach { color ->
Container(
- height = 5.px.toDp(),
- width = 45.px.toDp()
+ height = rowHeight.toDp(),
+ width = width.toDp()
) {
Draw { canvas, parentSize ->
val paint = Paint()
@@ -305,11 +383,13 @@
private fun composeHorizontalScroller(
scrollerPosition: ScrollerPosition = ScrollerPosition(),
- width: IntPx = 40.ipx
+ width: IntPx = defaultMainAxisSize,
+ height: IntPx = defaultCrossAxisSize,
+ columnWidth: IntPx = defaultCellSize
) {
// We assume that the height of the device is more than 45 px
withDensity(composeTestRule.density) {
- val constraints = DpConstraints.tightConstraints(width.toDp(), 45.px.toDp())
+ val constraints = DpConstraints.tightConstraints(width.toDp(), height.toDp())
composeTestRule.runOnUiThread {
activity.setContent {
Align(alignment = Alignment.TopLeft) {
@@ -318,8 +398,8 @@
Row {
colors.forEach { color ->
Container(
- width = 5.px.toDp(),
- height = 45.px.toDp()
+ width = columnWidth.toDp(),
+ height = height.toDp()
) {
Draw { canvas, parentSize ->
val paint = Paint()
@@ -341,21 +421,23 @@
}
}
+ @RequiresApi(api = 26)
private fun validateVerticalScroller(
- offset: Int,
- height: Int,
- width: Int = 45
+ offset: IntPx = 0.ipx,
+ width: IntPx = 45.ipx,
+ height: IntPx = 40.ipx,
+ rowHeight: IntPx = 5.ipx
) {
assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
val bitmap = waitAndScreenShot()
- assertTrue(bitmap.height >= height)
- assertTrue(bitmap.width >= 45)
- for (y in 0 until height) {
- val colorIndex = (offset + y) / 5
+ assertTrue(bitmap.height >= height.value)
+ assertTrue(bitmap.width >= width.value)
+ for (y in 0 until height.value) {
+ val colorIndex = (offset.value + y) / rowHeight.value
val expectedColor = colors[colorIndex]
- for (x in 0 until width) {
+ for (x in 0 until width.value) {
val pixel = bitmap.getPixel(x, y)
assertEquals(
"Expected $expectedColor, but got ${Color(pixel)} at $x, $y",
@@ -365,21 +447,23 @@
}
}
+ @RequiresApi(api = 26)
private fun validateHorizontalScroller(
- offset: Int,
- width: Int,
- height: Int = 45
+ offset: IntPx = 0.ipx,
+ width: IntPx = 40.ipx,
+ height: IntPx = 45.ipx,
+ columnWidth: IntPx = 5.ipx
) {
assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
val bitmap = waitAndScreenShot()
- assertTrue(bitmap.height >= 45)
- assertTrue(bitmap.width >= width)
- for (x in 0 until width) {
- val colorIndex = (offset + x) / 5
+ assertTrue(bitmap.height >= height.value)
+ assertTrue(bitmap.width >= width.value)
+ for (x in 0 until width.value) {
+ val colorIndex = (offset.value + x) / columnWidth.value
val expectedColor = colors[colorIndex]
- for (y in 0 until height) {
+ for (y in 0 until height.value) {
val pixel = bitmap.getPixel(x, y)
assertEquals(
"Expected $expectedColor, but got ${Color(pixel)} at $x, $y",
@@ -389,25 +473,37 @@
}
}
- private fun createScrollableContent(isVertical: Boolean) {
+ private fun createScrollableContent(
+ isVertical: Boolean,
+ itemCount: Int = 100,
+ width: Dp = 100.dp,
+ height: Dp = 100.dp,
+ scrollerPosition: ScrollerPosition = ScrollerPosition()
+ ) {
composeTestRule.setContent {
- val style = TextStyle(fontSize = 30.sp)
val content = @Composable {
- for (i in 1..100) {
- Text(text = i.toString(), style = style)
+ repeat(itemCount) {
+ Text(text = "$it")
}
}
- Padding(padding = 10.dp) {
- if (isVertical) {
- VerticalScroller {
- Column {
- content()
- }
- }
- } else {
- HorizontalScroller {
- Row {
- content()
+ Align(alignment = Alignment.TopLeft) {
+ Container(width = width, height = height) {
+ DrawShape(RectangleShape, Color.White)
+ TestTag("scroller") {
+ Semantics {
+ if (isVertical) {
+ VerticalScroller(scrollerPosition) {
+ Column {
+ content()
+ }
+ }
+ } else {
+ HorizontalScroller(scrollerPosition) {
+ Row {
+ content()
+ }
+ }
+ }
}
}
}
@@ -415,6 +511,7 @@
}
}
+ @RequiresApi(api = 26) // For PixelCopy.request(Window, Rect, Bitmap, listener, Handler)
private fun waitAndScreenShot(): Bitmap {
val view = findAndroidComposeView()
waitForDraw(view)
@@ -441,14 +538,35 @@
return dest
}
+ private fun SemanticsNodeInteraction.awaitScrollAnimation(
+ scroller: ScrollerPosition
+ ): SemanticsNodeInteraction {
+ if (!scroller.holder.animatedFloat.isRunning) {
+ return this
+ }
+ val latch = CountDownLatch(1)
+ val handler = Handler(Looper.getMainLooper())
+ handler.post(object : Runnable {
+ override fun run() {
+ if (scroller.holder.animatedFloat.isRunning) {
+ handler.post(this)
+ } else {
+ latch.countDown()
+ }
+ }
+ })
+ latch.await()
+ return this
+ }
+
// TODO(malkov): ALL below is copypaste from LayoutTest as this test in ui-foundation now
- internal fun findAndroidComposeView(): AndroidComposeView {
+ private fun findAndroidComposeView(): AndroidComposeView {
val contentViewGroup = activity.findViewById<ViewGroup>(android.R.id.content)
return findAndroidComposeView(contentViewGroup)!!
}
- internal fun findAndroidComposeView(parent: ViewGroup): AndroidComposeView? {
+ private fun findAndroidComposeView(parent: ViewGroup): AndroidComposeView? {
for (index in 0 until parent.childCount) {
val child = parent.getChildAt(index)
if (child is AndroidComposeView) {
@@ -463,7 +581,7 @@
return null
}
- internal fun waitForDraw(view: View) {
+ private fun waitForDraw(view: View) {
val viewDrawLatch = CountDownLatch(1)
val listener = object : ViewTreeObserver.OnDrawListener {
override fun onDraw() {
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
index 7881172..5bb083e 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
@@ -53,7 +53,7 @@
@Model
class ScrollerPosition(initial: Float = 0f) {
- internal val holder = AnimatedValueHolder(initial)
+ internal val holder = AnimatedValueHolder(-initial)
/**
* maxPosition this scroller that consume this ScrollerPosition can reach, or [Px.Infinity]
diff --git a/ui/ui-framework/api/0.1.0-dev03.txt b/ui/ui-framework/api/0.1.0-dev03.txt
index 360ed8b..cfcb917 100644
--- a/ui/ui-framework/api/0.1.0-dev03.txt
+++ b/ui/ui-framework/api/0.1.0-dev03.txt
@@ -39,7 +39,7 @@
method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function3<? super androidx.ui.core.MeasureScope,? super androidx.ui.core.MultiComposableMeasurables,? super androidx.ui.core.Constraints,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
}
public final class MultiComposableMeasurables implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.ui.core.Measurable> {
diff --git a/ui/ui-framework/api/current.txt b/ui/ui-framework/api/current.txt
index 360ed8b..cfcb917 100644
--- a/ui/ui-framework/api/current.txt
+++ b/ui/ui-framework/api/current.txt
@@ -39,7 +39,7 @@
method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function3<? super androidx.ui.core.MeasureScope,? super androidx.ui.core.MultiComposableMeasurables,? super androidx.ui.core.Constraints,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
}
public final class MultiComposableMeasurables implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.ui.core.Measurable> {
diff --git a/ui/ui-framework/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-framework/api/public_plus_experimental_0.1.0-dev03.txt
index 360ed8b..cfcb917 100644
--- a/ui/ui-framework/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-framework/api/public_plus_experimental_0.1.0-dev03.txt
@@ -39,7 +39,7 @@
method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function3<? super androidx.ui.core.MeasureScope,? super androidx.ui.core.MultiComposableMeasurables,? super androidx.ui.core.Constraints,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
}
public final class MultiComposableMeasurables implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.ui.core.Measurable> {
diff --git a/ui/ui-framework/api/public_plus_experimental_current.txt b/ui/ui-framework/api/public_plus_experimental_current.txt
index 360ed8b..cfcb917 100644
--- a/ui/ui-framework/api/public_plus_experimental_current.txt
+++ b/ui/ui-framework/api/public_plus_experimental_current.txt
@@ -39,7 +39,7 @@
method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function3<? super androidx.ui.core.MeasureScope,? super androidx.ui.core.MultiComposableMeasurables,? super androidx.ui.core.Constraints,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
}
public final class MultiComposableMeasurables implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.ui.core.Measurable> {
diff --git a/ui/ui-framework/api/restricted_0.1.0-dev03.txt b/ui/ui-framework/api/restricted_0.1.0-dev03.txt
index 360ed8b..cfcb917 100644
--- a/ui/ui-framework/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-framework/api/restricted_0.1.0-dev03.txt
@@ -39,7 +39,7 @@
method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function3<? super androidx.ui.core.MeasureScope,? super androidx.ui.core.MultiComposableMeasurables,? super androidx.ui.core.Constraints,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
}
public final class MultiComposableMeasurables implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.ui.core.Measurable> {
diff --git a/ui/ui-framework/api/restricted_current.txt b/ui/ui-framework/api/restricted_current.txt
index 360ed8b..cfcb917 100644
--- a/ui/ui-framework/api/restricted_current.txt
+++ b/ui/ui-framework/api/restricted_current.txt
@@ -39,7 +39,7 @@
method public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit>![] childrenArray, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function3<? super androidx.ui.core.MeasureScope,? super androidx.ui.core.MultiComposableMeasurables,? super androidx.ui.core.Constraints,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
}
public final class MultiComposableMeasurables implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.ui.core.Measurable> {
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeEditorModelTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeEditorModelTest.kt
index 98e68f7..58aec5d 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeEditorModelTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeEditorModelTest.kt
@@ -29,8 +29,9 @@
import androidx.ui.input.SetSelectionEditOp
import androidx.ui.input.TextInputService
import androidx.ui.test.createComposeRule
-import androidx.ui.test.doClick
+import androidx.ui.test.doGesture
import androidx.ui.test.findByTag
+import androidx.ui.test.sendClick
import androidx.ui.test.waitForIdleCompose
import androidx.ui.text.TextRange
import com.google.common.truth.Truth.assertThat
@@ -90,7 +91,7 @@
// Perform click to focus in.
val element = findByTag("textField")
- element.doClick()
+ element.doGesture { sendClick(1f, 1f) }
// Verify startInput is called and capture the callback.
val onEditCommandCaptor = argumentCaptor<(List<EditOperation>) -> Unit>()
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeFullEditorModelTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeFullEditorModelTest.kt
index c376455..bc9bb2f 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeFullEditorModelTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeFullEditorModelTest.kt
@@ -29,8 +29,9 @@
import androidx.ui.input.SetSelectionEditOp
import androidx.ui.input.TextInputService
import androidx.ui.test.createComposeRule
-import androidx.ui.test.doClick
+import androidx.ui.test.doGesture
import androidx.ui.test.findByTag
+import androidx.ui.test.sendClick
import androidx.ui.test.waitForIdleCompose
import androidx.ui.text.TextRange
import com.google.common.truth.Truth.assertThat
@@ -92,7 +93,7 @@
// Perform click to focus in.
val element = findByTag("textField")
- element.doClick()
+ element.doGesture { sendClick(1f, 1f) }
// Verify startInput is called and capture the callback.
val onEditCommandCaptor = argumentCaptor<(List<EditOperation>) -> Unit>()
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeStringTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeStringTest.kt
index 023c015..13e37b5 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeStringTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/TextFieldOnValueChangeStringTest.kt
@@ -29,8 +29,9 @@
import androidx.ui.input.SetSelectionEditOp
import androidx.ui.input.TextInputService
import androidx.ui.test.createComposeRule
-import androidx.ui.test.doClick
+import androidx.ui.test.doGesture
import androidx.ui.test.findByTag
+import androidx.ui.test.sendClick
import androidx.ui.test.waitForIdleCompose
import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.any
@@ -90,7 +91,7 @@
// Perform click to focus in.
val element = findByTag("textField")
- element.doClick()
+ element.doGesture { sendClick(1f, 1f) }
// Verify startInput is called and capture the callback.
val onEditCommandCaptor = argumentCaptor<(List<EditOperation>) -> Unit>()
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
index edd2878..e6e01f6 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
@@ -33,7 +33,6 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
-import androidx.ui.core.AlignmentLine
import androidx.ui.core.AndroidComposeView
import androidx.ui.core.Constraints
import androidx.ui.core.ContextAmbient
@@ -2181,15 +2180,9 @@
)
override fun DensityScope.modifyPosition(
- childPosition: IntPxPosition,
childSize: IntPxSize,
containerSize: IntPxSize
- ) = IntPxPosition(left + childPosition.x, top + childPosition.y)
-
- override fun DensityScope.modifyAlignmentLine(line: AlignmentLine, value: IntPx?): IntPx? {
- if (value == null) return null
- return if (line.horizontal) value + left else value + top
- }
+ ) = IntPxPosition(left, top)
}
@Model
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
index 4ecfe0e..09558d0 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
@@ -434,9 +434,12 @@
* children. If the composition yields multiple layout children, these will be all placed at the
* top left of the WithConstraints, so consider wrapping them in an additional common
* parent if different positioning is preferred.
+ *
+ * @param modifier Modifier to be applied to the introduced layout.
*/
@Composable
fun WithConstraints(
+ modifier: Modifier = Modifier.None,
children: @Composable() (Constraints) -> Unit
) {
val state = +memo { WithConstrainsState() }
@@ -446,7 +449,7 @@
// if this code was executed subcomposition must be triggered as well
state.forceRecompose = true
- LayoutNode(ref = state.nodeRef, measureBlocks = state.measureBlocks)
+ LayoutNode(modifier = modifier, ref = state.nodeRef, measureBlocks = state.measureBlocks)
// if LayoutNode scheduled the remeasuring no further steps are needed - subcomposition
// will happen later on the measuring stage. otherwise we can assume the LayoutNode
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
index fafc275..95bccc2 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
@@ -40,7 +40,6 @@
import androidx.compose.unaryPlus
import androidx.ui.autofill.Autofill
import androidx.ui.autofill.AutofillTree
-import androidx.ui.core.selection.SelectionContainer
import androidx.ui.text.font.Font
import kotlinx.coroutines.Dispatchers
import kotlin.coroutines.CoroutineContext
@@ -115,22 +114,11 @@
// kotlinx.coroutines.Dispatchers' not instance of 'Precise Reference: androidx.compose.Ambient'.
val coroutineContext = Dispatchers.Main
return Compose.composeInto(composeView.root, this) {
- WrapWithAmbients(composeView, this, coroutineContext) {
- WrapWithSelectionContainer(content)
- }
+ WrapWithAmbients(composeView, this, coroutineContext, content)
}
}
/**
- * We want text/image selection to be enabled by default and disabled per widget. Therefore a root
- * level [SelectionContainer] is installed at the root.
- */
-@Composable
-private fun WrapWithSelectionContainer(content: @Composable() () -> Unit) {
- SelectionContainer(children = content)
-}
-
-/**
* Composes the given composable into the given view.
*
* @param content Composable that will be the content of the view.
@@ -146,9 +134,7 @@
// kotlinx.coroutines.Dispatchers' not instance of 'Precise Reference: androidx.compose.Ambient'.
val coroutineContext = Dispatchers.Main
return Compose.composeInto(composeView.root, context) {
- WrapWithAmbients(composeView, context, coroutineContext) {
- WrapWithSelectionContainer(content)
- }
+ WrapWithAmbients(composeView, context, coroutineContext, content)
}
}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
index acdda9e2..445c88f 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
@@ -32,7 +32,7 @@
import androidx.ui.core.Popup
import androidx.ui.core.enforce
import androidx.ui.core.gesture.LongPressDragGestureDetector
-import androidx.ui.core.gesture.PressGestureDetector
+import androidx.ui.core.gesture.PressReleasedGestureDetector
import androidx.ui.core.gesture.TouchSlopDragGestureDetector
import androidx.ui.core.hasTightHeight
import androidx.ui.core.hasTightWidth
@@ -81,7 +81,7 @@
// Get the layout coordinates of the selection container. This is for hit test of
// cross-composable selection.
OnPositioned(onPositioned = { manager.containerLayoutCoordinates = it })
- PressGestureDetector(onRelease = { manager.onRelease() }) {
+ PressReleasedGestureDetector(onRelease = { manager.onRelease() }) {
LongPressDragGestureDetector(manager.longPressDragObserver, children = children)
}
addHandles(
diff --git a/ui/ui-layout/api/0.1.0-dev03.txt b/ui/ui-layout/api/0.1.0-dev03.txt
index 37f5b57..a9abbf5 100644
--- a/ui/ui-layout/api/0.1.0-dev03.txt
+++ b/ui/ui-layout/api/0.1.0-dev03.txt
@@ -7,6 +7,40 @@
method public static void Center(kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public final class Aligned {
+ method public androidx.ui.core.LayoutModifier getBottom();
+ method public androidx.ui.core.LayoutModifier getBottomCenter();
+ method public androidx.ui.core.LayoutModifier getBottomLeft();
+ method public androidx.ui.core.LayoutModifier getBottomRight();
+ method public androidx.ui.core.LayoutModifier getCenter();
+ method public androidx.ui.core.LayoutModifier getCenterHorizontally();
+ method public androidx.ui.core.LayoutModifier getCenterLeft();
+ method public androidx.ui.core.LayoutModifier getCenterRight();
+ method public androidx.ui.core.LayoutModifier getCenterVertically();
+ method public androidx.ui.core.LayoutModifier getEnd();
+ method public androidx.ui.core.LayoutModifier getStart();
+ method public androidx.ui.core.LayoutModifier getTop();
+ method public androidx.ui.core.LayoutModifier getTopCenter();
+ method public androidx.ui.core.LayoutModifier getTopLeft();
+ method public androidx.ui.core.LayoutModifier getTopRight();
+ property public final androidx.ui.core.LayoutModifier Bottom;
+ property public final androidx.ui.core.LayoutModifier BottomCenter;
+ property public final androidx.ui.core.LayoutModifier BottomLeft;
+ property public final androidx.ui.core.LayoutModifier BottomRight;
+ property public final androidx.ui.core.LayoutModifier Center;
+ property public final androidx.ui.core.LayoutModifier CenterHorizontally;
+ property public final androidx.ui.core.LayoutModifier CenterLeft;
+ property public final androidx.ui.core.LayoutModifier CenterRight;
+ property public final androidx.ui.core.LayoutModifier CenterVertically;
+ property public final androidx.ui.core.LayoutModifier End;
+ property public final androidx.ui.core.LayoutModifier Start;
+ property public final androidx.ui.core.LayoutModifier Top;
+ property public final androidx.ui.core.LayoutModifier TopCenter;
+ property public final androidx.ui.core.LayoutModifier TopLeft;
+ property public final androidx.ui.core.LayoutModifier TopRight;
+ field public static final androidx.ui.layout.Aligned! INSTANCE;
+ }
+
public final class AlignmentLineKt {
ctor public AlignmentLineKt();
method public static void AlignmentLineOffset(androidx.ui.core.AlignmentLine alignmentLine, androidx.ui.core.Dp before = 0.dp, androidx.ui.core.Dp after = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -357,3 +391,169 @@
}
+package androidx.ui.layout.constraintlayout {
+
+ public final class ConstraintLayoutKt {
+ ctor public ConstraintLayoutKt();
+ method public static void ConstraintLayout(androidx.ui.layout.constraintlayout.ConstraintSet constraintSet, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.LayoutModifier Tag(Object tag);
+ method public static Object! getTag(androidx.ui.core.Measurable);
+ }
+
+ public final class ConstraintSet {
+ ctor public ConstraintSet(internal kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ method public androidx.ui.layout.constraintlayout.ConstraintSet copy(kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ }
+
+ public final class ConstraintSetBuilderScope {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createBottomBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalChain createHorizontalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createLeftBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createRightBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createTopBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalChain createVerticalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference getParent();
+ method public Object! getParentDimension();
+ method public Object! getSpreadDimension();
+ method public Object! getWrapDimension();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference tag(Object tag);
+ property public final Object! ParentDimension;
+ property public final Object! SpreadDimension;
+ property public final Object! WrapDimension;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference parent;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle {
+ field public static final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle.Companion! Companion;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle.Companion {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed(float bias);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getPacked();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpread();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpreadInside();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Spread;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle SpreadInside;
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor other);
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutReference {
+ method public void center();
+ method public void centerHorizontally();
+ method public void centerVertically();
+ method public infix void constrainHorizontallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainVerticallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor getBaseline();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public float getHorizontalBias();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ method public float getVerticalBias();
+ method public void setBaseline(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor p);
+ method public void setBottom(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor p);
+ method public void setHorizontalBias(float value);
+ method public void setRight(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor p);
+ method public void setVerticalBias(float value);
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor baseline;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final float horizontalBias;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ property public final float verticalBias;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.HorizontalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.VerticalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ }
+
+}
+
diff --git a/ui/ui-layout/api/api_lint.ignore b/ui/ui-layout/api/api_lint.ignore
index f4de926..2295821 100644
--- a/ui/ui-layout/api/api_lint.ignore
+++ b/ui/ui-layout/api/api_lint.ignore
@@ -1,5 +1,21 @@
// Baseline format: 1.0
+ArrayReturn: androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope#createHorizontalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference[], androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle) parameter #0:
+ Method parameter should be Collection<ConstrainedLayoutReference> (or subclass) instead of raw array; was `androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference[]`
+ArrayReturn: androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope#createVerticalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference[], androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle) parameter #0:
+ Method parameter should be Collection<ConstrainedLayoutReference> (or subclass) instead of raw array; was `androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference[]`
+
+
DocumentExceptions: androidx.ui.layout.FlexChildren#expanded(float, kotlin.jvm.functions.Function0<kotlin.Unit>):
Method FlexChildren.expanded appears to be throwing java.lang.IllegalArgumentException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
DocumentExceptions: androidx.ui.layout.FlexChildren#flexible(float, kotlin.jvm.functions.Function0<kotlin.Unit>):
Method FlexChildren.flexible appears to be throwing java.lang.IllegalArgumentException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
+
+
+MissingNullability: androidx.ui.layout.constraintlayout.ConstraintLayoutKt#getTag(androidx.ui.core.Measurable):
+ Missing nullability on method `getTag` return
+MissingNullability: androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope#getParentDimension():
+ Missing nullability on method `getParentDimension` return
+MissingNullability: androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope#getSpreadDimension():
+ Missing nullability on method `getSpreadDimension` return
+MissingNullability: androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope#getWrapDimension():
+ Missing nullability on method `getWrapDimension` return
diff --git a/ui/ui-layout/api/current.txt b/ui/ui-layout/api/current.txt
index 37f5b57..a9abbf5 100644
--- a/ui/ui-layout/api/current.txt
+++ b/ui/ui-layout/api/current.txt
@@ -7,6 +7,40 @@
method public static void Center(kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public final class Aligned {
+ method public androidx.ui.core.LayoutModifier getBottom();
+ method public androidx.ui.core.LayoutModifier getBottomCenter();
+ method public androidx.ui.core.LayoutModifier getBottomLeft();
+ method public androidx.ui.core.LayoutModifier getBottomRight();
+ method public androidx.ui.core.LayoutModifier getCenter();
+ method public androidx.ui.core.LayoutModifier getCenterHorizontally();
+ method public androidx.ui.core.LayoutModifier getCenterLeft();
+ method public androidx.ui.core.LayoutModifier getCenterRight();
+ method public androidx.ui.core.LayoutModifier getCenterVertically();
+ method public androidx.ui.core.LayoutModifier getEnd();
+ method public androidx.ui.core.LayoutModifier getStart();
+ method public androidx.ui.core.LayoutModifier getTop();
+ method public androidx.ui.core.LayoutModifier getTopCenter();
+ method public androidx.ui.core.LayoutModifier getTopLeft();
+ method public androidx.ui.core.LayoutModifier getTopRight();
+ property public final androidx.ui.core.LayoutModifier Bottom;
+ property public final androidx.ui.core.LayoutModifier BottomCenter;
+ property public final androidx.ui.core.LayoutModifier BottomLeft;
+ property public final androidx.ui.core.LayoutModifier BottomRight;
+ property public final androidx.ui.core.LayoutModifier Center;
+ property public final androidx.ui.core.LayoutModifier CenterHorizontally;
+ property public final androidx.ui.core.LayoutModifier CenterLeft;
+ property public final androidx.ui.core.LayoutModifier CenterRight;
+ property public final androidx.ui.core.LayoutModifier CenterVertically;
+ property public final androidx.ui.core.LayoutModifier End;
+ property public final androidx.ui.core.LayoutModifier Start;
+ property public final androidx.ui.core.LayoutModifier Top;
+ property public final androidx.ui.core.LayoutModifier TopCenter;
+ property public final androidx.ui.core.LayoutModifier TopLeft;
+ property public final androidx.ui.core.LayoutModifier TopRight;
+ field public static final androidx.ui.layout.Aligned! INSTANCE;
+ }
+
public final class AlignmentLineKt {
ctor public AlignmentLineKt();
method public static void AlignmentLineOffset(androidx.ui.core.AlignmentLine alignmentLine, androidx.ui.core.Dp before = 0.dp, androidx.ui.core.Dp after = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -357,3 +391,169 @@
}
+package androidx.ui.layout.constraintlayout {
+
+ public final class ConstraintLayoutKt {
+ ctor public ConstraintLayoutKt();
+ method public static void ConstraintLayout(androidx.ui.layout.constraintlayout.ConstraintSet constraintSet, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.LayoutModifier Tag(Object tag);
+ method public static Object! getTag(androidx.ui.core.Measurable);
+ }
+
+ public final class ConstraintSet {
+ ctor public ConstraintSet(internal kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ method public androidx.ui.layout.constraintlayout.ConstraintSet copy(kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ }
+
+ public final class ConstraintSetBuilderScope {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createBottomBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalChain createHorizontalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createLeftBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createRightBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createTopBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalChain createVerticalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference getParent();
+ method public Object! getParentDimension();
+ method public Object! getSpreadDimension();
+ method public Object! getWrapDimension();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference tag(Object tag);
+ property public final Object! ParentDimension;
+ property public final Object! SpreadDimension;
+ property public final Object! WrapDimension;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference parent;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle {
+ field public static final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle.Companion! Companion;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle.Companion {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed(float bias);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getPacked();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpread();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpreadInside();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Spread;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle SpreadInside;
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor other);
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutReference {
+ method public void center();
+ method public void centerHorizontally();
+ method public void centerVertically();
+ method public infix void constrainHorizontallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainVerticallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor getBaseline();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public float getHorizontalBias();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ method public float getVerticalBias();
+ method public void setBaseline(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor p);
+ method public void setBottom(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor p);
+ method public void setHorizontalBias(float value);
+ method public void setRight(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor p);
+ method public void setVerticalBias(float value);
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor baseline;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final float horizontalBias;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ property public final float verticalBias;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.HorizontalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.VerticalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ }
+
+}
+
diff --git a/ui/ui-layout/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-layout/api/public_plus_experimental_0.1.0-dev03.txt
index 37f5b57..a9abbf5 100644
--- a/ui/ui-layout/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-layout/api/public_plus_experimental_0.1.0-dev03.txt
@@ -7,6 +7,40 @@
method public static void Center(kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public final class Aligned {
+ method public androidx.ui.core.LayoutModifier getBottom();
+ method public androidx.ui.core.LayoutModifier getBottomCenter();
+ method public androidx.ui.core.LayoutModifier getBottomLeft();
+ method public androidx.ui.core.LayoutModifier getBottomRight();
+ method public androidx.ui.core.LayoutModifier getCenter();
+ method public androidx.ui.core.LayoutModifier getCenterHorizontally();
+ method public androidx.ui.core.LayoutModifier getCenterLeft();
+ method public androidx.ui.core.LayoutModifier getCenterRight();
+ method public androidx.ui.core.LayoutModifier getCenterVertically();
+ method public androidx.ui.core.LayoutModifier getEnd();
+ method public androidx.ui.core.LayoutModifier getStart();
+ method public androidx.ui.core.LayoutModifier getTop();
+ method public androidx.ui.core.LayoutModifier getTopCenter();
+ method public androidx.ui.core.LayoutModifier getTopLeft();
+ method public androidx.ui.core.LayoutModifier getTopRight();
+ property public final androidx.ui.core.LayoutModifier Bottom;
+ property public final androidx.ui.core.LayoutModifier BottomCenter;
+ property public final androidx.ui.core.LayoutModifier BottomLeft;
+ property public final androidx.ui.core.LayoutModifier BottomRight;
+ property public final androidx.ui.core.LayoutModifier Center;
+ property public final androidx.ui.core.LayoutModifier CenterHorizontally;
+ property public final androidx.ui.core.LayoutModifier CenterLeft;
+ property public final androidx.ui.core.LayoutModifier CenterRight;
+ property public final androidx.ui.core.LayoutModifier CenterVertically;
+ property public final androidx.ui.core.LayoutModifier End;
+ property public final androidx.ui.core.LayoutModifier Start;
+ property public final androidx.ui.core.LayoutModifier Top;
+ property public final androidx.ui.core.LayoutModifier TopCenter;
+ property public final androidx.ui.core.LayoutModifier TopLeft;
+ property public final androidx.ui.core.LayoutModifier TopRight;
+ field public static final androidx.ui.layout.Aligned! INSTANCE;
+ }
+
public final class AlignmentLineKt {
ctor public AlignmentLineKt();
method public static void AlignmentLineOffset(androidx.ui.core.AlignmentLine alignmentLine, androidx.ui.core.Dp before = 0.dp, androidx.ui.core.Dp after = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -357,3 +391,169 @@
}
+package androidx.ui.layout.constraintlayout {
+
+ public final class ConstraintLayoutKt {
+ ctor public ConstraintLayoutKt();
+ method public static void ConstraintLayout(androidx.ui.layout.constraintlayout.ConstraintSet constraintSet, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.LayoutModifier Tag(Object tag);
+ method public static Object! getTag(androidx.ui.core.Measurable);
+ }
+
+ public final class ConstraintSet {
+ ctor public ConstraintSet(internal kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ method public androidx.ui.layout.constraintlayout.ConstraintSet copy(kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ }
+
+ public final class ConstraintSetBuilderScope {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createBottomBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalChain createHorizontalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createLeftBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createRightBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createTopBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalChain createVerticalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference getParent();
+ method public Object! getParentDimension();
+ method public Object! getSpreadDimension();
+ method public Object! getWrapDimension();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference tag(Object tag);
+ property public final Object! ParentDimension;
+ property public final Object! SpreadDimension;
+ property public final Object! WrapDimension;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference parent;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle {
+ field public static final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle.Companion! Companion;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle.Companion {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed(float bias);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getPacked();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpread();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpreadInside();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Spread;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle SpreadInside;
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor other);
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutReference {
+ method public void center();
+ method public void centerHorizontally();
+ method public void centerVertically();
+ method public infix void constrainHorizontallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainVerticallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor getBaseline();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public float getHorizontalBias();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ method public float getVerticalBias();
+ method public void setBaseline(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor p);
+ method public void setBottom(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor p);
+ method public void setHorizontalBias(float value);
+ method public void setRight(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor p);
+ method public void setVerticalBias(float value);
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor baseline;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final float horizontalBias;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ property public final float verticalBias;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.HorizontalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.VerticalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ }
+
+}
+
diff --git a/ui/ui-layout/api/public_plus_experimental_current.txt b/ui/ui-layout/api/public_plus_experimental_current.txt
index 37f5b57..a9abbf5 100644
--- a/ui/ui-layout/api/public_plus_experimental_current.txt
+++ b/ui/ui-layout/api/public_plus_experimental_current.txt
@@ -7,6 +7,40 @@
method public static void Center(kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public final class Aligned {
+ method public androidx.ui.core.LayoutModifier getBottom();
+ method public androidx.ui.core.LayoutModifier getBottomCenter();
+ method public androidx.ui.core.LayoutModifier getBottomLeft();
+ method public androidx.ui.core.LayoutModifier getBottomRight();
+ method public androidx.ui.core.LayoutModifier getCenter();
+ method public androidx.ui.core.LayoutModifier getCenterHorizontally();
+ method public androidx.ui.core.LayoutModifier getCenterLeft();
+ method public androidx.ui.core.LayoutModifier getCenterRight();
+ method public androidx.ui.core.LayoutModifier getCenterVertically();
+ method public androidx.ui.core.LayoutModifier getEnd();
+ method public androidx.ui.core.LayoutModifier getStart();
+ method public androidx.ui.core.LayoutModifier getTop();
+ method public androidx.ui.core.LayoutModifier getTopCenter();
+ method public androidx.ui.core.LayoutModifier getTopLeft();
+ method public androidx.ui.core.LayoutModifier getTopRight();
+ property public final androidx.ui.core.LayoutModifier Bottom;
+ property public final androidx.ui.core.LayoutModifier BottomCenter;
+ property public final androidx.ui.core.LayoutModifier BottomLeft;
+ property public final androidx.ui.core.LayoutModifier BottomRight;
+ property public final androidx.ui.core.LayoutModifier Center;
+ property public final androidx.ui.core.LayoutModifier CenterHorizontally;
+ property public final androidx.ui.core.LayoutModifier CenterLeft;
+ property public final androidx.ui.core.LayoutModifier CenterRight;
+ property public final androidx.ui.core.LayoutModifier CenterVertically;
+ property public final androidx.ui.core.LayoutModifier End;
+ property public final androidx.ui.core.LayoutModifier Start;
+ property public final androidx.ui.core.LayoutModifier Top;
+ property public final androidx.ui.core.LayoutModifier TopCenter;
+ property public final androidx.ui.core.LayoutModifier TopLeft;
+ property public final androidx.ui.core.LayoutModifier TopRight;
+ field public static final androidx.ui.layout.Aligned! INSTANCE;
+ }
+
public final class AlignmentLineKt {
ctor public AlignmentLineKt();
method public static void AlignmentLineOffset(androidx.ui.core.AlignmentLine alignmentLine, androidx.ui.core.Dp before = 0.dp, androidx.ui.core.Dp after = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -357,3 +391,169 @@
}
+package androidx.ui.layout.constraintlayout {
+
+ public final class ConstraintLayoutKt {
+ ctor public ConstraintLayoutKt();
+ method public static void ConstraintLayout(androidx.ui.layout.constraintlayout.ConstraintSet constraintSet, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.LayoutModifier Tag(Object tag);
+ method public static Object! getTag(androidx.ui.core.Measurable);
+ }
+
+ public final class ConstraintSet {
+ ctor public ConstraintSet(internal kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ method public androidx.ui.layout.constraintlayout.ConstraintSet copy(kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ }
+
+ public final class ConstraintSetBuilderScope {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createBottomBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalChain createHorizontalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createLeftBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createRightBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createTopBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalChain createVerticalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference getParent();
+ method public Object! getParentDimension();
+ method public Object! getSpreadDimension();
+ method public Object! getWrapDimension();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference tag(Object tag);
+ property public final Object! ParentDimension;
+ property public final Object! SpreadDimension;
+ property public final Object! WrapDimension;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference parent;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle {
+ field public static final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle.Companion! Companion;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle.Companion {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed(float bias);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getPacked();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpread();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpreadInside();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Spread;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle SpreadInside;
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor other);
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutReference {
+ method public void center();
+ method public void centerHorizontally();
+ method public void centerVertically();
+ method public infix void constrainHorizontallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainVerticallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor getBaseline();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public float getHorizontalBias();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ method public float getVerticalBias();
+ method public void setBaseline(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor p);
+ method public void setBottom(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor p);
+ method public void setHorizontalBias(float value);
+ method public void setRight(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor p);
+ method public void setVerticalBias(float value);
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor baseline;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final float horizontalBias;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ property public final float verticalBias;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.HorizontalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.VerticalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ }
+
+}
+
diff --git a/ui/ui-layout/api/restricted_0.1.0-dev03.txt b/ui/ui-layout/api/restricted_0.1.0-dev03.txt
index 37f5b57..a9abbf5 100644
--- a/ui/ui-layout/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-layout/api/restricted_0.1.0-dev03.txt
@@ -7,6 +7,40 @@
method public static void Center(kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public final class Aligned {
+ method public androidx.ui.core.LayoutModifier getBottom();
+ method public androidx.ui.core.LayoutModifier getBottomCenter();
+ method public androidx.ui.core.LayoutModifier getBottomLeft();
+ method public androidx.ui.core.LayoutModifier getBottomRight();
+ method public androidx.ui.core.LayoutModifier getCenter();
+ method public androidx.ui.core.LayoutModifier getCenterHorizontally();
+ method public androidx.ui.core.LayoutModifier getCenterLeft();
+ method public androidx.ui.core.LayoutModifier getCenterRight();
+ method public androidx.ui.core.LayoutModifier getCenterVertically();
+ method public androidx.ui.core.LayoutModifier getEnd();
+ method public androidx.ui.core.LayoutModifier getStart();
+ method public androidx.ui.core.LayoutModifier getTop();
+ method public androidx.ui.core.LayoutModifier getTopCenter();
+ method public androidx.ui.core.LayoutModifier getTopLeft();
+ method public androidx.ui.core.LayoutModifier getTopRight();
+ property public final androidx.ui.core.LayoutModifier Bottom;
+ property public final androidx.ui.core.LayoutModifier BottomCenter;
+ property public final androidx.ui.core.LayoutModifier BottomLeft;
+ property public final androidx.ui.core.LayoutModifier BottomRight;
+ property public final androidx.ui.core.LayoutModifier Center;
+ property public final androidx.ui.core.LayoutModifier CenterHorizontally;
+ property public final androidx.ui.core.LayoutModifier CenterLeft;
+ property public final androidx.ui.core.LayoutModifier CenterRight;
+ property public final androidx.ui.core.LayoutModifier CenterVertically;
+ property public final androidx.ui.core.LayoutModifier End;
+ property public final androidx.ui.core.LayoutModifier Start;
+ property public final androidx.ui.core.LayoutModifier Top;
+ property public final androidx.ui.core.LayoutModifier TopCenter;
+ property public final androidx.ui.core.LayoutModifier TopLeft;
+ property public final androidx.ui.core.LayoutModifier TopRight;
+ field public static final androidx.ui.layout.Aligned! INSTANCE;
+ }
+
public final class AlignmentLineKt {
ctor public AlignmentLineKt();
method public static void AlignmentLineOffset(androidx.ui.core.AlignmentLine alignmentLine, androidx.ui.core.Dp before = 0.dp, androidx.ui.core.Dp after = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -357,3 +391,169 @@
}
+package androidx.ui.layout.constraintlayout {
+
+ public final class ConstraintLayoutKt {
+ ctor public ConstraintLayoutKt();
+ method public static void ConstraintLayout(androidx.ui.layout.constraintlayout.ConstraintSet constraintSet, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.LayoutModifier Tag(Object tag);
+ method public static Object! getTag(androidx.ui.core.Measurable);
+ }
+
+ public final class ConstraintSet {
+ ctor public ConstraintSet(internal kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ method public androidx.ui.layout.constraintlayout.ConstraintSet copy(kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ }
+
+ public final class ConstraintSetBuilderScope {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createBottomBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalChain createHorizontalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createLeftBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createRightBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createTopBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalChain createVerticalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference getParent();
+ method public Object! getParentDimension();
+ method public Object! getSpreadDimension();
+ method public Object! getWrapDimension();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference tag(Object tag);
+ property public final Object! ParentDimension;
+ property public final Object! SpreadDimension;
+ property public final Object! WrapDimension;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference parent;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle {
+ field public static final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle.Companion! Companion;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle.Companion {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed(float bias);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getPacked();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpread();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpreadInside();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Spread;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle SpreadInside;
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor other);
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutReference {
+ method public void center();
+ method public void centerHorizontally();
+ method public void centerVertically();
+ method public infix void constrainHorizontallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainVerticallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor getBaseline();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public float getHorizontalBias();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ method public float getVerticalBias();
+ method public void setBaseline(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor p);
+ method public void setBottom(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor p);
+ method public void setHorizontalBias(float value);
+ method public void setRight(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor p);
+ method public void setVerticalBias(float value);
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor baseline;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final float horizontalBias;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ property public final float verticalBias;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.HorizontalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.VerticalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ }
+
+}
+
diff --git a/ui/ui-layout/api/restricted_current.txt b/ui/ui-layout/api/restricted_current.txt
index 37f5b57..a9abbf5 100644
--- a/ui/ui-layout/api/restricted_current.txt
+++ b/ui/ui-layout/api/restricted_current.txt
@@ -7,6 +7,40 @@
method public static void Center(kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public final class Aligned {
+ method public androidx.ui.core.LayoutModifier getBottom();
+ method public androidx.ui.core.LayoutModifier getBottomCenter();
+ method public androidx.ui.core.LayoutModifier getBottomLeft();
+ method public androidx.ui.core.LayoutModifier getBottomRight();
+ method public androidx.ui.core.LayoutModifier getCenter();
+ method public androidx.ui.core.LayoutModifier getCenterHorizontally();
+ method public androidx.ui.core.LayoutModifier getCenterLeft();
+ method public androidx.ui.core.LayoutModifier getCenterRight();
+ method public androidx.ui.core.LayoutModifier getCenterVertically();
+ method public androidx.ui.core.LayoutModifier getEnd();
+ method public androidx.ui.core.LayoutModifier getStart();
+ method public androidx.ui.core.LayoutModifier getTop();
+ method public androidx.ui.core.LayoutModifier getTopCenter();
+ method public androidx.ui.core.LayoutModifier getTopLeft();
+ method public androidx.ui.core.LayoutModifier getTopRight();
+ property public final androidx.ui.core.LayoutModifier Bottom;
+ property public final androidx.ui.core.LayoutModifier BottomCenter;
+ property public final androidx.ui.core.LayoutModifier BottomLeft;
+ property public final androidx.ui.core.LayoutModifier BottomRight;
+ property public final androidx.ui.core.LayoutModifier Center;
+ property public final androidx.ui.core.LayoutModifier CenterHorizontally;
+ property public final androidx.ui.core.LayoutModifier CenterLeft;
+ property public final androidx.ui.core.LayoutModifier CenterRight;
+ property public final androidx.ui.core.LayoutModifier CenterVertically;
+ property public final androidx.ui.core.LayoutModifier End;
+ property public final androidx.ui.core.LayoutModifier Start;
+ property public final androidx.ui.core.LayoutModifier Top;
+ property public final androidx.ui.core.LayoutModifier TopCenter;
+ property public final androidx.ui.core.LayoutModifier TopLeft;
+ property public final androidx.ui.core.LayoutModifier TopRight;
+ field public static final androidx.ui.layout.Aligned! INSTANCE;
+ }
+
public final class AlignmentLineKt {
ctor public AlignmentLineKt();
method public static void AlignmentLineOffset(androidx.ui.core.AlignmentLine alignmentLine, androidx.ui.core.Dp before = 0.dp, androidx.ui.core.Dp after = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
@@ -357,3 +391,169 @@
}
+package androidx.ui.layout.constraintlayout {
+
+ public final class ConstraintLayoutKt {
+ ctor public ConstraintLayoutKt();
+ method public static void ConstraintLayout(androidx.ui.layout.constraintlayout.ConstraintSet constraintSet, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.LayoutModifier Tag(Object tag);
+ method public static Object! getTag(androidx.ui.core.Measurable);
+ }
+
+ public final class ConstraintSet {
+ ctor public ConstraintSet(internal kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ method public androidx.ui.layout.constraintlayout.ConstraintSet copy(kotlin.jvm.functions.Function1<? super androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope,kotlin.Unit> description);
+ }
+
+ public final class ConstraintSetBuilderScope {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createBottomBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromBottom(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromLeft(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor createGuidelineFromRight(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(androidx.ui.core.Dp offset);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor createGuidelineFromTop(float percent);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalChain createHorizontalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createLeftBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor createRightBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor createTopBarrier(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference... elements);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalChain createVerticalChain(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference![] elements, androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle chainStyle = ChainStyle.Spread);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference getParent();
+ method public Object! getParentDimension();
+ method public Object! getSpreadDimension();
+ method public Object! getWrapDimension();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference tag(Object tag);
+ property public final Object! ParentDimension;
+ property public final Object! SpreadDimension;
+ property public final Object! WrapDimension;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference parent;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle {
+ field public static final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle.Companion! Companion;
+ }
+
+ public static final class ConstraintSetBuilderScope.ChainStyle.Companion {
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed(float bias);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getPacked();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpread();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle getSpreadInside();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Packed;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle Spread;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ChainStyle SpreadInside;
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor other);
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ }
+
+ public static final class ConstraintSetBuilderScope.ConstrainedLayoutReference {
+ method public void center();
+ method public void centerHorizontally();
+ method public void centerVertically();
+ method public infix void constrainHorizontallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public infix void constrainVerticallyTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor getBaseline();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public float getHorizontalBias();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ method public androidx.constraintlayout.solver.state.State getState();
+ method public Object getTag();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ method public float getVerticalBias();
+ method public void setBaseline(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor p);
+ method public void setBottom(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor p);
+ method public void setHorizontalBias(float value);
+ method public void setRight(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor p);
+ method public void setVerticalBias(float value);
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutBaselineAnchor baseline;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final float horizontalBias;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ property public final float verticalBias;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.HorizontalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.HorizontalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getLeft();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor getRight();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor left;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor right;
+ }
+
+ public abstract static sealed class ConstraintSetBuilderScope.VerticalAnchor {
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.BarrierAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.ConstrainedLayoutAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor other);
+ method public int getIndex$lintWithKotlin();
+ method public androidx.ui.core.Dp getMargin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ method public void setMargin(androidx.ui.core.Dp value);
+ property public final androidx.ui.core.Dp margin;
+ property public Object tag;
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalAnchor.GuidelineAnchor extends androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.VerticalAnchor {
+ method public int getIndex$lintWithKotlin();
+ method public androidx.constraintlayout.solver.state.State getState$lintWithKotlin();
+ method public Object getTag$lintWithKotlin();
+ }
+
+ public static final class ConstraintSetBuilderScope.VerticalChain {
+ method public infix void constrainTo(androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.ConstrainedLayoutReference other);
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getBottom();
+ method public androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor getTop();
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor bottom;
+ property public final androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope.HorizontalAnchor.ConstrainedLayoutAnchor top;
+ }
+
+}
+
diff --git a/ui/ui-layout/build.gradle b/ui/ui-layout/build.gradle
index 9beabcf..1c364ba 100644
--- a/ui/ui-layout/build.gradle
+++ b/ui/ui-layout/build.gradle
@@ -39,6 +39,7 @@
implementation project(":compose:compose-runtime")
api project(":ui:ui-core")
implementation project(":ui:ui-framework")
+ implementation(CONSTRAINT_LAYOUT_SOLVER)
testImplementation(ANDROIDX_TEST_RULES)
testImplementation(ANDROIDX_TEST_RUNNER)
diff --git a/ui/ui-layout/integration-tests/layout-demos/src/main/AndroidManifest.xml b/ui/ui-layout/integration-tests/layout-demos/src/main/AndroidManifest.xml
index 09bb609..41c77fe 100644
--- a/ui/ui-layout/integration-tests/layout-demos/src/main/AndroidManifest.xml
+++ b/ui/ui-layout/integration-tests/layout-demos/src/main/AndroidManifest.xml
@@ -27,7 +27,14 @@
<category android:name="androidx.ui.demos.SAMPLE_CODE" />
</intent-filter>
</activity>
-
+ <activity android:name=".ConstraintLayoutActivity"
+ android:configChanges="orientation|screenSize"
+ android:label="Layout/ConstraintLayout">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="androidx.ui.demos.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
<activity android:name=".ComplexLayoutActivity"
android:configChanges="orientation|screenSize"
android:label="Layout/Complex layout">
diff --git a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ConstraintLayoutActivity.kt b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ConstraintLayoutActivity.kt
new file mode 100644
index 0000000..c57aacb
--- /dev/null
+++ b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ConstraintLayoutActivity.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.layout.demos
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.compose.Composable
+import androidx.ui.core.Draw
+import androidx.ui.core.Text
+import androidx.ui.core.dp
+import androidx.ui.core.setContent
+import androidx.ui.core.sp
+import androidx.ui.core.toRect
+import androidx.ui.graphics.Color
+import androidx.ui.graphics.Paint
+import androidx.ui.layout.constraintlayout.ConstraintLayout
+import androidx.ui.layout.constraintlayout.ConstraintSet
+import androidx.ui.layout.constraintlayout.ConstraintSetBuilderScope
+import androidx.ui.layout.constraintlayout.Tag
+import androidx.ui.text.TextStyle
+
+/**
+ * Simple ConstraintLayout demo
+ */
+class ConstraintLayoutActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ CLDemo()
+ }
+ }
+}
+
+@Composable
+fun CLDemo() {
+ ConstraintLayout(ConstraintSet {
+ val text1 = tag("text1")
+ val text2 = tag("text2")
+ val text3 = tag("text3")
+ val text4 = tag("text4")
+ val text5 = tag("text5")
+
+ text2.center()
+
+ val half = createGuidelineFromLeft(percent = 0.5f)
+ text1.apply {
+ left constrainTo half
+ left.margin = 50.dp
+ bottom constrainTo text2.top
+ }
+
+ text3 constrainHorizontallyTo parent
+ text3.horizontalBias = 0.2f
+ text4 constrainHorizontallyTo parent
+ text4.horizontalBias = 0.8f
+ val chain = createVerticalChain(
+ text3,
+ text4,
+ chainStyle = ConstraintSetBuilderScope.ChainStyle.Spread
+ )
+ chain.top.margin = 100.dp
+ chain.bottom.margin = 100.dp
+
+ val barrier = createBottomBarrier(text2, text3)
+ barrier.margin = 50.dp
+ text5.top constrainTo barrier
+ text5.centerHorizontally()
+ }) {
+ Draw { canvas, parentSize ->
+ canvas.drawRect(parentSize.toRect(), Paint().apply { color = Color.Blue })
+ }
+ Text(modifier = Tag("text1"), text = "Text1", style = TextStyle(fontSize = 10.sp))
+ Text(modifier = Tag("text2"), text = "Text2", style = TextStyle(fontSize = 12.sp))
+ Text(modifier = Tag("text3"), text = "Text3", style = TextStyle(fontSize = 14.sp))
+ Text(modifier = Tag("text4"), text = "Text4", style = TextStyle(fontSize = 16.sp))
+ Text(modifier = Tag("text5"), text = "Text5", style = TextStyle(fontSize = 18.sp))
+ }
+}
diff --git a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt
index 0e94d80..69af541 100644
--- a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt
+++ b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt
@@ -22,6 +22,7 @@
import androidx.ui.core.dp
import androidx.ui.graphics.Color
import androidx.ui.layout.Align
+import androidx.ui.layout.Aligned
import androidx.ui.layout.Center
import androidx.ui.layout.Column
import androidx.ui.layout.ExpandedHeight
@@ -47,6 +48,18 @@
@Sampled
@Composable
+fun SimpleAlignedModifier() {
+ SizedRectangle(modifier = Aligned.TopCenter, color = Color.Blue, width = 20.dp, height = 20.dp)
+}
+
+@Sampled
+@Composable
+fun SimpleVerticallyAlignedModifier() {
+ SizedRectangle(modifier = Aligned.CenterVertically, color = Color.Blue, height = 50.dp)
+}
+
+@Sampled
+@Composable
fun SimpleGravityInRow() {
Row(ExpandedHeight) {
// The child with no gravity modifier is positioned by default so that its top edge is
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt
index 1442e18..2de62fa 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignTest.kt
@@ -32,8 +32,12 @@
import androidx.ui.core.px
import androidx.ui.core.withDensity
import androidx.ui.layout.Align
+import androidx.ui.layout.Aligned
import androidx.ui.layout.AspectRatio
import androidx.ui.layout.Container
+import androidx.ui.layout.ExpandedHeight
+import androidx.ui.layout.Size
+import androidx.ui.layout.Width
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
@@ -85,6 +89,83 @@
}
@Test
+ fun test2DAlignedModifier() = withDensity(density) {
+ val sizeDp = 50.dp
+ val size = sizeDp.toIntPx()
+
+ val positionedLatch = CountDownLatch(2)
+ val alignSize = Ref<PxSize>()
+ val alignPosition = Ref<PxPosition>()
+ val childSize = Ref<PxSize>()
+ val childPosition = Ref<PxPosition>()
+ show {
+ Container {
+ SaveLayoutInfo(
+ size = alignSize,
+ position = alignPosition,
+ positionedLatch = positionedLatch
+ )
+ Container(modifier = Aligned.BottomRight wraps Size(sizeDp, sizeDp)) {
+ SaveLayoutInfo(
+ size = childSize,
+ position = childPosition,
+ positionedLatch = positionedLatch
+ )
+ }
+ }
+ }
+ positionedLatch.await(1, TimeUnit.SECONDS)
+
+ val root = findAndroidComposeView()
+ waitForDraw(root)
+
+ assertEquals(PxSize(root.width.px, root.height.px), alignSize.value)
+ assertEquals(PxPosition(0.px, 0.px), alignPosition.value)
+ assertEquals(PxSize(size, size), childSize.value)
+ assertEquals(
+ PxPosition(root.width.px - size, root.height.px - size),
+ childPosition.value
+ )
+ }
+
+ @Test
+ fun test1DAlignedModifier() = withDensity(density) {
+ val sizeDp = 50.dp
+ val size = sizeDp.toIntPx()
+
+ val positionedLatch = CountDownLatch(2)
+ val alignSize = Ref<PxSize>()
+ val alignPosition = Ref<PxPosition>()
+ val childSize = Ref<PxSize>()
+ val childPosition = Ref<PxPosition>()
+ show {
+ Container {
+ SaveLayoutInfo(
+ size = alignSize,
+ position = alignPosition,
+ positionedLatch = positionedLatch
+ )
+ Container(modifier = Aligned.End wraps ExpandedHeight wraps Width(sizeDp)) {
+ SaveLayoutInfo(
+ size = childSize,
+ position = childPosition,
+ positionedLatch = positionedLatch
+ )
+ }
+ }
+ }
+ positionedLatch.await(1, TimeUnit.SECONDS)
+
+ val root = findAndroidComposeView()
+ waitForDraw(root)
+
+ assertEquals(PxSize(root.width.px, root.height.px), alignSize.value)
+ assertEquals(PxPosition(0.px, 0.px), alignPosition.value)
+ assertEquals(PxSize(size, root.height.ipx), childSize.value)
+ assertEquals(PxPosition(root.width.px - size, 0.px), childPosition.value)
+ }
+
+ @Test
fun testAlign_wrapsContent_whenMeasuredWithInfiniteConstraints() = withDensity(density) {
val sizeDp = 50.dp
val size = sizeDp.toIntPx()
@@ -131,6 +212,55 @@
assertEquals(PxPosition(0.px, 0.px), childPosition.value)
}
+ @Test
+ fun testAlignedModifier_wrapsContent_whenMeasuredWithInfiniteConstraints() = withDensity(
+ density
+ ) {
+ val sizeDp = 50.dp
+ val size = sizeDp.toIntPx()
+
+ val positionedLatch = CountDownLatch(2)
+ val alignSize = Ref<PxSize>()
+ val alignPosition = Ref<PxPosition>()
+ val childSize = Ref<PxSize>()
+ val childPosition = Ref<PxPosition>()
+ show {
+ Layout(
+ children = {
+ Container {
+ SaveLayoutInfo(
+ size = alignSize,
+ position = alignPosition,
+ positionedLatch = positionedLatch
+ )
+ Container(modifier = Aligned.BottomRight wraps Size(sizeDp, sizeDp)) {
+ SaveLayoutInfo(
+ size = childSize,
+ position = childPosition,
+ positionedLatch = positionedLatch
+ )
+ }
+ }
+ },
+ measureBlock = { measurables, constraints ->
+ val placeable = measurables.first().measure(Constraints())
+ layout(constraints.maxWidth, constraints.maxHeight) {
+ placeable.place(0.ipx, 0.ipx)
+ }
+ }
+ )
+ }
+ positionedLatch.await(1, TimeUnit.SECONDS)
+
+ val root = findAndroidComposeView()
+ waitForDraw(root)
+
+ assertEquals(PxSize(size, size), alignSize.value)
+ assertEquals(PxPosition(0.px, 0.px), alignPosition.value)
+ assertEquals(PxSize(size, size), childSize.value)
+ assertEquals(PxPosition(0.px, 0.px), childPosition.value)
+ }
+
// TODO(popam): this should be unit test instead
@Test
fun testAlignmentCoordinates_evenSize() {
@@ -184,6 +314,61 @@
}
@Test
+ fun test2DAlignedModifier_hasCorrectIntrinsicMeasurements() = withDensity(density) {
+ testIntrinsics(@Composable {
+ Container(Aligned.TopLeft wraps AspectRatio(2f)) { }
+ }) { minIntrinsicWidth, minIntrinsicHeight, maxIntrinsicWidth, maxIntrinsicHeight ->
+ // Min width.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(25.dp.toIntPx() * 2, minIntrinsicWidth(25.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), minIntrinsicWidth(IntPx.Infinity))
+
+ // Min height.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(50.dp.toIntPx() / 2, minIntrinsicHeight(50.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), minIntrinsicHeight(IntPx.Infinity))
+
+ // Max width.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(25.dp.toIntPx() * 2, maxIntrinsicWidth(25.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), maxIntrinsicWidth(IntPx.Infinity))
+
+ // Max height.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(50.dp.toIntPx() / 2, maxIntrinsicHeight(50.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), maxIntrinsicHeight(IntPx.Infinity))
+ }
+ }
+
+ @Test
+ fun test1DAlignedModifier_hasCorrectIntrinsicMeasurements() = withDensity(density) {
+ testIntrinsics(@Composable {
+ Container(Aligned.CenterVertically wraps AspectRatio(2f)) { }
+ }) { minIntrinsicWidth, minIntrinsicHeight, maxIntrinsicWidth, maxIntrinsicHeight ->
+
+ // Min width.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(25.dp.toIntPx() * 2, minIntrinsicWidth(25.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), minIntrinsicWidth(IntPx.Infinity))
+
+ // Min height.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(50.dp.toIntPx() / 2, minIntrinsicHeight(50.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), minIntrinsicHeight(IntPx.Infinity))
+
+ // Max width.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(25.dp.toIntPx() * 2, maxIntrinsicWidth(25.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), maxIntrinsicWidth(IntPx.Infinity))
+
+ // Max height.
+ assertEquals(0.ipx, minIntrinsicWidth(0.ipx))
+ assertEquals(50.dp.toIntPx() / 2, maxIntrinsicHeight(50.dp.toIntPx()))
+ assertEquals(0.dp.toIntPx(), maxIntrinsicHeight(IntPx.Infinity))
+ }
+ }
+
+ @Test
fun testAlign_hasCorrectIntrinsicMeasurements_whenNoChildren() = withDensity(density) {
testIntrinsics(@Composable {
Align(alignment = Alignment.TopLeft) { }
@@ -257,4 +442,61 @@
childPosition.value
)
}
+
+ @Test
+ fun testAlignedModifier_alignsCorrectly_whenOddDimensions_endAligned() = withDensity(density) {
+ // Given a 100 x 100 pixel container, we want to make sure that when aligning a 1 x 1 pixel
+ // child to both ends (bottom, and right) we correctly position children at the last
+ // possible pixel, and avoid rounding issues. Previously we first centered the coordinates,
+ // and then aligned after, so the maths would actually be (99 / 2) * 2, which incorrectly
+ // ends up at 100 (IntPx rounds up) - so the last pixels in both directions just wouldn't
+ // be visible.
+ val parentSize = 100.ipx.toDp()
+ val childSizeDp = 1.ipx.toDp()
+ val childSizeIpx = childSizeDp.toIntPx()
+
+ val positionedLatch = CountDownLatch(2)
+ val alignSize = Ref<PxSize>()
+ val alignPosition = Ref<PxPosition>()
+ val childSize = Ref<PxSize>()
+ val childPosition = Ref<PxPosition>()
+ show {
+ Layout(
+ children = {
+ Container(Size(parentSize, parentSize)) {
+ SaveLayoutInfo(
+ size = alignSize,
+ position = alignPosition,
+ positionedLatch = positionedLatch
+ )
+ Container(Aligned.BottomRight wraps Size(childSizeDp, childSizeDp)) {
+ SaveLayoutInfo(
+ size = childSize,
+ position = childPosition,
+ positionedLatch = positionedLatch
+ )
+ }
+ }
+ }, measureBlock = { measurables, constraints ->
+ val placeable = measurables.first().measure(Constraints())
+ layout(constraints.maxWidth, constraints.maxHeight) {
+ placeable.place(0.ipx, 0.ipx)
+ }
+ }
+ )
+ }
+ positionedLatch.await(1, TimeUnit.SECONDS)
+
+ val root = findAndroidComposeView()
+ waitForDraw(root)
+
+ assertEquals(PxSize(childSizeIpx, childSizeIpx), childSize.value)
+ assertEquals(
+ PxPosition(
+ alignSize.value!!.width - childSizeIpx,
+ alignSize.value!!.height - childSizeIpx
+ ),
+ childPosition.value
+ )
+ }
}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
index d272906..1ef4221 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
@@ -22,6 +22,11 @@
import androidx.ui.core.looseMin
import androidx.compose.Composable
import androidx.ui.core.Alignment
+import androidx.ui.core.Constraints
+import androidx.ui.core.DensityScope
+import androidx.ui.core.IntPxPosition
+import androidx.ui.core.LayoutModifier
+import androidx.ui.core.ipx
/**
* A layout that takes a child and aligns it within itself, according to the alignment parameter.
@@ -90,7 +95,7 @@
* by the parent layout rather than the child itself. Different layout models allow different
* [Gravity] options. For example, [Row] provides Top and Bottom, while [Column] provides
* Start and End.
- * Unlike [Align], layout children with [Gravity] are aligned only after the size
+ * Unlike [Aligned], layout children with [Gravity] are aligned only after the size
* of the parent is known, therefore not affecting the size of the parent in order to achieve
* their own alignment.
*
@@ -101,3 +106,160 @@
* @sample androidx.ui.layout.samples.SimpleGravityInColumn
*/
object Gravity
+
+/**
+ * Provides alignment options for a target layout where the alignment is handled by the modifier
+ * itself (rather than by the layout's parent). To achieve this, the modifier tries to fill the
+ * available space and align the target layout within itself. If the incoming constraints are
+ * infinite, the modifier will wrap the child instead and the alignment will not be achieved.
+ *
+ * Example usage:
+ *
+ * @sample androidx.ui.layout.samples.SimpleAlignedModifier
+ * @sample androidx.ui.layout.samples.SimpleVerticallyAlignedModifier
+ */
+object Aligned {
+ /**
+ * A layout modifier that positions the target component inside its parent to the top in
+ * vertical direction and wraps the component in horizontal direction.
+ */
+ val Top: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.TopLeft, direction = Direction.Vertical)
+
+ /**
+ * A layout modifier that positions the target component in the center of the parent in
+ * vertical direction and wraps the component in horizontal direction.
+ */
+ val CenterVertically: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.CenterLeft, direction = Direction.Vertical)
+
+ /**
+ * A layout modifier that positions the target component inside its parent to the bottom in
+ * vertical direction and wraps the component in horizontal direction.
+ */
+ val Bottom: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.BottomLeft, direction = Direction.Vertical)
+
+ /**
+ * A layout modifier that positions the target component inside its parent to the start edge
+ * in horizontal direction and wraps the component in vertical direction.
+ */
+ val Start: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.TopLeft, direction = Direction.Horizontal)
+
+ /**
+ * A layout modifier that positions the target component in the center of the parent in
+ * horizontal direction and wraps the component in vertical direction.
+ */
+ val CenterHorizontally: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.TopCenter, direction = Direction.Horizontal)
+
+ /**
+ * A layout modifier that positions the target component inside its parent to the end edge
+ * in horizontal direction and wraps the component in vertical direction.
+ */
+ val End: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.TopRight, direction = Direction.Horizontal)
+
+ /**
+ * A layout modifier that positions the target component top-left inside its parent.
+ */
+ val TopLeft: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.TopLeft, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component top-center inside its parent.
+ */
+ val TopCenter: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.TopCenter, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component top-right inside its parent.
+ */
+ val TopRight: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.TopRight, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component center-left inside its parent.
+ */
+ val CenterLeft: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.CenterLeft, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component in the center of its parent.
+ */
+ val Center: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.Center, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component center-right inside its parent.
+ */
+ val CenterRight: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.CenterRight, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component bottom-left inside its parent.
+ */
+ val BottomLeft: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.BottomLeft, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component bottom-center inside its parent.
+ */
+ val BottomCenter: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.BottomCenter, direction = Direction.Both)
+
+ /**
+ * A layout modifier that positions the target component bottom-right inside its parent.
+ */
+ val BottomRight: LayoutModifier =
+ AlignmentModifier(alignment = Alignment.BottomRight, direction = Direction.Both)
+}
+
+private enum class Direction {
+ Vertical, Horizontal, Both
+}
+
+private data class AlignmentModifier(
+ private val alignment: Alignment,
+ private val direction: Direction
+) : LayoutModifier {
+ override fun DensityScope.modifyConstraints(constraints: Constraints) = when (direction) {
+ Direction.Both -> constraints.looseMin()
+ Direction.Horizontal -> constraints.copy(minWidth = 0.ipx)
+ Direction.Vertical -> constraints.copy(minHeight = 0.ipx)
+ }
+
+ override fun DensityScope.modifySize(
+ constraints: Constraints,
+ childSize: IntPxSize
+ ): IntPxSize {
+ val width = if (
+ direction != Direction.Vertical && constraints.maxWidth.isFinite()
+ ) {
+ constraints.maxWidth
+ } else {
+ childSize.width
+ }
+ val height = if (
+ direction != Direction.Horizontal && constraints.maxHeight.isFinite()
+ ) {
+ constraints.maxHeight
+ } else {
+ childSize.height
+ }
+ return IntPxSize(width, height)
+ }
+
+ override fun DensityScope.modifyPosition(
+ childSize: IntPxSize,
+ containerSize: IntPxSize
+ ): IntPxPosition {
+ return alignment.align(
+ IntPxSize(
+ containerSize.width - childSize.width,
+ containerSize.height - childSize.height
+ )
+ )
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/ConstraintLayout.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/ConstraintLayout.kt
new file mode 100644
index 0000000..3632539
--- /dev/null
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/ConstraintLayout.kt
@@ -0,0 +1,683 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.layout.constraintlayout
+
+import androidx.compose.Composable
+import androidx.compose.Immutable
+import androidx.compose.memo
+import androidx.compose.unaryPlus
+import androidx.constraintlayout.solver.state.ConstraintReference
+import androidx.constraintlayout.solver.state.Dimension
+import androidx.constraintlayout.solver.state.State
+import androidx.constraintlayout.solver.state.helpers.BarrierReference
+import androidx.constraintlayout.solver.widgets.ConstraintWidget
+import androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer
+import androidx.constraintlayout.solver.widgets.Optimizer
+import androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure
+import androidx.ui.core.AlignmentLine
+import androidx.ui.core.Constraints
+import androidx.ui.core.DensityScope
+import androidx.ui.core.Dp
+import androidx.ui.core.FirstBaseline
+import androidx.ui.core.IntPx
+import androidx.ui.core.IntPxSize
+import androidx.ui.core.Layout
+import androidx.ui.core.LayoutModifier
+import androidx.ui.core.Measurable
+import androidx.ui.core.Placeable
+import androidx.ui.core.Placeable.PlacementScope.place
+import androidx.ui.core.dp
+import androidx.ui.core.hasBoundedHeight
+import androidx.ui.core.hasBoundedWidth
+import androidx.ui.core.ipx
+
+/**
+ * Layout that positions its children according to the constraints between them.
+ */
+@Composable
+fun ConstraintLayout(constraintSet: ConstraintSet, children: @Composable() () -> Unit) {
+ val measurer = +memo { Measurer() }
+ Layout(children) { measurables, constraints ->
+ val layoutSize = measurer.performMeasure(
+ constraints,
+ constraintSet,
+ measurables,
+ this
+ )
+ layout(layoutSize.width, layoutSize.height) {
+ measurer.performLayout()
+ }
+ }
+}
+
+/**
+ * Immutable description of the constraints used to layout the children of a [ConstraintLayout].
+ */
+@Immutable
+data class ConstraintSet(internal val description: ConstraintSetBuilderScope.() -> Unit)
+
+/**
+ * Builder scope for a [ConstraintSet]. The scope should not be created directly - the
+ * [ConstraintSet] function should be used instead.
+ */
+// TODO(popam): support RTL
+class ConstraintSetBuilderScope internal constructor(internal val state: State) {
+ /**
+ * Creates a reference corresponding to the constraint layout children with a specific tag,
+ * which can be used to define the constraints to be imposed to those children.
+ */
+ fun tag(tag: Any) = tags.getOrPut(tag, { ConstrainedLayoutReference(state, tag) })
+ private val tags = mutableMapOf<Any, ConstrainedLayoutReference>()
+
+ /**
+ * Reference to the [ConstraintLayout] itself, which can be used to specify constraints
+ * between itself and its children.
+ */
+ val parent = ConstrainedLayoutReference(state, State.PARENT)
+
+ class ConstrainedLayoutReference internal constructor(val state: State, val tag: Any) {
+ val left = VerticalAnchor.ConstrainedLayoutAnchor(state, this, 0)
+ val top = HorizontalAnchor.ConstrainedLayoutAnchor(state, this, 0)
+ var right = VerticalAnchor.ConstrainedLayoutAnchor(state, this, 1)
+ var bottom = HorizontalAnchor.ConstrainedLayoutAnchor(state, this, 1)
+ var baseline = ConstrainedLayoutBaselineAnchor(state, this)
+
+ /**
+ * Adds constraints between left, top, right and bottom corresponding anchors of
+ * two layout references.
+ */
+ infix fun constrainTo(other: ConstrainedLayoutReference) {
+ left constrainTo other.left
+ top constrainTo other.top
+ right constrainTo other.right
+ bottom constrainTo other.bottom
+ }
+
+ /**
+ * Adds constraints between left and right corresponding anchors of two layout references.
+ */
+ infix fun constrainHorizontallyTo(other: ConstrainedLayoutReference) {
+ left constrainTo other.left
+ right constrainTo other.right
+ }
+
+ /**
+ * Adds constraints between top and bottom corresponding anchors of two layout references.
+ */
+ infix fun constrainVerticallyTo(other: ConstrainedLayoutReference) {
+ top constrainTo other.top
+ bottom constrainTo other.bottom
+ }
+
+ /**
+ * The horizontal bias of the current layout reference.
+ */
+ // TODO(popam): keep the source of truth in ConstraintReference
+ var horizontalBias: Float = 0.5f
+ set(value) {
+ field = value
+ state.constraints(tag).horizontalBias(value)
+ }
+
+ /**
+ * The vertical bias of the current layout reference.
+ */
+ // TODO(popam): keep the source of truth in ConstraintReference
+ var verticalBias: Float = 0.5f
+ set(value) {
+ field = value
+ state.constraints(tag).verticalBias(value)
+ }
+
+ /**
+ * Centers the layout horizontally in its [parent].
+ */
+ fun centerHorizontally() = state.centerHorizontally(tag).also { it.bias(0.5f) }.apply()
+
+ /**
+ * Centers the layout vertically in its [parent].
+ */
+ fun centerVertically() = state.centerVertically(tag).also { it.bias(0.5f) }.apply()
+
+ /**
+ * Centers the layout in its [parent].
+ */
+ fun center() {
+ centerHorizontally()
+ centerVertically()
+ }
+ }
+
+ /**
+ * Represents a horizontal chain.
+ */
+ class HorizontalChain internal constructor(
+ internal val first: ConstrainedLayoutReference,
+ internal val last: ConstrainedLayoutReference
+ ) {
+ val left: VerticalAnchor.ConstrainedLayoutAnchor get() = first.left
+ val right: VerticalAnchor.ConstrainedLayoutAnchor get() = last.right
+
+ infix fun constrainTo(other: ConstrainedLayoutReference) {
+ left constrainTo other.left
+ right constrainTo other.right
+ }
+ }
+
+ /**
+ * Represents a vertical chain.
+ */
+ class VerticalChain internal constructor(
+ internal val first: ConstrainedLayoutReference,
+ internal val last: ConstrainedLayoutReference
+ ) {
+ val top: HorizontalAnchor.ConstrainedLayoutAnchor get() = first.top
+ val bottom: HorizontalAnchor.ConstrainedLayoutAnchor get() = last.bottom
+
+ infix fun constrainTo(other: ConstrainedLayoutReference) {
+ first.top constrainTo other.top
+ last.bottom constrainTo other.bottom
+ }
+ }
+
+ /**
+ * Defines a vertical anchor which can be used for defining constraints. It can correspond:
+ * - to a side or baseline of a child of the [ConstraintLayout]
+ * - to a left barrier or right barrier
+ * - to a vertical guideline
+ */
+ sealed class VerticalAnchor {
+ internal abstract val state: State
+ internal abstract val tag: Any
+ internal abstract val index: Int
+
+ /**
+ * Anchor corresponding to the left or right of a child of the [ConstraintLayout].
+ */
+ class ConstrainedLayoutAnchor internal constructor(
+ override val state: State,
+ internal val constrainedLayoutReference: ConstrainedLayoutReference,
+ override val index: Int
+ ) : VerticalAnchor() {
+ override val tag: Any get() = constrainedLayoutReference.tag
+
+ // TODO(popam): keep the source of truth in ConstraintReference
+ /**
+ * The margin to be applied to the current [ConstrainedLayoutAnchor].
+ */
+ var margin: Dp = 0.dp
+ set(value) {
+ field = value
+ state.constraints(tag)
+ .let { if (index == 0) it.start() else it.end() }
+ .margin(value)
+ }
+
+ /**
+ * Adds a constraint between a [ConstrainedLayoutAnchor] and a [VerticalAnchor].
+ */
+ infix fun constrainTo(other: VerticalAnchor) {
+ with(state.constraints(this.constrainedLayoutReference.tag)) {
+ val thisIndex = this@ConstrainedLayoutAnchor.index
+ val otherIndex = other.index
+ verticalAnchorFunctions[thisIndex][otherIndex].invoke(this, other.tag)
+ }
+ }
+ }
+
+ /**
+ * Anchor corresponding to a vertical guideline.
+ */
+ class GuidelineAnchor internal constructor(
+ override val state: State,
+ override val tag: Any,
+ override val index: Int = 0
+ ) : VerticalAnchor()
+
+ /**
+ * Anchor corresponding to a left or right barrier.
+ */
+ class BarrierAnchor internal constructor(
+ override val state: State,
+ override val tag: Any,
+ private val barrierReference: BarrierReference,
+ override val index: Int = 0
+ ) : VerticalAnchor() {
+ // TODO(popam): keep the source of truth in ConstraintReference
+ /**
+ * The margin to be applied to the current [BarrierAnchor], in the
+ * direction of the barrier.
+ */
+ var margin: Dp = 0.dp
+ set(value) {
+ field = value
+ barrierReference.margin(value)
+ }
+ }
+ }
+
+ /**
+ * Defines an horizontal anchor which can be used for defining constraints. It can correspond:
+ * - to a side or baseline of a child of the [ConstraintLayout]
+ * - to a top or bottom barrier
+ * - to a horizontal guideline
+ */
+ sealed class HorizontalAnchor {
+ internal abstract val state: State
+ internal abstract val tag: Any
+ internal abstract val index: Int
+
+ /**
+ * Anchor corresponding to the top or bottom of a child of the [ConstraintLayout].
+ */
+ class ConstrainedLayoutAnchor internal constructor(
+ override val state: State,
+ internal val constrainedLayoutReference: ConstrainedLayoutReference,
+ override val index: Int
+ ) : HorizontalAnchor() {
+ override val tag: Any get() = constrainedLayoutReference.tag
+
+ // TODO(popam): keep the source of truth in ConstraintReference
+ /**
+ * The margin to be applied to the current [ConstrainedLayoutAnchor].
+ */
+ var margin: Dp = 0.dp
+ set(value) {
+ field = value
+ state.constraints(tag)
+ .let { if (index == 0) it.top() else it.bottom() }
+ .margin(value)
+ }
+
+ /**
+ * Adds a constraint between a [ConstrainedLayoutAnchor] and a [HorizontalAnchor].
+ */
+ infix fun constrainTo(other: HorizontalAnchor) {
+ with(state.constraints(this.constrainedLayoutReference.tag)) {
+ val thisIndex = this@ConstrainedLayoutAnchor.index
+ val otherIndex = other.index
+ horizontalAnchorFunctions[thisIndex][otherIndex].invoke(this, other.tag)
+ }
+ }
+ }
+
+ /**
+ * Anchor corresponding to a horizontal guideline.
+ */
+ class GuidelineAnchor internal constructor(
+ override val state: State,
+ override val tag: Any,
+ override val index: Int = 0
+ ) : HorizontalAnchor()
+
+ /**
+ * Anchor corresponding to a top or bottom barrier.
+ */
+ class BarrierAnchor internal constructor(
+ override val state: State,
+ override val tag: Any,
+ private val barrierReference: BarrierReference,
+ override val index: Int = 0
+ ) : HorizontalAnchor() {
+ // TODO(popam): keep the source of truth in ConstraintReference
+ var margin: Dp = 0.dp
+ set(value) {
+ field = value
+ barrierReference.margin(value)
+ }
+ }
+ }
+
+ /**
+ * Anchor corresponding to the baseline of a [ConstraintLayout] child.
+ */
+ class ConstrainedLayoutBaselineAnchor internal constructor(
+ val state: State,
+ val tag: Any
+ ) {
+ /**
+ * Adds a constraint between two [ConstrainedLayoutBaselineAnchor] anchors.
+ */
+ infix fun constrainTo(other: ConstrainedLayoutBaselineAnchor) {
+ with(state.constraints(tag)) {
+ baselineAnchorFunction.invoke(this, other.tag)
+ }
+ }
+ }
+
+ /**
+ * Creates a horizontal chain including the referenced layouts.
+ */
+ fun createHorizontalChain(
+ vararg elements: ConstrainedLayoutReference,
+ chainStyle: ChainStyle = ChainStyle.Spread
+ ): HorizontalChain {
+ state.horizontalChain(*(elements.map { it.tag }.toTypedArray()))
+ .also { it.style(chainStyle.style) }
+ .apply()
+ if (chainStyle.bias != null) elements[0].horizontalBias = chainStyle.bias
+ return HorizontalChain(elements.first(), elements.last())
+ }
+
+ /**
+ * Creates a vertical chain including the referenced layouts.
+ */
+ fun createVerticalChain(
+ vararg elements: ConstrainedLayoutReference,
+ chainStyle: ChainStyle = ChainStyle.Spread
+ ): VerticalChain {
+ state.verticalChain(*(elements.map { it.tag }.toTypedArray()))
+ .also { it.style(chainStyle.style) }
+ .apply()
+ if (chainStyle.bias != null) elements[0].verticalBias = chainStyle.bias
+ return VerticalChain(elements.first(), elements.last())
+ }
+
+ /**
+ * The style of a horizontal or vertical chain.
+ */
+ class ChainStyle internal constructor(
+ internal val style: State.Chain,
+ internal val bias: Float? = null
+ ) {
+ companion object {
+ val Spread = ChainStyle(State.Chain.SPREAD)
+ val SpreadInside = ChainStyle(State.Chain.SPREAD_INSIDE)
+ val Packed = Packed(0.5f)
+ fun Packed(bias: Float) = ChainStyle(State.Chain.PACKED, bias)
+ }
+ }
+
+ /**
+ * Creates a guideline at a specific offset from the left of the [ConstraintLayout].
+ */
+ fun createGuidelineFromLeft(offset: Dp): VerticalAnchor.GuidelineAnchor {
+ val tag = object : Any() {}
+ state.verticalGuideline(tag).apply { start(offset) }
+ return VerticalAnchor.GuidelineAnchor(state, tag)
+ }
+
+ /**
+ * Creates a guideline at a width percentage from the left of the [ConstraintLayout].
+ */
+ fun createGuidelineFromLeft(percent: Float): VerticalAnchor.GuidelineAnchor {
+ val tag = object : Any() {}
+ state.verticalGuideline(tag).apply { percent(percent) }
+ return VerticalAnchor.GuidelineAnchor(state, tag)
+ }
+
+ /**
+ * Creates a guideline at a specific offset from the right of the [ConstraintLayout].
+ */
+ fun createGuidelineFromRight(offset: Dp): VerticalAnchor.GuidelineAnchor {
+ val tag = object : Any() {}
+ state.verticalGuideline(tag).apply { end(offset) }
+ return VerticalAnchor.GuidelineAnchor(state, tag)
+ }
+
+ /**
+ * Creates a guideline at a width percentage from the right of the [ConstraintLayout].
+ */
+ fun createGuidelineFromRight(percent: Float): VerticalAnchor.GuidelineAnchor {
+ return createGuidelineFromLeft(1f - percent)
+ }
+
+ /**
+ * Creates a guideline at a specific offset from the top of the [ConstraintLayout].
+ */
+ fun createGuidelineFromTop(offset: Dp): HorizontalAnchor.GuidelineAnchor {
+ val tag = object : Any() {}
+ state.horizontalGuideline(tag).apply { start(offset) }
+ return HorizontalAnchor.GuidelineAnchor(state, tag)
+ }
+
+ /**
+ * Creates a guideline at a height percentage from the top of the [ConstraintLayout].
+ */
+ fun createGuidelineFromTop(percent: Float): HorizontalAnchor.GuidelineAnchor {
+ val tag = object : Any() {}
+ state.horizontalGuideline(tag).apply { percent(percent) }
+ return HorizontalAnchor.GuidelineAnchor(state, tag)
+ }
+
+ /**
+ * Creates a guideline at a specific offset from the bottom of the [ConstraintLayout].
+ */
+ fun createGuidelineFromBottom(offset: Dp): HorizontalAnchor.GuidelineAnchor {
+ val tag = object : Any() {}
+ state.horizontalGuideline(tag).apply { end(offset) }
+ return HorizontalAnchor.GuidelineAnchor(state, tag)
+ }
+
+ /**
+ * Creates a guideline at a height percentage from the bottom of the [ConstraintLayout].
+ */
+ fun createGuidelineFromBottom(percent: Float): HorizontalAnchor.GuidelineAnchor {
+ return createGuidelineFromTop(1f - percent)
+ }
+
+ /**
+ * Creates and returns a top barrier, containing the specified elements.
+ */
+ fun createTopBarrier(
+ vararg elements: ConstrainedLayoutReference
+ ): HorizontalAnchor.BarrierAnchor {
+ val tag = object : Any() {}
+ val barrier = state.barrier(tag, State.Direction.TOP).apply {
+ add(*(elements.map { it.tag }.toTypedArray()))
+ }
+ return HorizontalAnchor.BarrierAnchor(state, tag, barrier)
+ }
+
+ /**
+ * Creates and returns a bottom barrier, containing the specified elements.
+ */
+ fun createBottomBarrier(
+ vararg elements: ConstrainedLayoutReference
+ ): HorizontalAnchor.BarrierAnchor {
+ val tag = object : Any() {}
+ val barrier = state.barrier(tag, State.Direction.BOTTOM).apply {
+ add(*(elements.map { it.tag }.toTypedArray()))
+ }
+ return HorizontalAnchor.BarrierAnchor(state, tag, barrier)
+ }
+
+ /**
+ * Creates and returns a left barrier, containing the specified elements.
+ */
+ fun createLeftBarrier(
+ vararg elements: ConstrainedLayoutReference
+ ): VerticalAnchor.BarrierAnchor {
+ val tag = object : Any() {}
+ val barrier = state.barrier(tag, State.Direction.START).apply {
+ add(*(elements.map { it.tag }.toTypedArray()))
+ }
+ return VerticalAnchor.BarrierAnchor(state, tag, barrier)
+ }
+
+ /**
+ * Creates and returns a right barrier, containing the specified elements.
+ */
+ fun createRightBarrier(
+ vararg elements: ConstrainedLayoutReference
+ ): VerticalAnchor.BarrierAnchor {
+ val tag = object : Any() {}
+ val barrier = state.barrier(tag, State.Direction.END).apply {
+ add(*(elements.map { it.tag }.toTypedArray()))
+ }
+ return VerticalAnchor.BarrierAnchor(state, tag, barrier)
+ }
+
+ // TODO(popam): support these
+ val WrapDimension = Dimension.WRAP_DIMENSION
+ val SpreadDimension = Dimension.SPREAD_DIMENSION
+ val ParentDimension = Dimension.PARENT_DIMENSION
+
+ internal companion object {
+ val verticalAnchorFunctions: Array<Array<ConstraintReference.(Any) -> Unit>> = arrayOf(
+ arrayOf(
+ { other -> startToStart(other).apply() },
+ { other -> startToEnd(other).apply() }
+ ),
+ arrayOf(
+ { other -> endToStart(other) },
+ { other -> endToEnd(other) }
+ )
+ )
+ val horizontalAnchorFunctions: Array<Array<ConstraintReference.(Any) -> Unit>> = arrayOf(
+ arrayOf(
+ { other -> topToTop(other) },
+ { other -> topToBottom(other) }
+ ),
+ arrayOf(
+ { other -> bottomToTop(other) },
+ { other -> bottomToBottom(other) }
+ )
+ )
+ val baselineAnchorFunction: ConstraintReference.(Any) -> Unit =
+ { other -> baselineToBaseline(other) }
+ }
+}
+
+/**
+ * Creates a tag that can be used to identify a measurable / child.
+ * TODO(popam): should not be ConstraintLayout specific
+ */
+fun Tag(tag: Any): LayoutModifier = TagModifier(tag)
+
+/**
+ * Returns the tag associated to a measurable using the [Tag] modifier.
+ */
+val Measurable.tag get() = (parentData as? TagModifier)?.tag
+
+private class Measurer internal constructor() : BasicMeasure.Measurer {
+ private val root = ConstraintWidgetContainer(0, 0).also { it.measurer = this }
+ private val placeables = mutableMapOf<Measurable, Placeable>()
+ private lateinit var densityScope: DensityScope
+ private val state = object : State() {
+ override fun convertDimension(value: Any?): Int {
+ return if (value is Dp) {
+ with(densityScope) { value.toIntPx().value }
+ } else {
+ super.convertDimension(value)
+ }
+ }
+ }
+
+ override fun measure(constraintWidget: ConstraintWidget, measure: BasicMeasure.Measure) {
+ val measurable = constraintWidget.companionWidget
+ if (measurable !is Measurable) return
+
+ var measuredWidth = constraintWidget.width
+ var measuredHeight = constraintWidget.height
+
+ val constraints = Constraints(
+ if (measure.wrapsHorizontal) 0.ipx else constraintWidget.width.ipx,
+ if (measure.wrapsHorizontal) IntPx.Infinity else constraintWidget.width.ipx,
+ if (measure.wrapsVertical) 0.ipx else constraintWidget.height.ipx,
+ if (measure.wrapsVertical) IntPx.Infinity else constraintWidget.height.ipx
+ )
+
+ val placeable = measurable.measure(constraints).also { placeables[measurable] = it }
+
+ if (measure.wrapsHorizontal) {
+ measuredWidth = placeable.width.value
+ }
+ if (measure.wrapsVertical) {
+ measuredHeight = placeable.height.value
+ }
+
+ measure.measuredWidth = measuredWidth
+ measure.measuredHeight = measuredHeight
+ val baseline = placeable[FirstBaseline]
+ if (baseline != null) {
+ measure.measuredBaseline = baseline.value
+ } else {
+ measure.measuredBaseline = measuredHeight
+ }
+ }
+
+ fun performMeasure(
+ constraints: Constraints,
+ constraintSet: ConstraintSet,
+ measurables: List<Measurable>,
+ densityScope: DensityScope
+ ): IntPxSize {
+ this.densityScope = densityScope
+ state.reset()
+ measurables.forEach { measurable ->
+ state.map(measurable.tag ?: object : Any() {}, measurable)
+ }
+ state.width(if (constraints.hasBoundedWidth) {
+ Dimension.Fixed(constraints.maxWidth.value)
+ } else {
+ Dimension.Wrap()
+ })
+ state.height(if (constraints.hasBoundedHeight) {
+ Dimension.Fixed(constraints.maxHeight.value)
+ } else {
+ Dimension.Wrap()
+ })
+ constraintSet.description(ConstraintSetBuilderScope(state))
+ state.apply(root)
+
+ root.minWidth = constraints.minWidth.value
+ root.minHeight = constraints.minHeight.value
+ root.measure(
+ Optimizer.OPTIMIZATION_NONE,
+ if (constraints.hasBoundedWidth) BasicMeasure.EXACTLY else BasicMeasure.WRAP_CONTENT,
+ if (constraints.hasBoundedWidth) constraints.maxWidth.value else 0,
+ if (constraints.hasBoundedHeight) BasicMeasure.EXACTLY else BasicMeasure.WRAP_CONTENT,
+ if (constraints.hasBoundedHeight) constraints.maxHeight.value else 0,
+ 0,
+ 0,
+ 0,
+ 0
+ )
+ return IntPxSize(root.width.ipx, root.height.ipx)
+ }
+
+ fun performLayout() {
+ for (child in root.children) {
+ val measurable = child.companionWidget
+ if (measurable !is Measurable) continue
+ placeables[measurable]?.place(IntPx(child.x), IntPx(child.y))
+ }
+ }
+
+ override fun didMeasures() { }
+
+ private val BasicMeasure.Measure.wrapsHorizontal
+ get() = horizontalBehavior == ConstraintWidget.DimensionBehaviour.WRAP_CONTENT
+ private val BasicMeasure.Measure.wrapsVertical
+ get() = verticalBehavior == ConstraintWidget.DimensionBehaviour.WRAP_CONTENT
+}
+
+private data class TagModifier(val tag: Any) : LayoutModifier {
+ override fun DensityScope.modifyConstraints(constraints: Constraints) = constraints
+ override fun DensityScope.modifySize(constraints: Constraints, childSize: IntPxSize) = childSize
+ override fun DensityScope.minIntrinsicWidthOf(measurable: Measurable, height: IntPx) =
+ measurable.minIntrinsicWidth(height)
+ override fun DensityScope.maxIntrinsicWidthOf(measurable: Measurable, height: IntPx) =
+ measurable.maxIntrinsicWidth(height)
+ override fun DensityScope.minIntrinsicHeightOf(measurable: Measurable, width: IntPx) =
+ measurable.minIntrinsicHeight(width)
+ override fun DensityScope.maxIntrinsicHeightOf(measurable: Measurable, width: IntPx) =
+ measurable.maxIntrinsicHeight(width)
+ override fun DensityScope.modifyAlignmentLine(line: AlignmentLine, value: IntPx?) = value
+ override fun DensityScope.modifyParentData(parentData: Any?) = this@TagModifier
+}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Spacing.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Spacing.kt
index 550d78e..ff997af 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Spacing.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Spacing.kt
@@ -81,10 +81,9 @@
)
override fun DensityScope.modifyPosition(
- childPosition: IntPxPosition,
childSize: IntPxSize,
containerSize: IntPxSize
- ) = IntPxPosition(left.toIntPx() + childPosition.x, top.toIntPx() + childPosition.y)
+ ) = IntPxPosition(left.toIntPx(), top.toIntPx())
}
/**
diff --git a/ui/ui-material/api/0.1.0-dev03.txt b/ui/ui-material/api/0.1.0-dev03.txt
index 0733899..26a3d17 100644
--- a/ui/ui-material/api/0.1.0-dev03.txt
+++ b/ui/ui-material/api/0.1.0-dev03.txt
@@ -70,7 +70,8 @@
public final class ColorKt {
ctor public ColorKt();
- method public static androidx.ui.material.ColorPalette ColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
+ method public static androidx.ui.material.ColorPalette darkColorPalette(androidx.ui.graphics.Color primary = Color(4290479868), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color background = Color(4279374354), androidx.ui.graphics.Color surface = Color(4279374354), androidx.ui.graphics.Color error = Color(4291782265), androidx.ui.graphics.Color onPrimary = Color.Black, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.White, androidx.ui.graphics.Color onSurface = Color.White, androidx.ui.graphics.Color onError = Color.Black);
+ method public static androidx.ui.material.ColorPalette lightColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
}
public interface ColorPalette {
@@ -86,8 +87,10 @@
method public androidx.ui.graphics.Color getSecondary();
method public androidx.ui.graphics.Color getSecondaryVariant();
method public androidx.ui.graphics.Color getSurface();
+ method public boolean isLight();
property public abstract androidx.ui.graphics.Color background;
property public abstract androidx.ui.graphics.Color error;
+ property public abstract boolean isLight;
property public abstract androidx.ui.graphics.Color onBackground;
property public abstract androidx.ui.graphics.Color onError;
property public abstract androidx.ui.graphics.Color onPrimary;
@@ -161,13 +164,9 @@
public final class FloatingActionButtonKt {
ctor public FloatingActionButtonKt();
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void FloatingActionButton(androidx.ui.graphics.Image icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
- method public static androidx.ui.core.Dp getExtendedFabHeight();
- method public static androidx.ui.core.Dp getExtendedFabIconPadding();
- method public static androidx.ui.core.Dp getExtendedFabTextPadding();
- method public static androidx.ui.core.Dp getFabSize();
}
public final class ListItemKt {
@@ -185,7 +184,7 @@
public final class MaterialThemeKt {
ctor public MaterialThemeKt();
- method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = ColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = lightColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ProgressIndicatorKt {
diff --git a/ui/ui-material/api/current.txt b/ui/ui-material/api/current.txt
index 0733899..26a3d17 100644
--- a/ui/ui-material/api/current.txt
+++ b/ui/ui-material/api/current.txt
@@ -70,7 +70,8 @@
public final class ColorKt {
ctor public ColorKt();
- method public static androidx.ui.material.ColorPalette ColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
+ method public static androidx.ui.material.ColorPalette darkColorPalette(androidx.ui.graphics.Color primary = Color(4290479868), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color background = Color(4279374354), androidx.ui.graphics.Color surface = Color(4279374354), androidx.ui.graphics.Color error = Color(4291782265), androidx.ui.graphics.Color onPrimary = Color.Black, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.White, androidx.ui.graphics.Color onSurface = Color.White, androidx.ui.graphics.Color onError = Color.Black);
+ method public static androidx.ui.material.ColorPalette lightColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
}
public interface ColorPalette {
@@ -86,8 +87,10 @@
method public androidx.ui.graphics.Color getSecondary();
method public androidx.ui.graphics.Color getSecondaryVariant();
method public androidx.ui.graphics.Color getSurface();
+ method public boolean isLight();
property public abstract androidx.ui.graphics.Color background;
property public abstract androidx.ui.graphics.Color error;
+ property public abstract boolean isLight;
property public abstract androidx.ui.graphics.Color onBackground;
property public abstract androidx.ui.graphics.Color onError;
property public abstract androidx.ui.graphics.Color onPrimary;
@@ -161,13 +164,9 @@
public final class FloatingActionButtonKt {
ctor public FloatingActionButtonKt();
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void FloatingActionButton(androidx.ui.graphics.Image icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
- method public static androidx.ui.core.Dp getExtendedFabHeight();
- method public static androidx.ui.core.Dp getExtendedFabIconPadding();
- method public static androidx.ui.core.Dp getExtendedFabTextPadding();
- method public static androidx.ui.core.Dp getFabSize();
}
public final class ListItemKt {
@@ -185,7 +184,7 @@
public final class MaterialThemeKt {
ctor public MaterialThemeKt();
- method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = ColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = lightColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ProgressIndicatorKt {
diff --git a/ui/ui-material/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-material/api/public_plus_experimental_0.1.0-dev03.txt
index 0733899..26a3d17 100644
--- a/ui/ui-material/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-material/api/public_plus_experimental_0.1.0-dev03.txt
@@ -70,7 +70,8 @@
public final class ColorKt {
ctor public ColorKt();
- method public static androidx.ui.material.ColorPalette ColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
+ method public static androidx.ui.material.ColorPalette darkColorPalette(androidx.ui.graphics.Color primary = Color(4290479868), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color background = Color(4279374354), androidx.ui.graphics.Color surface = Color(4279374354), androidx.ui.graphics.Color error = Color(4291782265), androidx.ui.graphics.Color onPrimary = Color.Black, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.White, androidx.ui.graphics.Color onSurface = Color.White, androidx.ui.graphics.Color onError = Color.Black);
+ method public static androidx.ui.material.ColorPalette lightColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
}
public interface ColorPalette {
@@ -86,8 +87,10 @@
method public androidx.ui.graphics.Color getSecondary();
method public androidx.ui.graphics.Color getSecondaryVariant();
method public androidx.ui.graphics.Color getSurface();
+ method public boolean isLight();
property public abstract androidx.ui.graphics.Color background;
property public abstract androidx.ui.graphics.Color error;
+ property public abstract boolean isLight;
property public abstract androidx.ui.graphics.Color onBackground;
property public abstract androidx.ui.graphics.Color onError;
property public abstract androidx.ui.graphics.Color onPrimary;
@@ -161,13 +164,9 @@
public final class FloatingActionButtonKt {
ctor public FloatingActionButtonKt();
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void FloatingActionButton(androidx.ui.graphics.Image icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
- method public static androidx.ui.core.Dp getExtendedFabHeight();
- method public static androidx.ui.core.Dp getExtendedFabIconPadding();
- method public static androidx.ui.core.Dp getExtendedFabTextPadding();
- method public static androidx.ui.core.Dp getFabSize();
}
public final class ListItemKt {
@@ -185,7 +184,7 @@
public final class MaterialThemeKt {
ctor public MaterialThemeKt();
- method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = ColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = lightColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ProgressIndicatorKt {
diff --git a/ui/ui-material/api/public_plus_experimental_current.txt b/ui/ui-material/api/public_plus_experimental_current.txt
index 0733899..26a3d17 100644
--- a/ui/ui-material/api/public_plus_experimental_current.txt
+++ b/ui/ui-material/api/public_plus_experimental_current.txt
@@ -70,7 +70,8 @@
public final class ColorKt {
ctor public ColorKt();
- method public static androidx.ui.material.ColorPalette ColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
+ method public static androidx.ui.material.ColorPalette darkColorPalette(androidx.ui.graphics.Color primary = Color(4290479868), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color background = Color(4279374354), androidx.ui.graphics.Color surface = Color(4279374354), androidx.ui.graphics.Color error = Color(4291782265), androidx.ui.graphics.Color onPrimary = Color.Black, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.White, androidx.ui.graphics.Color onSurface = Color.White, androidx.ui.graphics.Color onError = Color.Black);
+ method public static androidx.ui.material.ColorPalette lightColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
}
public interface ColorPalette {
@@ -86,8 +87,10 @@
method public androidx.ui.graphics.Color getSecondary();
method public androidx.ui.graphics.Color getSecondaryVariant();
method public androidx.ui.graphics.Color getSurface();
+ method public boolean isLight();
property public abstract androidx.ui.graphics.Color background;
property public abstract androidx.ui.graphics.Color error;
+ property public abstract boolean isLight;
property public abstract androidx.ui.graphics.Color onBackground;
property public abstract androidx.ui.graphics.Color onError;
property public abstract androidx.ui.graphics.Color onPrimary;
@@ -161,13 +164,9 @@
public final class FloatingActionButtonKt {
ctor public FloatingActionButtonKt();
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void FloatingActionButton(androidx.ui.graphics.Image icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
- method public static androidx.ui.core.Dp getExtendedFabHeight();
- method public static androidx.ui.core.Dp getExtendedFabIconPadding();
- method public static androidx.ui.core.Dp getExtendedFabTextPadding();
- method public static androidx.ui.core.Dp getFabSize();
}
public final class ListItemKt {
@@ -185,7 +184,7 @@
public final class MaterialThemeKt {
ctor public MaterialThemeKt();
- method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = ColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = lightColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ProgressIndicatorKt {
diff --git a/ui/ui-material/api/restricted_0.1.0-dev03.txt b/ui/ui-material/api/restricted_0.1.0-dev03.txt
index 0733899..26a3d17 100644
--- a/ui/ui-material/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-material/api/restricted_0.1.0-dev03.txt
@@ -70,7 +70,8 @@
public final class ColorKt {
ctor public ColorKt();
- method public static androidx.ui.material.ColorPalette ColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
+ method public static androidx.ui.material.ColorPalette darkColorPalette(androidx.ui.graphics.Color primary = Color(4290479868), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color background = Color(4279374354), androidx.ui.graphics.Color surface = Color(4279374354), androidx.ui.graphics.Color error = Color(4291782265), androidx.ui.graphics.Color onPrimary = Color.Black, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.White, androidx.ui.graphics.Color onSurface = Color.White, androidx.ui.graphics.Color onError = Color.Black);
+ method public static androidx.ui.material.ColorPalette lightColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
}
public interface ColorPalette {
@@ -86,8 +87,10 @@
method public androidx.ui.graphics.Color getSecondary();
method public androidx.ui.graphics.Color getSecondaryVariant();
method public androidx.ui.graphics.Color getSurface();
+ method public boolean isLight();
property public abstract androidx.ui.graphics.Color background;
property public abstract androidx.ui.graphics.Color error;
+ property public abstract boolean isLight;
property public abstract androidx.ui.graphics.Color onBackground;
property public abstract androidx.ui.graphics.Color onError;
property public abstract androidx.ui.graphics.Color onPrimary;
@@ -161,13 +164,9 @@
public final class FloatingActionButtonKt {
ctor public FloatingActionButtonKt();
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void FloatingActionButton(androidx.ui.graphics.Image icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
- method public static androidx.ui.core.Dp getExtendedFabHeight();
- method public static androidx.ui.core.Dp getExtendedFabIconPadding();
- method public static androidx.ui.core.Dp getExtendedFabTextPadding();
- method public static androidx.ui.core.Dp getFabSize();
}
public final class ListItemKt {
@@ -185,7 +184,7 @@
public final class MaterialThemeKt {
ctor public MaterialThemeKt();
- method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = ColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = lightColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ProgressIndicatorKt {
diff --git a/ui/ui-material/api/restricted_current.txt b/ui/ui-material/api/restricted_current.txt
index 0733899..26a3d17 100644
--- a/ui/ui-material/api/restricted_current.txt
+++ b/ui/ui-material/api/restricted_current.txt
@@ -70,7 +70,8 @@
public final class ColorKt {
ctor public ColorKt();
- method public static androidx.ui.material.ColorPalette ColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
+ method public static androidx.ui.material.ColorPalette darkColorPalette(androidx.ui.graphics.Color primary = Color(4290479868), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color background = Color(4279374354), androidx.ui.graphics.Color surface = Color(4279374354), androidx.ui.graphics.Color error = Color(4291782265), androidx.ui.graphics.Color onPrimary = Color.Black, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.White, androidx.ui.graphics.Color onSurface = Color.White, androidx.ui.graphics.Color onError = Color.Black);
+ method public static androidx.ui.material.ColorPalette lightColorPalette(androidx.ui.graphics.Color primary = Color(4284612846), androidx.ui.graphics.Color primaryVariant = Color(4281794739), androidx.ui.graphics.Color secondary = Color(4278442694), androidx.ui.graphics.Color secondaryVariant = Color(4278290310), androidx.ui.graphics.Color background = Color.White, androidx.ui.graphics.Color surface = Color.White, androidx.ui.graphics.Color error = Color(4289724448), androidx.ui.graphics.Color onPrimary = Color.White, androidx.ui.graphics.Color onSecondary = Color.Black, androidx.ui.graphics.Color onBackground = Color.Black, androidx.ui.graphics.Color onSurface = Color.Black, androidx.ui.graphics.Color onError = Color.White);
}
public interface ColorPalette {
@@ -86,8 +87,10 @@
method public androidx.ui.graphics.Color getSecondary();
method public androidx.ui.graphics.Color getSecondaryVariant();
method public androidx.ui.graphics.Color getSurface();
+ method public boolean isLight();
property public abstract androidx.ui.graphics.Color background;
property public abstract androidx.ui.graphics.Color error;
+ property public abstract boolean isLight;
property public abstract androidx.ui.graphics.Color onBackground;
property public abstract androidx.ui.graphics.Color onError;
property public abstract androidx.ui.graphics.Color onPrimary;
@@ -161,13 +164,9 @@
public final class FloatingActionButtonKt {
ctor public FloatingActionButtonKt();
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.core.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void FloatingActionButton(androidx.ui.graphics.Image icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.engine.geometry.Shape shape = CircleShape, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Image? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = (+MaterialTheme.colors()).primary, androidx.ui.core.Dp elevation = 6.dp);
- method public static androidx.ui.core.Dp getExtendedFabHeight();
- method public static androidx.ui.core.Dp getExtendedFabIconPadding();
- method public static androidx.ui.core.Dp getExtendedFabTextPadding();
- method public static androidx.ui.core.Dp getFabSize();
}
public final class ListItemKt {
@@ -185,7 +184,7 @@
public final class MaterialThemeKt {
ctor public MaterialThemeKt();
- method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = ColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void MaterialTheme(androidx.ui.material.ColorPalette colors = lightColorPalette(), androidx.ui.material.Typography typography = androidx.ui.material.Typography(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ProgressIndicatorKt {
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/AppBarActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/AppBarActivity.kt
index cbc2338..69edd80 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/AppBarActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/AppBarActivity.kt
@@ -22,9 +22,13 @@
import androidx.ui.core.Alignment
import androidx.ui.core.Text
import androidx.ui.core.dp
+import androidx.ui.graphics.imageFromResource
+import androidx.ui.layout.Arrangement
import androidx.ui.layout.Column
import androidx.ui.layout.Container
+import androidx.ui.layout.ExpandedHeight
import androidx.ui.layout.FlexColumn
+import androidx.ui.material.MaterialTheme
import androidx.ui.material.RadioGroup
import androidx.ui.material.demos.AppBarActivity.BottomAppBarOption.CenterFab
import androidx.ui.material.demos.AppBarActivity.BottomAppBarOption.CutoutFab
@@ -34,19 +38,14 @@
import androidx.ui.material.demos.AppBarActivity.BottomAppBarOption.NoFab
import androidx.ui.material.demos.AppBarActivity.TopAppBarOption.Actions
import androidx.ui.material.demos.AppBarActivity.TopAppBarOption.Simple
-import androidx.ui.material.samples.SimpleBottomAppBarCutoutFab
import androidx.ui.material.samples.SimpleBottomAppBarCenterFab
+import androidx.ui.material.samples.SimpleBottomAppBarCutoutFab
import androidx.ui.material.samples.SimpleBottomAppBarEndFab
import androidx.ui.material.samples.SimpleBottomAppBarExtendedCutoutFab
import androidx.ui.material.samples.SimpleBottomAppBarFancyAnimatingCutoutFab
import androidx.ui.material.samples.SimpleBottomAppBarNoFab
import androidx.ui.material.samples.SimpleTopAppBarNavIcon
import androidx.ui.material.samples.SimpleTopAppBarNavIconWithActions
-import androidx.ui.material.surface.Surface
-import androidx.ui.graphics.imageFromResource
-import androidx.ui.layout.Arrangement
-import androidx.ui.layout.ExpandedHeight
-import androidx.ui.material.MaterialTheme
class AppBarActivity : MaterialDemoActivity() {
@@ -77,65 +76,63 @@
var selectedTopAppBar by +state { Simple }
var selectedBottomAppBar by +state { NoFab }
- Surface {
- FlexColumn {
- inflexible {
- Container(height = 120.dp, alignment = Alignment.TopCenter) {
- when (selectedTopAppBar) {
- Simple -> SimpleTopAppBarNavIcon(navigationImage)
- Actions -> SimpleTopAppBarNavIconWithActions(
- favouriteImage,
- navigationImage
+ FlexColumn {
+ inflexible {
+ Container(height = 120.dp, alignment = Alignment.TopCenter) {
+ when (selectedTopAppBar) {
+ Simple -> SimpleTopAppBarNavIcon(navigationImage)
+ Actions -> SimpleTopAppBarNavIconWithActions(
+ favouriteImage,
+ navigationImage
+ )
+ }
+ }
+ }
+ flexible(1f) {
+ Column(ExpandedHeight, arrangement = Arrangement.SpaceBetween) {
+ DemoText("TopAppBar options")
+ RadioGroup {
+ topAppBarOptions.forEach { topAppBar ->
+ RadioGroupTextItem(
+ selected = (topAppBar == selectedTopAppBar),
+ onSelect = { selectedTopAppBar = topAppBar },
+ text = topAppBar.description
+ )
+ }
+ }
+ DemoText("BottomAppBar options")
+ RadioGroup {
+ bottomAppBarOptions.forEach { bottomAppBar ->
+ RadioGroupTextItem(
+ selected = (bottomAppBar == selectedBottomAppBar),
+ onSelect = { selectedBottomAppBar = bottomAppBar },
+ text = bottomAppBar.description
)
}
}
}
- flexible(1f) {
- Column(ExpandedHeight, arrangement = Arrangement.SpaceBetween) {
- DemoText("TopAppBar options")
- RadioGroup {
- topAppBarOptions.forEach { topAppBar ->
- RadioGroupTextItem(
- selected = (topAppBar == selectedTopAppBar),
- onSelect = { selectedTopAppBar = topAppBar },
- text = topAppBar.description
- )
- }
- }
- DemoText("BottomAppBar options")
- RadioGroup {
- bottomAppBarOptions.forEach { bottomAppBar ->
- RadioGroupTextItem(
- selected = (bottomAppBar == selectedBottomAppBar),
- onSelect = { selectedBottomAppBar = bottomAppBar },
- text = bottomAppBar.description
- )
- }
- }
- }
- }
- inflexible {
- Container(height = 120.dp, alignment = Alignment.BottomCenter) {
- when (selectedBottomAppBar) {
- NoFab -> SimpleBottomAppBarNoFab(favouriteImage, navigationImage)
- CenterFab -> SimpleBottomAppBarCenterFab(
- favouriteImage,
- navigationImage
- )
- EndFab -> SimpleBottomAppBarEndFab(favouriteImage)
- CutoutFab -> SimpleBottomAppBarCutoutFab(
- favouriteImage,
- navigationImage
- )
- ExtendedCutoutFab -> SimpleBottomAppBarExtendedCutoutFab(
- favouriteImage,
- navigationImage
- )
- FancyAnimatingCutoutFab -> SimpleBottomAppBarFancyAnimatingCutoutFab(
- favouriteImage,
- navigationImage
- )
- }
+ }
+ inflexible {
+ Container(height = 120.dp, alignment = Alignment.BottomCenter) {
+ when (selectedBottomAppBar) {
+ NoFab -> SimpleBottomAppBarNoFab(favouriteImage, navigationImage)
+ CenterFab -> SimpleBottomAppBarCenterFab(
+ favouriteImage,
+ navigationImage
+ )
+ EndFab -> SimpleBottomAppBarEndFab(favouriteImage)
+ CutoutFab -> SimpleBottomAppBarCutoutFab(
+ favouriteImage,
+ navigationImage
+ )
+ ExtendedCutoutFab -> SimpleBottomAppBarExtendedCutoutFab(
+ favouriteImage,
+ navigationImage
+ )
+ FancyAnimatingCutoutFab -> SimpleBottomAppBarFancyAnimatingCutoutFab(
+ favouriteImage,
+ navigationImage
+ )
}
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DataTableActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DataTableActivity.kt
index 8d92f88..0c04a5a 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DataTableActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DataTableActivity.kt
@@ -18,14 +18,11 @@
import androidx.compose.Composable
import androidx.ui.material.samples.SimpleDataTable
-import androidx.ui.material.surface.Surface
class DataTableActivity : MaterialDemoActivity() {
@Composable
override fun materialContent() {
- Surface {
- SimpleDataTable()
- }
+ SimpleDataTable()
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
index 484f12f..ec30f46 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
@@ -50,6 +50,7 @@
import androidx.ui.material.FloatingActionButton
import androidx.ui.material.MaterialTheme
import androidx.ui.material.TopAppBar
+import androidx.ui.material.lightColorPalette
import androidx.ui.material.surface.Surface
import androidx.ui.text.TextStyle
import kotlin.math.round
@@ -166,7 +167,7 @@
val secondary = lerp(Color(0xFF03DAC6), Color(0xFFBB86FC), interpolatedFraction)
val background = lerp(Color.White, Color(0xFF121212), interpolatedFraction)
- return ColorPalette(
+ return lightColorPalette(
primary = primary,
secondary = secondary,
background = background
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt
index 98ccd23..4a91328a 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt
@@ -26,21 +26,29 @@
import androidx.compose.Composable
import androidx.compose.FrameManager
import androidx.compose.Model
+import androidx.compose.unaryPlus
import androidx.preference.EditTextPreference
+import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.ui.core.setContent
+import androidx.ui.foundation.isSystemInDarkTheme
import androidx.ui.graphics.Color
import androidx.ui.graphics.toArgb
import androidx.ui.material.ColorPalette
import androidx.ui.material.MaterialTheme
+import androidx.ui.material.darkColorPalette
import androidx.ui.material.demos.MaterialSettingsActivity.SettingsFragment
-import kotlin.random.Random
+import androidx.ui.material.lightColorPalette
+import androidx.ui.material.surface.Surface
import kotlin.reflect.full.memberProperties
@Model
class CurrentColorPalette {
- var colors: ColorPalette = ColorPalette()
+ var lightColors: ColorPalette = lightColorPalette()
+ var darkColors: ColorPalette = darkColorPalette()
+
+ val colors get() = if (+isSystemInDarkTheme()) darkColors else lightColors
}
/**
@@ -49,16 +57,18 @@
*/
abstract class MaterialDemoActivity : Activity() {
- private val currentColors = CurrentColorPalette()
+ private var currentColors = CurrentColorPalette()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Ensure we are in a frame, as this is only normally initialized after the setContent call
FrameManager.ensureStarted()
- currentColors.colors = getColorsFromSharedPreferences()
+ currentColors.getColorsFromSharedPreferences()
setContent {
MaterialTheme(currentColors.colors) {
- materialContent()
+ Surface {
+ materialContent()
+ }
}
}
}
@@ -66,14 +76,15 @@
override fun onResume() {
super.onResume()
// Update colors in case we changed something in settings activity
- currentColors.colors = getColorsFromSharedPreferences()
+ currentColors.getColorsFromSharedPreferences()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
- menu?.add(Menu.NONE, SETTINGS, Menu.NONE, "Theme settings")
- menu?.add(Menu.NONE, SHUFFLE, Menu.NONE, "Shuffle colors")
- menu?.add(Menu.NONE, INVERT, Menu.NONE, "Invert color mapping")
- menu?.add(Menu.NONE, RESET, Menu.NONE, "Reset theme to default")
+ menu?.run {
+ add(Menu.NONE, SETTINGS, Menu.NONE, "Theme settings")
+ add(Menu.NONE, SHUFFLE, Menu.NONE, "Shuffle colors")
+ add(Menu.NONE, RESET, Menu.NONE, "Reset theme to default")
+ }
return true
}
@@ -81,37 +92,13 @@
when (item.itemId) {
SETTINGS -> startActivity(Intent(this, MaterialSettingsActivity::class.java))
SHUFFLE -> {
- val colors = generateColorPalette(currentColors.colors)
- colors.saveColors()
- currentColors.colors = colors
- }
- INVERT -> {
- // Flip all colors
- val newPrimary = currentColors.colors.onPrimary
- val newOnPrimary = currentColors.colors.primary
- val newSecondary = currentColors.colors.onSecondary
- val newOnSecondary = currentColors.colors.secondary
- val colors = ColorPalette(
- primary = newPrimary,
- primaryVariant = currentColors.colors.primaryVariant,
- secondary = newSecondary,
- secondaryVariant = currentColors.colors.secondaryVariant,
- background = currentColors.colors.background,
- surface = currentColors.colors.surface,
- error = currentColors.colors.error,
- onPrimary = newOnPrimary,
- onSecondary = newOnSecondary,
- onBackground = currentColors.colors.onBackground,
- onSurface = currentColors.colors.onSurface,
- onError = currentColors.colors.onError
- )
- colors.saveColors()
- currentColors.colors = colors
+ currentColors.shuffleColors()
+ currentColors.saveColors()
}
RESET -> {
val sharedPreferences = getDefaultSharedPreferences(this)
sharedPreferences.edit().clear().apply()
- currentColors.colors = getColorsFromSharedPreferences()
+ currentColors.getColorsFromSharedPreferences()
}
}
return true
@@ -122,30 +109,41 @@
* not present in the [SharedPreferences], its default value as defined in [ColorPalette]
* will be returned.
*/
- private fun getColorsFromSharedPreferences(): ColorPalette {
- val sharedPreferences = getDefaultSharedPreferences(this)
- val function = ::ColorPalette
- val parametersToSet = function.parameters.mapNotNull { parameter ->
- val savedValue = sharedPreferences.getString(parameter.name, "")
- if (savedValue.isNullOrBlank()) {
- null
- } else {
- val parsedColor = Color(java.lang.Long.parseLong(savedValue, 16))
- parameter to parsedColor
- }
- }.toMap()
- if (parametersToSet.isEmpty()) return ColorPalette()
- return ::ColorPalette.callBy(parametersToSet)
+ private fun CurrentColorPalette.getColorsFromSharedPreferences() {
+ val sharedPreferences = getDefaultSharedPreferences(this@MaterialDemoActivity)
+
+ fun getColorsFromSharedPreferences(isLightTheme: Boolean): ColorPalette {
+ val function = if (isLightTheme) ::lightColorPalette else ::darkColorPalette
+ val parametersToSet = function.parameters.mapNotNull { parameter ->
+ val savedValue = sharedPreferences.getString(parameter.name + isLightTheme, "")
+ if (savedValue.isNullOrBlank()) {
+ null
+ } else {
+ val parsedColor = Color(java.lang.Long.parseLong(savedValue, 16))
+ parameter to parsedColor
+ }
+ }.toMap()
+ return function.callBy(parametersToSet)
+ }
+
+ lightColors = getColorsFromSharedPreferences(true)
+ darkColors = getColorsFromSharedPreferences(false)
}
/**
- * Persists the current [ColorPalette] to [SharedPreferences].
+ * Persists the current [CurrentColorPalette] to [SharedPreferences].
*/
- private fun ColorPalette.saveColors() {
- forEachColorProperty { name, color ->
+ private fun CurrentColorPalette.saveColors() {
+ lightColors.forEachColorProperty { name, color ->
getDefaultSharedPreferences(this@MaterialDemoActivity)
.edit()
- .putString(name, Integer.toHexString(color.toArgb()))
+ .putString(name + true, Integer.toHexString(color.toArgb()))
+ .apply()
+ }
+ darkColors.forEachColorProperty { name, color ->
+ getDefaultSharedPreferences(this@MaterialDemoActivity)
+ .edit()
+ .putString(name + false, Integer.toHexString(color.toArgb()))
.apply()
}
}
@@ -155,22 +153,37 @@
* [ColorPalette.secondary] and [ColorPalette.onSecondary] as dark-on-light or light-on-dark
* pairs.
*/
- private fun generateColorPalette(currentColors: ColorPalette): ColorPalette {
- val (primary, onPrimary) = generateColorPair()
- val (secondary, onSecondary) = generateColorPair()
- return ColorPalette(
- primary = primary,
- primaryVariant = currentColors.primaryVariant,
- secondary = secondary,
- secondaryVariant = currentColors.secondaryVariant,
- background = currentColors.background,
- surface = currentColors.surface,
- error = currentColors.error,
- onPrimary = onPrimary,
- onSecondary = onSecondary,
- onBackground = currentColors.onBackground,
- onSurface = currentColors.onSurface,
- onError = currentColors.onError
+ private fun CurrentColorPalette.shuffleColors() {
+ val (lightPrimary, lightOnPrimary) = generateColorPair(true)
+ val (lightSecondary, lightOnSecondary) = generateColorPair(true)
+ lightColors = lightColorPalette(
+ primary = lightPrimary,
+ primaryVariant = lightColors.primaryVariant,
+ secondary = lightSecondary,
+ secondaryVariant = lightColors.secondaryVariant,
+ background = lightColors.background,
+ surface = lightColors.surface,
+ error = lightColors.error,
+ onPrimary = lightOnPrimary,
+ onSecondary = lightOnSecondary,
+ onBackground = lightColors.onBackground,
+ onSurface = lightColors.onSurface,
+ onError = lightColors.onError
+ )
+ val (darkPrimary, darkOnPrimary) = generateColorPair(false)
+ val (darkSecondary, darkOnSecondary) = generateColorPair(false)
+ darkColors = darkColorPalette(
+ primary = darkPrimary,
+ primaryVariant = darkColors.primaryVariant,
+ secondary = darkSecondary,
+ background = darkColors.background,
+ surface = darkColors.surface,
+ error = darkColors.error,
+ onPrimary = darkOnPrimary,
+ onSecondary = darkOnSecondary,
+ onBackground = darkColors.onBackground,
+ onSurface = darkColors.onSurface,
+ onError = darkColors.onError
)
}
@@ -178,14 +191,13 @@
* Generate a random dark and light color from the palette, and returns either a dark-on-light
* or light-on-dark color pair.
*/
- private fun generateColorPair(): Pair<Color, Color> {
+ private fun generateColorPair(isLightTheme: Boolean): Pair<Color, Color> {
val darkColor = Color(DARK_PALETTE_COLORS.random())
val lightColor = Color(LIGHT_PALETTE_COLORS.random())
- val isMainColorLight = Random.nextBoolean()
- return if (isMainColorLight) {
- (lightColor to darkColor)
+ return if (isLightTheme) {
+ darkColor to lightColor
} else {
- (darkColor to lightColor)
+ lightColor to darkColor
}
}
@@ -199,8 +211,7 @@
companion object {
private const val SETTINGS = 1
private const val SHUFFLE = 2
- private const val INVERT = 3
- private const val RESET = 4
+ private const val RESET = 3
// Colors taken from https://material.io/design/color -> 2014 Material Design color palettes
@@ -465,15 +476,35 @@
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val context = preferenceManager.context
val screen = preferenceManager.createPreferenceScreen(context)
+
+ val light = PreferenceCategory(context).apply {
+ title = "Light colors"
+ screen.addPreference(this)
+ }
// Create new ColorPalette to resolve defaults
- ColorPalette().forEachColorProperty { name, color ->
+ lightColorPalette().forEachColorProperty { name, color ->
val preference = EditTextPreference(context)
- preference.key = name
+ preference.key = name + true
preference.title = name
// set the default value to be the default for ColorPalette
preference.setDefaultValue(Integer.toHexString(color.toArgb()))
preference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()
- screen.addPreference(preference)
+ light.addPreference(preference)
+ }
+
+ val dark = PreferenceCategory(context).apply {
+ title = "Dark colors"
+ screen.addPreference(this)
+ }
+
+ darkColorPalette().forEachColorProperty { name, color ->
+ val preference = EditTextPreference(context)
+ preference.key = name + false
+ preference.title = name
+ // set the default value to be the default for ColorPalette
+ preference.setDefaultValue(Integer.toHexString(color.toArgb()))
+ preference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()
+ dark.addPreference(preference)
}
preferenceScreen = screen
}
@@ -490,7 +521,7 @@
private fun ColorPalette.forEachColorProperty(action: (name: String, color: Color) -> Unit) {
ColorPalette::class.memberProperties.forEach { property ->
val name = property.name
- val color = property.get(this) as Color
+ val color = property.get(this) as? Color ?: return@forEach
action(name, color)
}
-}
\ No newline at end of file
+}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsActivity.kt
index 5fd2c06..109a5e4 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsActivity.kt
@@ -20,7 +20,6 @@
import androidx.compose.unaryPlus
import androidx.ui.core.Text
import androidx.ui.core.dp
-import androidx.ui.graphics.Color
import androidx.ui.layout.Column
import androidx.ui.layout.EdgeInsets
import androidx.ui.layout.Padding
@@ -30,7 +29,6 @@
import androidx.ui.material.samples.RadioButtonSample
import androidx.ui.material.samples.SwitchSample
import androidx.ui.material.samples.TriStateCheckboxSample
-import androidx.ui.material.surface.Surface
class SelectionControlsActivity : MaterialDemoActivity() {
@@ -39,29 +37,27 @@
val headerStyle = (+MaterialTheme.typography()).h6
val padding = EdgeInsets(10.dp)
- Surface(color = Color.White) {
- Padding(padding = padding) {
- Column {
- Text(text = "Checkbox", style = headerStyle)
- Padding(padding = padding) {
- TriStateCheckboxSample()
- }
- Text(text = "Switch", style = headerStyle)
- Padding(padding = padding) {
- SwitchSample()
- }
- Text(text = "RadioButton", style = headerStyle)
- Padding(padding = padding) {
- RadioButtonSample()
- }
- Text(text = "Radio group :: Default usage", style = headerStyle)
- Padding(padding = padding) {
- DefaultRadioGroupSample()
- }
- Text(text = "Radio group :: Custom usage", style = headerStyle)
- Padding(padding = padding) {
- CustomRadioGroupSample()
- }
+ Padding(padding = padding) {
+ Column {
+ Text(text = "Checkbox", style = headerStyle)
+ Padding(padding = padding) {
+ TriStateCheckboxSample()
+ }
+ Text(text = "Switch", style = headerStyle)
+ Padding(padding = padding) {
+ SwitchSample()
+ }
+ Text(text = "RadioButton", style = headerStyle)
+ Padding(padding = padding) {
+ RadioButtonSample()
+ }
+ Text(text = "Radio group :: Default usage", style = headerStyle)
+ Padding(padding = padding) {
+ DefaultRadioGroupSample()
+ }
+ Text(text = "Radio group :: Custom usage", style = headerStyle)
+ Padding(padding = padding) {
+ CustomRadioGroupSample()
}
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SliderActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SliderActivity.kt
index 003923b..00327259 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SliderActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SliderActivity.kt
@@ -18,25 +18,21 @@
import androidx.compose.Composable
import androidx.ui.core.dp
-import androidx.ui.graphics.Color
import androidx.ui.layout.Column
import androidx.ui.layout.EdgeInsets
import androidx.ui.layout.Padding
import androidx.ui.material.samples.SliderSample
import androidx.ui.material.samples.StepsSliderSample
-import androidx.ui.material.surface.Surface
class SliderActivity : MaterialDemoActivity() {
@Composable
override fun materialContent() {
val padding = EdgeInsets(10.dp)
- Surface(color = Color.White) {
- Padding(padding = padding) {
- Column {
- SliderSample()
- StepsSliderSample()
- }
+ Padding(padding = padding) {
+ Column {
+ SliderSample()
+ StepsSliderSample()
}
}
}
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAnimatedCircle.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAnimatedCircle.kt
index 6e22941..b5e6fa9 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAnimatedCircle.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAnimatedCircle.kt
@@ -65,7 +65,7 @@
fun DrawAnimatedCircle(proportions: List<Float>, colors: List<Color>) {
val strokeWidthDp = 5.dp
val paint = +memo { Paint() }
- Transition(definition = CircularTransition, toState = 1) { state ->
+ Transition(definition = CircularTransition, initState = 0, toState = 1) { state ->
Draw { canvas, parentSize ->
val strokeWidth = strokeWidthDp.toPx().value
paint.style = PaintingStyle.stroke
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyTheme.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyTheme.kt
index ff10252..4752bd1 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyTheme.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyTheme.kt
@@ -21,9 +21,9 @@
import androidx.ui.core.em
import androidx.ui.core.sp
import androidx.ui.graphics.Color
-import androidx.ui.material.ColorPalette
import androidx.ui.material.MaterialTheme
import androidx.ui.material.Typography
+import androidx.ui.material.lightColorPalette
import androidx.ui.text.TextStyle
import androidx.ui.text.font.FontFamily
import androidx.ui.text.font.FontWeight
@@ -37,7 +37,7 @@
@Composable
fun RallyTheme(children: @Composable() () -> Unit) {
- val colors = ColorPalette(
+ val colors = lightColorPalette(
primary = rallyGreen,
surface = Color(0xFF26282F),
onSurface = Color.White,
@@ -91,7 +91,7 @@
@Composable
fun RallyDialogThemeOverlay(children: @Composable() () -> Unit) {
- val dialogColors = ColorPalette(
+ val dialogColors = lightColorPalette(
primary = Color.White,
surface = Color(0xFF1E1E1E),
onSurface = Color.White
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ThemeSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ThemeSamples.kt
index 2a3412f..0b66644 100644
--- a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ThemeSamples.kt
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ThemeSamples.kt
@@ -22,11 +22,13 @@
import androidx.ui.core.Text
import androidx.ui.core.sp
import androidx.ui.foundation.ColoredRect
+import androidx.ui.foundation.isSystemInDarkTheme
import androidx.ui.graphics.Color
-import androidx.ui.material.ColorPalette
import androidx.ui.material.FloatingActionButton
import androidx.ui.material.MaterialTheme
import androidx.ui.material.Typography
+import androidx.ui.material.darkColorPalette
+import androidx.ui.material.lightColorPalette
import androidx.ui.text.TextStyle
import androidx.ui.text.font.FontFamily
import androidx.ui.text.font.FontWeight
@@ -34,12 +36,16 @@
@Sampled
@Composable
fun MaterialThemeSample() {
- val colors = ColorPalette(
- primary = Color(0xFF1EB980),
- surface = Color(0xFF26282F),
- onSurface = Color.White
+ val lightColors = lightColorPalette(
+ primary = Color(0xFF1EB980)
)
+ val darkColors = darkColorPalette(
+ primary = Color(0xFF66ffc7)
+ )
+
+ val colors = if (+isSystemInDarkTheme()) darkColors else lightColors
+
val typography = Typography(
h1 = TextStyle(fontFamily = FontFamily("RobotoCondensed"),
fontWeight = FontWeight.W100,
@@ -47,11 +53,11 @@
button = TextStyle(fontFamily = FontFamily("RobotoCondensed"),
fontWeight = FontWeight.W600,
fontSize = 14.sp)
-
)
MaterialTheme(colors = colors, typography = typography) {
- FloatingActionButton("FAB with text style and color from theme", onClick = {})
+ val currentTheme = if ((+MaterialTheme.colors()).isLight) "light" else "dark"
+ FloatingActionButton("FAB with text style and color from $currentTheme theme", onClick = {})
}
}
@@ -65,5 +71,6 @@
@Sampled
@Composable
fun ThemeTextStyleSample() {
- Text(text = "H4 styled text", style = (+MaterialTheme.typography()).h4)
+ val typography = +MaterialTheme.typography()
+ Text(text = "H4 styled text", style = typography.h4)
}
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/TextColorsTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/TextColorsTest.kt
index b973eea..abd4b27 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/TextColorsTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/TextColorsTest.kt
@@ -36,7 +36,7 @@
@Test
fun textColorForBackgroundUsesCorrectValues() {
- val colors = ColorPalette(
+ val colors = lightColorPalette(
primary = Color(0),
onPrimary = Color(1),
secondary = Color(2),
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Color.kt b/ui/ui-material/src/main/java/androidx/ui/material/Color.kt
index f3fa80c..ee7eb9d 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Color.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Color.kt
@@ -27,6 +27,9 @@
/**
* Collection of colors in the [Material color specification]
* [https://material.io/design/color/the-color-system.html#color-theme-creation].
+ *
+ * To create a light set of colors, use [lightColorPalette]
+ * To create a dark set of colors, use [darkColorPalette]
*/
interface ColorPalette {
/**
@@ -86,13 +89,22 @@
* Color used for text and icons displayed on top of the error color.
*/
val onError: Color
+ /**
+ * Whether this ColorPalette is considered as a 'light' or 'dark' set of colors. This affects
+ * default behavior for some components: for example, in a light theme a [TopAppBar] will use
+ * [primary] by default for its background color, when in a dark theme it will use [surface].
+ */
+ val isLight: Boolean
}
/**
* Creates a complete color definition for the [Material color specification]
- * [https://material.io/design/color/the-color-system.html#color-theme-creation].
+ * [https://material.io/design/color/the-color-system.html#color-theme-creation] using the default
+ * light theme values.
+ *
+ * @see darkColorPalette
*/
-fun ColorPalette(
+fun lightColorPalette(
primary: Color = Color(0xFF6200EE),
primaryVariant: Color = Color(0xFF3700B3),
secondary: Color = Color(0xFF03DAC6),
@@ -117,7 +129,45 @@
onSecondary,
onBackground,
onSurface,
- onError
+ onError,
+ true
+)
+
+/**
+ * Creates a complete color definition for the [Material color specification]
+ * [https://material.io/design/color/the-color-system.html#color-theme-creation] using the default
+ * dark theme values.
+ *
+ * @see lightColorPalette
+ */
+fun darkColorPalette(
+ primary: Color = Color(0xFFBB86FC),
+ primaryVariant: Color = Color(0xFF3700B3),
+ secondary: Color = Color(0xFF03DAC6),
+ background: Color = Color(0xFF121212),
+ surface: Color = Color(0xFF121212),
+ error: Color = Color(0xFFCF6679),
+ onPrimary: Color = Color.Black,
+ onSecondary: Color = Color.Black,
+ onBackground: Color = Color.White,
+ onSurface: Color = Color.White,
+ onError: Color = Color.Black
+): ColorPalette = ObservableColorPalette(
+ primary,
+ primaryVariant,
+ secondary,
+ // Secondary and secondary variant are the same in dark mode, as contrast should be
+ // higher so there is no need for the variant.
+ secondary,
+ background,
+ surface,
+ error,
+ onPrimary,
+ onSecondary,
+ onBackground,
+ onSurface,
+ onError,
+ false
)
/**
@@ -146,7 +196,8 @@
onSecondary: Color,
onBackground: Color,
onSurface: Color,
- onError: Color
+ onError: Color,
+ isLight: Boolean
) : ColorPalette {
constructor(colorPalette: ColorPalette) : this(
@@ -161,7 +212,8 @@
onSecondary = colorPalette.onSecondary,
onBackground = colorPalette.onBackground,
onSurface = colorPalette.onSurface,
- onError = colorPalette.onError
+ onError = colorPalette.onError,
+ isLight = colorPalette.isLight
)
override var primary by ObservableColor(primary)
@@ -176,6 +228,7 @@
override var onBackground by ObservableColor(onBackground)
override var onSurface by ObservableColor(onSurface)
override var onError by ObservableColor(onError)
+ override var isLight by ObservableBoolean(isLight)
}
@Model
@@ -187,6 +240,15 @@
}
}
+@Model
+private class ObservableBoolean(var boolean: Boolean) {
+ operator fun getValue(thisObj: Any?, property: KProperty<*>) = boolean
+
+ operator fun setValue(thisObj: Any?, property: KProperty<*>, next: Boolean) {
+ if (boolean != next) boolean = next
+ }
+}
+
/**
* Updates the internal values of the given [ObservableColorPalette] with values from the [other]
* [ColorPalette].
@@ -204,6 +266,7 @@
onBackground = other.onBackground
onSurface = other.onSurface
onError = other.onError
+ isLight = other.isLight
return this
}
@@ -215,9 +278,7 @@
internal fun ProvideColorPalette(colorPalette: ColorPalette, children: @Composable() () -> Unit) {
val palette = when (colorPalette) {
is ObservableColorPalette -> {
- (+memo<ObservableColorPalette> {
- ObservableColorPalette(colorPalette)
- }).updateColorsFrom(colorPalette)
+ (+memo { ObservableColorPalette(colorPalette) }).updateColorsFrom(colorPalette)
}
else -> colorPalette
}
@@ -229,4 +290,4 @@
*
* To retrieve the current value of this ambient, use [MaterialTheme.colors].
*/
-internal val ColorAmbient = Ambient.of { ColorPalette() }
+internal val ColorAmbient = Ambient.of { lightColorPalette() }
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt b/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
index 957ccd2..4ea4cc3 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
@@ -42,7 +42,7 @@
/**
* A floating action button (FAB) is a [Button] to represents the primary action of a screen.
*
- * By default it adds the circle shape, the [FabSize] size and the centering for the content.
+ * By default it uses a circle shape and centers its content.
*
* @sample androidx.ui.material.samples.FloatingActionButtonCustomContent
*
@@ -51,7 +51,7 @@
* @param modifier Modifier to be applied to the button.
* @param onClick will be called when user clicked on the button. The button will be disabled
* when it is null.
- * @param minSize Minimum size of the button. Defaults to [FabSize]
+ * @param minSize Minimum size of the FAB.
* @param shape Defines the Button's shape as well its shadow. When null is provided it uses
* the [Shapes.button] from [ShapeAmbient].
* @param color The background color
@@ -82,7 +82,7 @@
/**
* A floating action button (FAB) is a [Button] to represents the primary action of a screen.
*
- * It draws the [icon] in the center of the FAB with [FabSize] size.
+ * It draws the [icon] in the center of the FAB.
*
* @sample androidx.ui.material.samples.FloatingActionButtonSimple
*
@@ -165,7 +165,7 @@
}
}
-val FabSize = 56.dp
-val ExtendedFabHeight = 48.dp
-val ExtendedFabIconPadding = 12.dp
-val ExtendedFabTextPadding = 20.dp
+private val FabSize = 56.dp
+private val ExtendedFabHeight = 48.dp
+private val ExtendedFabIconPadding = 12.dp
+private val ExtendedFabTextPadding = 20.dp
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt b/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
index eeccfeb..0bc689d 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
@@ -41,7 +41,7 @@
*/
@Composable
fun MaterialTheme(
- colors: ColorPalette = ColorPalette(),
+ colors: ColorPalette = lightColorPalette(),
typography: Typography = Typography(),
children: @Composable() () -> Unit
) {
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
index 65bda9a..d1d6873 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
@@ -93,7 +93,8 @@
color.copy(alpha = BackgroundOpacity),
StrokeCap.butt
)
- Transition(definition = LinearIndeterminateTransition, toState = 1) { state ->
+ Transition(definition = LinearIndeterminateTransition, initState = 0, toState = 1) {
+ state ->
val firstLineHead = state[FirstLineHeadProp]
val firstLineTail = state[FirstLineTailProp]
val secondLineHead = state[SecondLineHeadProp]
@@ -192,7 +193,8 @@
fun CircularProgressIndicator(color: Color = (+MaterialTheme.colors()).primary) {
CircularIndicatorContainer {
val paint = +paint(color, StrokeCap.square)
- Transition(definition = CircularIndeterminateTransition, toState = 1) { state ->
+ Transition(definition = CircularIndeterminateTransition, initState = 0, toState = 1) {
+ state ->
val currentRotation = state[IterationProp]
val baseRotation = state[BaseRotationProp]
diff --git a/ui/ui-platform/api/0.1.0-dev03.txt b/ui/ui-platform/api/0.1.0-dev03.txt
index 7430747..fb841f3 100644
--- a/ui/ui-platform/api/0.1.0-dev03.txt
+++ b/ui/ui-platform/api/0.1.0-dev03.txt
@@ -361,6 +361,10 @@
package androidx.ui.core.pointerinput {
+ public final class HitPathTrackerKt {
+ ctor public HitPathTrackerKt();
+ }
+
public final class MotionEventAdapterKt {
ctor public MotionEventAdapterKt();
}
diff --git a/ui/ui-platform/api/current.txt b/ui/ui-platform/api/current.txt
index 7430747..fb841f3 100644
--- a/ui/ui-platform/api/current.txt
+++ b/ui/ui-platform/api/current.txt
@@ -361,6 +361,10 @@
package androidx.ui.core.pointerinput {
+ public final class HitPathTrackerKt {
+ ctor public HitPathTrackerKt();
+ }
+
public final class MotionEventAdapterKt {
ctor public MotionEventAdapterKt();
}
diff --git a/ui/ui-platform/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-platform/api/public_plus_experimental_0.1.0-dev03.txt
index 7430747..fb841f3 100644
--- a/ui/ui-platform/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-platform/api/public_plus_experimental_0.1.0-dev03.txt
@@ -361,6 +361,10 @@
package androidx.ui.core.pointerinput {
+ public final class HitPathTrackerKt {
+ ctor public HitPathTrackerKt();
+ }
+
public final class MotionEventAdapterKt {
ctor public MotionEventAdapterKt();
}
diff --git a/ui/ui-platform/api/public_plus_experimental_current.txt b/ui/ui-platform/api/public_plus_experimental_current.txt
index 7430747..fb841f3 100644
--- a/ui/ui-platform/api/public_plus_experimental_current.txt
+++ b/ui/ui-platform/api/public_plus_experimental_current.txt
@@ -361,6 +361,10 @@
package androidx.ui.core.pointerinput {
+ public final class HitPathTrackerKt {
+ ctor public HitPathTrackerKt();
+ }
+
public final class MotionEventAdapterKt {
ctor public MotionEventAdapterKt();
}
diff --git a/ui/ui-platform/api/restricted_0.1.0-dev03.txt b/ui/ui-platform/api/restricted_0.1.0-dev03.txt
index 7430747..fb841f3 100644
--- a/ui/ui-platform/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-platform/api/restricted_0.1.0-dev03.txt
@@ -361,6 +361,10 @@
package androidx.ui.core.pointerinput {
+ public final class HitPathTrackerKt {
+ ctor public HitPathTrackerKt();
+ }
+
public final class MotionEventAdapterKt {
ctor public MotionEventAdapterKt();
}
diff --git a/ui/ui-platform/api/restricted_current.txt b/ui/ui-platform/api/restricted_current.txt
index 7430747..fb841f3 100644
--- a/ui/ui-platform/api/restricted_current.txt
+++ b/ui/ui-platform/api/restricted_current.txt
@@ -361,6 +361,10 @@
package androidx.ui.core.pointerinput {
+ public final class HitPathTrackerKt {
+ ctor public HitPathTrackerKt();
+ }
+
public final class MotionEventAdapterKt {
ctor public MotionEventAdapterKt();
}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
index baef999..08db131 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
@@ -344,6 +344,8 @@
override val repaintBoundary: RepaintBoundaryNode? get() = this
}
+// TODO(b/143778512): Why are the properties vars? Shouldn't they be vals defined in the
+// constructor such that they both must be provided?
/**
* Backing node for handling pointer events.
*/
@@ -353,11 +355,13 @@
*/
var pointerInputHandler: PointerInputHandler = { event, _, _ -> event }
- // TODO(b/142486858): Should cancelHandler be called when the PointerInputNode is removed
- // from the hierarchy?
/**
- * Invoked when Android passes an ACTION_CANCEL event to the [AndroidComposeView.onTouchEvent]
- * method.
+ * Invoked to notify the handler that no more calls to pointerInputHandler will be made, until
+ * at least new pointers exist. This can occur for a few reasons:
+ * 1. Android dispatches ACTION_CANCEL to [AndroidComposeView.onTouchEvent].
+ * 2. The PointerInputNode has been removed from the compose hierarchy.
+ * 3. The PointerInputNode no longer has any descendant [LayoutNode]s and therefore does not
+ * know what region of the screen it should virtually exist in.
*/
var cancelHandler: () -> Unit = { }
}
@@ -851,7 +855,8 @@
/**
* The position of the inner layout node content
*/
- val contentPosition: IntPxPosition get() = innerLayoutNodeWrapper.position
+ var contentPosition: IntPxPosition = IntPxPosition.Origin
+ private set
/**
* The size of the inner layout node content
@@ -1027,6 +1032,12 @@
var position = Origin
/**
+ * Calculate and set the content position based on the given offset and any internal
+ * positioning.
+ */
+ abstract fun calculateContentPosition(offset: IntPxPosition)
+
+ /**
* Assigns a layout size to this [LayoutNodeWrapper] given the assigned innermost size
* from the call to [MeasureScope.layout]. Assigns and returns [modifiedSize].
*/
@@ -1034,6 +1045,7 @@
}
private inner class InnerPlaceable : LayoutNodeWrapper(), DensityScope {
+
override fun measure(constraints: Constraints): Placeable {
val layoutResult = measureBlocks.measure(measureScope, layoutChildren, constraints)
handleLayoutResult(layoutResult)
@@ -1060,8 +1072,10 @@
override fun performPlace(position: IntPxPosition) {
isPlaced = true
- if (position != this.position) {
- this.position = position
+ this.position = position
+ val oldContentPosition = contentPosition
+ layoutNodeWrapper.calculateContentPosition(IntPxPosition.Origin)
+ if (oldContentPosition != contentPosition) {
owner?.onPositionChange(this@LayoutNode)
}
placeChildren()
@@ -1074,7 +1088,13 @@
return innermostSize
}
- override fun get(line: AlignmentLine): IntPx? = calculateAlignmentLines()[line]
+ override operator fun get(line: AlignmentLine): IntPx? {
+ return calculateAlignmentLines()[line]
+ }
+
+ override fun calculateContentPosition(offset: IntPxPosition) {
+ contentPosition = position + offset
+ }
}
private inner class ModifiedLayoutNode(
@@ -1145,15 +1165,20 @@
private set
override fun performPlace(position: IntPxPosition) {
+ this.position = position
val placeable = measuredPlaceable ?: error("Placeable not measured")
- this.position = with(layoutModifier) {
- measureScope.modifyPosition(position, placeable.size, size)
+ val relativePosition = with(layoutModifier) {
+ measureScope.modifyPosition(placeable.size, size)
}
- placeable.place(this.position)
+ placeable.place(relativePosition)
}
- override fun get(line: AlignmentLine): IntPx? = with(layoutModifier) {
- measureScope.modifyAlignmentLine(line, wrapped[line])
+ override operator fun get(line: AlignmentLine): IntPx? = with(layoutModifier) {
+ var lineValue = measureScope.modifyAlignmentLine(line, wrapped[line])
+ if (lineValue != null) {
+ lineValue += if (line.horizontal) wrapped.position.y else wrapped.position.x
+ }
+ lineValue
}
override fun layoutSize(innermostSize: IntPxSize): IntPxSize = with(layoutModifier) {
@@ -1162,6 +1187,10 @@
size = it
}
}
+
+ override fun calculateContentPosition(offset: IntPxPosition) {
+ wrapped.calculateContentPosition(position + offset)
+ }
}
internal val coordinates: LayoutCoordinates = LayoutNodeCoordinates(this)
@@ -1259,8 +1288,9 @@
layoutChildren.forEach { child ->
if (!child.isPlaced) return@forEach
child.alignmentLines.entries.forEach { (childLine, linePosition) ->
+ val offset = child.contentPosition
val linePositionInContainer = linePosition +
- if (childLine.horizontal) child.y else child.x
+ if (childLine.horizontal) offset.y else offset.x
// If the line was already provided by a previous child, merge the values.
alignmentLines[childLine] = if (childLine in alignmentLines) {
childLine.merge(
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/SemanticsTreeNodeImpl.kt b/ui/ui-platform/src/main/java/androidx/ui/core/SemanticsTreeNodeImpl.kt
index 66344f6..a8f9765 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/SemanticsTreeNodeImpl.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/SemanticsTreeNodeImpl.kt
@@ -81,7 +81,7 @@
)
parent?.addChild(wrapper)
nodes.add(wrapper)
- currentParent = parent
+ currentParent = wrapper
}
currentNode.visitChildren {
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/HitPathTracker.kt b/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/HitPathTracker.kt
index 945fb38..7aecd18 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/HitPathTracker.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/HitPathTracker.kt
@@ -18,18 +18,16 @@
import androidx.ui.core.IntPxPosition
import androidx.ui.core.IntPxSize
-import androidx.ui.core.LayoutNode
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerInputChange
import androidx.ui.core.PointerInputNode
import androidx.ui.core.hasNoLayoutDescendants
import androidx.ui.core.ipx
-import androidx.ui.core.positionRelativeToRoot
import androidx.ui.core.isAttached
+import androidx.ui.core.positionRelativeToRoot
import androidx.ui.core.visitLayoutChildren
-import java.lang.IllegalStateException
-import kotlin.math.min
import kotlin.math.max
+import kotlin.math.min
/**
* Organizes pointers and the [PointerInputNode]s that they hit into a hierarchy such that
@@ -148,6 +146,10 @@
root.refreshPositionInformation(additionalPointerOffset)
}
+ // TODO(b/145305910): removeDetachedPointerInputNodes and
+ // removePointerInputNodesWithNoLayoutNodeDescendants should not wait to be called during
+ // dispatching of pointer input events. Changing PointerInputNodes to be PointerInputModifiers
+ // will fix this for us.
/**
* Convenience method that removes PointerInputNodes that are no longer valid and refreshes the
* offset information for those that are.
@@ -165,8 +167,7 @@
// TODO(shepshapard): This really should be private. Currently some tests inspect the node's
// directly which is unnecessary and bad practice.
internal class Node(
- val pointerInputNode: PointerInputNode? = null,
- val layoutNode: LayoutNode? = null
+ val pointerInputNode: PointerInputNode? = null
) {
val pointerIds: MutableSet<Int> = mutableSetOf()
val children: MutableSet<Node> = mutableSetOf()
@@ -193,11 +194,13 @@
}
if (relevantChanges.isEmpty()) {
- throw IllegalStateException("Currently, HitPathTracker is operating under the " +
- "assumption that there should never be a circumstance in which it is tracking" +
- " a PointerInputNode where when it receives pointerInputChanges, none are " +
- "relevant to that PointerInputNode. This assumption may not hold true in " +
- "the future, but currently it assumes it can abide by this contract.")
+ throw IllegalStateException(
+ "Currently, HitPathTracker is operating under the assumption that there should " +
+ "never be a circumstance in which it is tracking a PointerInputNode " +
+ "where when it receives pointerInputChanges, none are relevant to that " +
+ "PointerInputNode. This assumption may not hold true in the future, but " +
+ "currently it assumes it can abide by this contract."
+ )
}
// For each relevant change:
@@ -253,26 +256,30 @@
children.clear()
}
- // TODO(b/142486858): Should cancel events be dispatched to PointerInputNodes that have been
- // removed from the tree?
fun removeDetachedPointerInputNodes() {
- children.removeAll {
- it.pointerInputNode != null && !it.pointerInputNode.isAttached()
- }
- children.forEach {
- it.removeDetachedPointerInputNodes()
- }
+ children.removeAndProcess(
+ removeIf = {
+ it.pointerInputNode != null && !it.pointerInputNode.isAttached()
+ },
+ ifRemoved = {
+ it.dispatchCancel()
+ },
+ ifKept = {
+ it.removeDetachedPointerInputNodes()
+ })
}
- // TODO(shepshapard): Not sure if this functionality should exist. The question will be moot
- // when/if PointerInputNodes are converted into modifiers.
fun removePointerInputNodesWithNoLayoutNodeDescendants() {
- children.removeAll {
- it.pointerInputNode != null && it.pointerInputNode.hasNoLayoutDescendants()
- }
- children.forEach {
- it.removePointerInputNodesWithNoLayoutNodeDescendants()
- }
+ children.removeAndProcess(
+ removeIf = {
+ it.pointerInputNode != null && it.pointerInputNode.hasNoLayoutDescendants()
+ },
+ ifRemoved = {
+ it.dispatchCancel()
+ },
+ ifKept = {
+ it.removePointerInputNodesWithNoLayoutNodeDescendants()
+ })
}
fun removePointerId(pointerId: Int) {
@@ -353,3 +360,21 @@
}
}
}
+
+private fun <T> MutableIterable<T>.removeAndProcess(
+ removeIf: (T) -> Boolean,
+ ifRemoved: (T) -> Unit,
+ ifKept: (T) -> Unit
+) {
+ with(iterator()) {
+ while (hasNext()) {
+ val next = next()
+ if (removeIf(next)) {
+ remove()
+ ifRemoved(next)
+ } else {
+ ifKept(next)
+ }
+ }
+ }
+}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt b/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt
index 0b04b15..a1ba823 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt
@@ -81,8 +81,6 @@
}
}
- // TODO(b/142486858): It seems likely that removed PointerInputNodes should not have their
- // cancelHandlers called. Investigate this.
/**
* Responds appropriately to Android ACTION_CANCEL events.
*
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
index b7f97ab..9701856 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
@@ -43,6 +43,7 @@
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.inOrder
+import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.spy
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
@@ -901,33 +902,49 @@
}
@Test
- fun removeDetachedPointerInputNodes_complexNothingDetached_nothingRemoved() {
+ fun removeDetachedPointerInputNodes_complexNothingDetached_nothingRemovedNoCancelsCalled() {
// Arrange.
- val pin1 = PointerInputNode()
+ val neverCalled: () -> Unit = spy {}
- val pin2 = PointerInputNode()
- val pin3 = PointerInputNode().apply {
- emitInsertAt(0, pin2)
+ val pin1 = PointerInputNode().apply {
+ this.cancelHandler = neverCalled
}
- val pin4 = PointerInputNode()
+ val pin2 = PointerInputNode().apply {
+ this.cancelHandler = neverCalled
+ }
+ val pin3 = PointerInputNode().apply {
+ emitInsertAt(0, pin2)
+ this.cancelHandler = neverCalled
+ }
+
+ val pin4 = PointerInputNode().apply {
+ this.cancelHandler = neverCalled
+ }
val pin5 = PointerInputNode().apply {
emitInsertAt(0, pin4)
+ this.cancelHandler = neverCalled
}
val pin6 = PointerInputNode().apply {
emitInsertAt(0, pin5)
+ this.cancelHandler = neverCalled
}
- val pin7 = PointerInputNode()
- val pin8 = PointerInputNode()
+ val pin7 = PointerInputNode().apply {
+ this.cancelHandler = neverCalled
+ }
+ val pin8 = PointerInputNode().apply {
+ this.cancelHandler = neverCalled
+ }
val layoutNode = LayoutNode().apply {
emitInsertAt(0, pin7)
emitInsertAt(1, pin8)
}
val pin9 = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ this.cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, pin1)
@@ -978,33 +995,48 @@
})
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verifyNoMoreInteractions(neverCalled)
}
// compositionRoot, root -> middle -> leaf
@Test
- fun removeDetachedPointerInputNodes_1PathRootDetached_fullPathRemoved() {
- val leaf = PointerInputNode()
+ fun removeDetachedPointerInputNodes_1PathRootDetached_allRemovedAndCorrectCancels() {
+ val leaf = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle = PointerInputNode().apply {
emitInsertAt(0, leaf)
+ cancelHandler = spy {}
}
val root = PointerInputNode().apply {
emitInsertAt(0, middle)
+ cancelHandler = spy {}
}
hitResult.addHitPath(0, listOf(root, middle, leaf))
hitResult.removeDetachedPointerInputNodes()
assertThat(areEqual(hitResult.root, Node())).isTrue()
+ inOrder(leaf.cancelHandler, middle.cancelHandler, root.cancelHandler) {
+ verify(leaf.cancelHandler).invoke()
+ verify(middle.cancelHandler).invoke()
+ verify(root.cancelHandler).invoke()
+ }
}
// compositionRoot -> root, middle -> child
@Test
- fun removeDetachedPointerInputNodes_1PathMiddleDetached_itAndAncestorsRemoved() {
- val child = PointerInputNode()
+ fun removeDetachedPointerInputNodes_1PathMiddleDetached_removesAndCancelsCorrect() {
+ val child = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle = PointerInputNode().apply {
emitInsertAt(0, child)
+ cancelHandler = spy {}
}
- val root = PointerInputNode()
+ val root = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
compositionRoot.add(root)
hitResult.addHitPath(0, listOf(root, middle, child))
@@ -1017,15 +1049,25 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(child.cancelHandler, middle.cancelHandler) {
+ verify(child.cancelHandler).invoke()
+ verify(middle.cancelHandler).invoke()
+ }
+ verify(root.cancelHandler, never()).invoke()
}
// compositionRoot -> root -> middle, leaf
@Test
- fun removeDetachedPointerInputNodes_1PathLeafDetached_justLeafRemoved() {
- val leaf = PointerInputNode()
- val middle = PointerInputNode()
+ fun removeDetachedPointerInputNodes_1PathLeafDetached_removesAndCancelsCorrect() {
+ val leaf = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val root = PointerInputNode().apply {
emitInsertAt(0, middle)
+ cancelHandler = spy {}
}
compositionRoot.add(root)
hitResult.addHitPath(0, listOf(root, middle, leaf))
@@ -1042,35 +1084,52 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(leaf.cancelHandler).invoke()
+ verifyNoMoreInteractions(middle.cancelHandler, root.cancelHandler)
}
// compositionRoot -> root1 -> middle1 -> leaf1
// compositionRoot -> root2 -> middle2 -> leaf2
// compositionRoot, root3 -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots1Detached_correctRootAndAncestorsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots1Detached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = neverCalled
}
val root1 = PointerInputNode().apply {
emitInsertAt(0, middle1)
+ cancelHandler = neverCalled
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
emitInsertAt(0, middle2)
+ cancelHandler = neverCalled
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = spy {}
}
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = spy {}
}
compositionRoot.emitInsertAt(0, root1)
@@ -1104,33 +1163,55 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf3.cancelHandler, middle3.cancelHandler, root3.cancelHandler) {
+ verify(leaf3.cancelHandler).invoke()
+ verify(middle3.cancelHandler).invoke()
+ verify(root3.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root1, middle1 -> leaf1
// compositionRoot -> root2 -> middle2 -> leaf2
// compositionRoot -> root3 -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots1MiddleDetached_correctMiddleAndAncestorsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots1MiddleDetached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
- val root1 = PointerInputNode()
+ val root1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
emitInsertAt(0, middle2)
+ cancelHandler = neverCalled
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root1)
@@ -1168,33 +1249,54 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root1 -> middle1 -> leaf1
// compositionRoot -> root2 -> middle2, leaf2
// compositionRoot -> root3 -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots1LeafDetached_correctLeafRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots1LeafDetached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = neverCalled
}
val root1 = PointerInputNode().apply {
emitInsertAt(0, middle1)
+ cancelHandler = neverCalled
}
- val leaf2 = PointerInputNode()
- val middle2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val root2 = PointerInputNode().apply {
emitInsertAt(0, middle2)
+ cancelHandler = neverCalled
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root1)
@@ -1235,35 +1337,52 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(leaf2.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
// compositionRoot, root1 -> middle1 -> leaf1
// compositionRoot -> root2 -> middle2 -> leaf2
// compositionRoot, root3 -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots2Detached_correct2RootsAndAncestorsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots2Detached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
emitInsertAt(0, middle1)
+ cancelHandler = spy {}
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
emitInsertAt(0, middle2)
+ cancelHandler = neverCalled
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = spy {}
}
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = spy {}
}
compositionRoot.emitInsertAt(0, root2)
@@ -1287,31 +1406,60 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler, root1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ verify(root1.cancelHandler).invoke()
+ }
+ inOrder(leaf3.cancelHandler, middle3.cancelHandler, root3.cancelHandler) {
+ verify(leaf3.cancelHandler).invoke()
+ verify(middle3.cancelHandler).invoke()
+ verify(root3.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root1, middle1 -> leaf1
// compositionRoot -> root2, middle2 -> leaf2
// compositionRoot -> root3 -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots2MiddlesDetached_correct2NodesAndAncestorsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots2MiddlesDetached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
- val root1 = PointerInputNode()
+ val root1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = spy {}
}
- val root2 = PointerInputNode()
+ val root2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root1)
@@ -1343,31 +1491,58 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ }
+ inOrder(leaf2.cancelHandler, middle2.cancelHandler) {
+ verify(leaf2.cancelHandler).invoke()
+ verify(middle2.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root1 -> middle1 -> leaf1
// compositionRoot -> root2 -> middle2, leaf2
// compositionRoot -> root3 -> middle3, leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots2LeafsDetached_correct2LeafsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots2LeafsDetached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = neverCalled
}
val root1 = PointerInputNode().apply {
emitInsertAt(0, middle1)
+ cancelHandler = neverCalled
}
- val leaf2 = PointerInputNode()
- val middle2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val root2 = PointerInputNode().apply {
emitInsertAt(0, middle2)
+ cancelHandler = neverCalled
}
- val leaf3 = PointerInputNode()
- val middle3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root1)
@@ -1405,35 +1580,50 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(leaf2.cancelHandler).invoke()
+ verify(leaf3.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
// compositionRoot, root1 -> middle1 -> leaf1
// compositionRoot, root2 -> middle2 -> leaf2
// compositionRoot, root3 -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots3Detached_all3RootsAndAncestorsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots3Detached_allRemovedAndCancelsCorrect() {
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
emitInsertAt(0, middle1)
+ cancelHandler = spy {}
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = spy {}
}
val root2 = PointerInputNode().apply {
emitInsertAt(0, middle2)
+ cancelHandler = spy {}
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = spy {}
}
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = spy {}
}
hitResult.addHitPath(3, listOf(root1, middle1, leaf1))
@@ -1445,30 +1635,63 @@
val expectedRoot = Node()
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler, root1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ verify(root1.cancelHandler).invoke()
+ }
+ inOrder(leaf2.cancelHandler, middle2.cancelHandler, root2.cancelHandler) {
+ verify(leaf2.cancelHandler).invoke()
+ verify(middle2.cancelHandler).invoke()
+ verify(root2.cancelHandler).invoke()
+ }
+ inOrder(leaf3.cancelHandler, middle3.cancelHandler, root3.cancelHandler) {
+ verify(leaf3.cancelHandler).invoke()
+ verify(middle3.cancelHandler).invoke()
+ verify(root3.cancelHandler).invoke()
+ }
}
// compositionRoot -> root1, middle1 -> leaf1
// compositionRoot -> root2, middle2 -> leaf2
// compositionRoot -> root3, middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots3MiddlesDetached_all3MiddlesAndAncestorsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots3MiddlesDetached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
- val root1 = PointerInputNode()
+ val root1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = spy {}
}
- val root2 = PointerInputNode()
+ val root2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = spy {}
}
- val root3 = PointerInputNode()
+ val root3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
compositionRoot.emitInsertAt(0, root1)
compositionRoot.emitInsertAt(1, root2)
@@ -1493,29 +1716,60 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ }
+ inOrder(leaf2.cancelHandler, middle2.cancelHandler) {
+ verify(leaf2.cancelHandler).invoke()
+ verify(middle2.cancelHandler).invoke()
+ }
+ inOrder(leaf3.cancelHandler, middle3.cancelHandler) {
+ verify(leaf3.cancelHandler).invoke()
+ verify(middle3.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root1 -> middle1, leaf1
// compositionRoot -> root2 -> middle2, leaf2
// compositionRoot -> root3 -> middle3, leaf3
@Test
- fun removeDetachedPointerInputNodes_3Roots3LeafsDetached_all3LeafsRemoved() {
- val leaf1 = PointerInputNode()
- val middle1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3Roots3LeafsDetached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val root1 = PointerInputNode().apply {
emitInsertAt(0, middle1)
+ cancelHandler = neverCalled
}
- val leaf2 = PointerInputNode()
- val middle2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val root2 = PointerInputNode().apply {
emitInsertAt(0, middle2)
+ cancelHandler = neverCalled
}
- val leaf3 = PointerInputNode()
- val middle3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root1)
@@ -1550,31 +1804,52 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(leaf1.cancelHandler).invoke()
+ verify(leaf2.cancelHandler).invoke()
+ verify(leaf3.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
// compositionRoot, root1 -> middle1 -> leaf1
// compositionRoot -> root2, middle2, leaf2
// compositionRoot -> root3 -> middle3, leaf3
@Test
- fun removeDetachedPointerInputNodes_3RootsStaggeredDetached_correctPathsRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_3RootsStaggeredDetached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
emitInsertAt(0, middle1)
+ cancelHandler = spy {}
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = spy {}
}
- val root2 = PointerInputNode()
+ val root2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
- val leaf3 = PointerInputNode()
- val middle3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val middle3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val root3 = PointerInputNode().apply {
emitInsertAt(0, middle3)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root2)
@@ -1599,6 +1874,17 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler, root1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ verify(root1.cancelHandler).invoke()
+ }
+ inOrder(leaf2.cancelHandler, middle2.cancelHandler) {
+ verify(leaf2.cancelHandler).invoke()
+ verify(middle2.cancelHandler).invoke()
+ }
+ verify(leaf3.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
// compositionRoot, root ->
@@ -1606,20 +1892,29 @@
// layoutNode -> middle2 -> leaf2
// layoutNode -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_rootWith3MiddlesDetached_allRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_rootWith3MiddlesDetached_allRemovedAndCorrectCancels() {
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = spy {}
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = spy {}
}
val layoutNode = LayoutNode().apply {
@@ -1630,6 +1925,7 @@
val root = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = spy {}
}
hitResult.addHitPath(3, listOf(root, middle1, leaf1))
@@ -1641,6 +1937,21 @@
val expectedRoot = Node()
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler, root.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ verify(root.cancelHandler).invoke()
+ }
+ inOrder(leaf2.cancelHandler, middle2.cancelHandler, root.cancelHandler) {
+ verify(leaf2.cancelHandler).invoke()
+ verify(middle2.cancelHandler).invoke()
+ verify(root.cancelHandler).invoke()
+ }
+ inOrder(leaf3.cancelHandler, middle3.cancelHandler, root.cancelHandler) {
+ verify(leaf3.cancelHandler).invoke()
+ verify(middle3.cancelHandler).invoke()
+ verify(root.cancelHandler).invoke()
+ }
}
// compositionRoot -> root ->
@@ -1648,20 +1959,32 @@
// layoutNode -> middle2 -> leaf2
// layoutNode, middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_rootWith3Middles1Detached_correctMiddleRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_rootWith3Middles1Detached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = neverCalled
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = neverCalled
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = spy {}
}
val layoutNode = LayoutNode().apply {
@@ -1671,6 +1994,7 @@
val root = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root)
@@ -1702,6 +2026,11 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf3.cancelHandler, middle3.cancelHandler) {
+ verify(leaf3.cancelHandler).invoke()
+ verify(middle3.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root ->
@@ -1709,20 +2038,32 @@
// layoutNode, middle2 -> leaf2
// layoutNode -> middle3 -> leaf3
@Test
- fun removeDetachedPointerInputNodes_rootWith3Middles2Detached_correctMiddlesRemoved() {
- val leaf1 = PointerInputNode()
+ fun removeDetachedPointerInputNodes_rootWith3Middles2Detached_removesAndCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = spy {}
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = neverCalled
}
val layoutNode = LayoutNode().apply {
@@ -1731,6 +2072,7 @@
val root = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root)
@@ -1756,6 +2098,15 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ }
+ inOrder(leaf2.cancelHandler, middle2.cancelHandler) {
+ verify(leaf2.cancelHandler).invoke()
+ verify(middle2.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root ->
@@ -1764,25 +2115,38 @@
// layoutNode, middle3 -> leaf3
@Test
fun removeDetachedPointerInputNodes_rootWith3MiddlesAllDetached_allMiddlesRemoved() {
- val leaf1 = PointerInputNode()
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle1 = PointerInputNode().apply {
emitInsertAt(0, leaf1)
+ cancelHandler = spy {}
}
- val leaf2 = PointerInputNode()
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle2 = PointerInputNode().apply {
emitInsertAt(0, leaf2)
+ cancelHandler = spy {}
}
- val leaf3 = PointerInputNode()
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val middle3 = PointerInputNode().apply {
emitInsertAt(0, leaf3)
+ cancelHandler = spy {}
}
val layoutNode = LayoutNode()
val root = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root)
@@ -1802,6 +2166,19 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ inOrder(leaf1.cancelHandler, middle1.cancelHandler) {
+ verify(leaf1.cancelHandler).invoke()
+ verify(middle1.cancelHandler).invoke()
+ }
+ inOrder(leaf2.cancelHandler, middle2.cancelHandler) {
+ verify(leaf2.cancelHandler).invoke()
+ verify(middle2.cancelHandler).invoke()
+ }
+ inOrder(leaf3.cancelHandler, middle3.cancelHandler) {
+ verify(leaf3.cancelHandler).invoke()
+ verify(middle3.cancelHandler).invoke()
+ }
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root -> middle ->
@@ -1810,9 +2187,18 @@
// layoutNode -> leaf3
@Test
fun removeDetachedPointerInputNodes_middleWith3Leafs1Detached_correctLeafRemoved() {
- val leaf1 = PointerInputNode()
- val leaf2 = PointerInputNode()
- val leaf3 = PointerInputNode()
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
val layoutNode = LayoutNode().apply {
emitInsertAt(0, leaf1)
@@ -1821,10 +2207,12 @@
val middle = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
val root = PointerInputNode().apply {
emitInsertAt(0, middle)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root)
@@ -1855,6 +2243,8 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(leaf2.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root -> middle ->
@@ -1863,9 +2253,18 @@
// layoutNode, leaf3
@Test
fun removeDetachedPointerInputNodes_middleWith3Leafs2Detached_correctLeafsRemoved() {
- val leaf1 = PointerInputNode()
- val leaf2 = PointerInputNode()
- val leaf3 = PointerInputNode()
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = neverCalled
+ }
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val layoutNode = LayoutNode().apply {
emitInsertAt(0, leaf2)
@@ -1873,10 +2272,12 @@
val middle = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
val root = PointerInputNode().apply {
emitInsertAt(0, middle)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root)
@@ -1904,6 +2305,9 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(leaf1.cancelHandler).invoke()
+ verify(leaf3.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
// compositionRoot -> root -> middle ->
@@ -1912,18 +2316,29 @@
// layoutNode, leaf3
@Test
fun removeDetachedPointerInputNodes_middleWith3LeafsAllDetached_allLeafsRemoved() {
- val leaf1 = PointerInputNode()
- val leaf2 = PointerInputNode()
- val leaf3 = PointerInputNode()
+
+ val neverCalled: () -> Unit = spy {}
+
+ val leaf1 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val leaf2 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
+ val leaf3 = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val layoutNode = LayoutNode()
val middle = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
val root = PointerInputNode().apply {
emitInsertAt(0, middle)
+ cancelHandler = neverCalled
}
compositionRoot.emitInsertAt(0, root)
@@ -1948,6 +2363,10 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(leaf1.cancelHandler).invoke()
+ verify(leaf2.cancelHandler).invoke()
+ verify(leaf3.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
@Test
@@ -1962,27 +2381,32 @@
// PointerInputNode
@Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_justPin_pinRemoved() {
- val pointerInputNode = PointerInputNode()
- hitResult.addHitPath(0, listOf(pointerInputNode))
-
- hitResult.removePointerInputNodesWithNoLayoutNodeDescendants()
-
- assertThat(areEqual(hitResult.root, Node())).isTrue()
- }
-
- // PointerInputNode -> DrawNode
- @Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_dnInPin_pinRemoved() {
- val drawNode = DrawNode()
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_justPin_pinRemovedCancelCalledOnce() {
val pointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, drawNode)
+ cancelHandler = spy {}
}
hitResult.addHitPath(0, listOf(pointerInputNode))
hitResult.removePointerInputNodesWithNoLayoutNodeDescendants()
assertThat(areEqual(hitResult.root, Node())).isTrue()
+ verify(pointerInputNode.cancelHandler).invoke()
+ }
+
+ // PointerInputNode -> DrawNode
+ @Test
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_dnInPin_pinRemovedCancelCalledOnce() {
+ val drawNode = DrawNode()
+ val pointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, drawNode)
+ cancelHandler = spy {}
+ }
+ hitResult.addHitPath(0, listOf(pointerInputNode))
+
+ hitResult.removePointerInputNodesWithNoLayoutNodeDescendants()
+
+ assertThat(areEqual(hitResult.root, Node())).isTrue()
+ verify(pointerInputNode.cancelHandler).invoke()
}
// PointerInputNode -> SemanticsNode
@@ -1991,54 +2415,69 @@
val semanticsNode = SemanticsComponentNode()
val pointerInputNode = PointerInputNode().apply {
emitInsertAt(0, semanticsNode)
+ cancelHandler = spy {}
}
hitResult.addHitPath(0, listOf(pointerInputNode))
hitResult.removePointerInputNodesWithNoLayoutNodeDescendants()
assertThat(areEqual(hitResult.root, Node())).isTrue()
+ verify(pointerInputNode.cancelHandler).invoke()
}
// PointerInputNode A -> PointerInputNode B -> SemanticsNode
@Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_smInPinInPin_pinsRemoved() {
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_smInPinInPin_removesAndCancelsCorrect() {
val semanticsNode = SemanticsComponentNode()
val pointerInputNodeB = PointerInputNode().apply {
emitInsertAt(0, semanticsNode)
+ cancelHandler = spy {}
}
val pointerInputNodeA = PointerInputNode().apply {
emitInsertAt(0, pointerInputNodeB)
+ cancelHandler = spy {}
}
hitResult.addHitPath(0, listOf(pointerInputNodeA, pointerInputNodeB))
hitResult.removePointerInputNodesWithNoLayoutNodeDescendants()
assertThat(areEqual(hitResult.root, Node())).isTrue()
+ inOrder(pointerInputNodeB.cancelHandler, pointerInputNodeA.cancelHandler) {
+ verify(pointerInputNodeB.cancelHandler).invoke()
+ verify(pointerInputNodeA.cancelHandler).invoke()
+ }
}
// PointerInputNode A -> PointerInputNode B -> DrawNode
@Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_dnInPinInPin_pisnRemoved() {
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_dnInPinInPin_removesAndCancelsCorrect() {
val drawnode = DrawNode()
val pointerInputNodeB = PointerInputNode().apply {
emitInsertAt(0, drawnode)
+ cancelHandler = spy {}
}
val pointerInputNodeA = PointerInputNode().apply {
emitInsertAt(0, pointerInputNodeB)
+ cancelHandler = spy {}
}
hitResult.addHitPath(0, listOf(pointerInputNodeA, pointerInputNodeB))
hitResult.removePointerInputNodesWithNoLayoutNodeDescendants()
assertThat(areEqual(hitResult.root, Node())).isTrue()
+ inOrder(pointerInputNodeB.cancelHandler, pointerInputNodeA.cancelHandler) {
+ verify(pointerInputNodeB.cancelHandler).invoke()
+ verify(pointerInputNodeA.cancelHandler).invoke()
+ }
}
// PointerInputNode -> LayoutNode
@Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_pinWithLn_nothingRemoved() {
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_pinWithLn_noRemovesOrCancels() {
val layoutNode = LayoutNode(0, 0, 100, 100)
val pointerInputNode = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = spy {}
}
hitResult.addHitPath(0, listOf(pointerInputNode))
@@ -2048,17 +2487,23 @@
children.add(Node(pointerInputNode).apply { pointerIds.add(0) })
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(pointerInputNode.cancelHandler, never()).invoke()
}
// PointerInputNode A -> PointerInputNode B -> LayoutNode
@Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_lnInPinInPin_nothingRemoved() {
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_lnInPinInPin_noRemovesOrCancels() {
+
+ val neverCalled: () -> Unit = spy {}
+
val layoutNode = LayoutNode(0, 0, 100, 100)
val pointerInputNodeB = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
val pointerInputNodeA = PointerInputNode().apply {
emitInsertAt(0, pointerInputNodeB)
+ cancelHandler = neverCalled
}
hitResult.addHitPath(0, listOf(pointerInputNodeA, pointerInputNodeB))
@@ -2074,17 +2519,21 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(neverCalled, never()).invoke()
}
// PointerInputNode A -> LayoutNode -> PointerInputNode B
@Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_PinInLnInPin_childPinRemoved() {
- val pointerInputNodeB = PointerInputNode()
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_PinInLnInPin_removesAndCancelsCorrect() {
+ val pointerInputNodeB = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val layoutNode = LayoutNode(0, 0, 100, 100).apply {
emitInsertAt(0, pointerInputNodeB)
}
val pointerInputNodeA = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = spy {}
}
hitResult.addHitPath(0, listOf(pointerInputNodeA, pointerInputNodeB))
@@ -2097,20 +2546,29 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(pointerInputNodeB.cancelHandler).invoke()
+ verify(pointerInputNodeA.cancelHandler, never()).invoke()
}
// PointerInputNode A -> PointerInputNode B -> LayoutNode
// PointerInputNode A -> PointerInputNode C
@Test
- fun removePointerInputNodesWithNoLayoutNodeDescendants_2BranchesOneHasLn_otherBranchRemoved() {
+ fun removePointerInputNodesWithNoLayoutNodeDescendants_2BranchOneHasLn_removesCancelsCorrect() {
+
+ val neverCalled: () -> Unit = spy {}
+
val layoutNode = LayoutNode(0, 0, 100, 100)
val pointerInputNodeB = PointerInputNode().apply {
emitInsertAt(0, layoutNode)
+ cancelHandler = neverCalled
}
- val pointerInputNodeC = PointerInputNode()
+ val pointerInputNodeC = PointerInputNode().apply {
+ cancelHandler = spy {}
+ }
val pointerInputNodeA = PointerInputNode().apply {
emitInsertAt(0, pointerInputNodeB)
emitInsertAt(0, pointerInputNodeC)
+ cancelHandler = neverCalled
}
hitResult.addHitPath(0, listOf(pointerInputNodeA, pointerInputNodeB))
hitResult.addHitPath(1, listOf(pointerInputNodeA, pointerInputNodeC))
@@ -2128,6 +2586,8 @@
}
assertThat(areEqual(hitResult.root, expectedRoot)).isTrue()
+ verify(pointerInputNodeC.cancelHandler).invoke()
+ verify(neverCalled, never()).invoke()
}
// arrange: root(3) -> middle(3) -> leaf(3)
@@ -3392,7 +3852,8 @@
pointerInputNodeChild.cancelHandler = spy(MyCancelHandler())
pointerInputNodeMiddle.cancelHandler = spy(MyCancelHandler())
pointerInputNodeParent.cancelHandler = spy(MyCancelHandler())
- hitResult.addHitPath(3,
+ hitResult.addHitPath(
+ 3,
listOf(pointerInputNodeParent, pointerInputNodeMiddle, pointerInputNodeChild)
)
@@ -3494,7 +3955,8 @@
val pointerInputNodeChild = PointerInputNode()
val pointerInputNodeMiddle = PointerInputNode()
val pointerInputNodeParent = PointerInputNode()
- hitResult.addHitPath(3,
+ hitResult.addHitPath(
+ 3,
listOf(pointerInputNodeParent, pointerInputNodeMiddle, pointerInputNodeChild)
)
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
index 5f08b95..a407a57 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
@@ -1908,64 +1908,6 @@
}
@Test
- fun process_pointerInputNodeRemovedDuringInput_correctPointerInputChangesReceived() {
-
- // Arrange
-
- val childLayoutNode = LayoutNode(0, 0, 100, 100)
- val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
- pointerInputHandler = spy(MyPointerInputHandler())
- }
- val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, childPointerInputNode)
- }
- val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
- pointerInputHandler = spy(MyPointerInputHandler())
- }
- root.emitInsertAt(0, parentPointerInputNode)
-
- val offset = PxPosition(50.px, 50.px)
-
- val down = PointerInputEvent(0, Uptime.Boot + 7.milliseconds, offset, true)
- val up = PointerInputEvent(0, Uptime.Boot + 11.milliseconds, null, false)
-
- val expectedDownChange = PointerInputChange(
- id = 0,
- current = PointerInputData(Uptime.Boot + 7.milliseconds, offset, true),
- previous = PointerInputData(null, null, false),
- consumed = ConsumedData()
- )
-
- val expectedUpChange = PointerInputChange(
- id = 0,
- current = PointerInputData(Uptime.Boot + 11.milliseconds, null, false),
- previous = PointerInputData(Uptime.Boot + 7.milliseconds, offset, true),
- consumed = ConsumedData()
- )
-
- // Act
-
- pointerInputEventProcessor.process(down, IntPxPosition.Origin)
- parentLayoutNode.emitRemoveAt(0, 1)
- pointerInputEventProcessor.process(up, IntPxPosition.Origin)
-
- // Assert
-
- PointerEventPass.values().forEach {
- verify(parentPointerInputNode.pointerInputHandler)
- .invoke(eq(listOf(expectedDownChange)), eq(it), any())
- verify(childPointerInputNode.pointerInputHandler)
- .invoke(eq(listOf(expectedDownChange)), eq(it), any())
- verify(parentPointerInputNode.pointerInputHandler)
- .invoke(eq(listOf(expectedUpChange)), eq(it), any())
- }
- verifyNoMoreInteractions(parentPointerInputNode.pointerInputHandler)
- verifyNoMoreInteractions(childPointerInputNode.pointerInputHandler)
- }
-
- @Test
fun processCancel_noPointers_doesntCrash() {
pointerInputEventProcessor.processCancel()
}
@@ -2459,4 +2401,190 @@
pointerInputNode.cancelHandler
)
}
+
+ @Test
+ fun process_pointerInputNodeRemovedDuringInput_correctPointerInputChangesReceived() {
+
+ // Arrange
+
+ val childLayoutNode = LayoutNode(0, 0, 100, 100)
+ val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, childLayoutNode)
+ pointerInputHandler = spy(MyPointerInputHandler())
+ }
+ val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
+ emitInsertAt(0, childPointerInputNode)
+ }
+ val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, parentLayoutNode)
+ pointerInputHandler = spy(MyPointerInputHandler())
+ }
+ root.emitInsertAt(0, parentPointerInputNode)
+
+ val offset = PxPosition(50.px, 50.px)
+
+ val down = PointerInputEvent(0, Uptime.Boot + 7.milliseconds, offset, true)
+ val up = PointerInputEvent(0, Uptime.Boot + 11.milliseconds, null, false)
+
+ val expectedDownChange = PointerInputChange(
+ id = 0,
+ current = PointerInputData(Uptime.Boot + 7.milliseconds, offset, true),
+ previous = PointerInputData(null, null, false),
+ consumed = ConsumedData()
+ )
+
+ val expectedUpChange = PointerInputChange(
+ id = 0,
+ current = PointerInputData(Uptime.Boot + 11.milliseconds, null, false),
+ previous = PointerInputData(Uptime.Boot + 7.milliseconds, offset, true),
+ consumed = ConsumedData()
+ )
+
+ // Act
+
+ pointerInputEventProcessor.process(down, IntPxPosition.Origin)
+ parentLayoutNode.emitRemoveAt(0, 1)
+ pointerInputEventProcessor.process(up, IntPxPosition.Origin)
+
+ // Assert
+
+ PointerEventPass.values().forEach {
+ verify(parentPointerInputNode.pointerInputHandler)
+ .invoke(eq(listOf(expectedDownChange)), eq(it), any())
+ verify(childPointerInputNode.pointerInputHandler)
+ .invoke(eq(listOf(expectedDownChange)), eq(it), any())
+ verify(parentPointerInputNode.pointerInputHandler)
+ .invoke(eq(listOf(expectedUpChange)), eq(it), any())
+ }
+ verifyNoMoreInteractions(parentPointerInputNode.pointerInputHandler)
+ verifyNoMoreInteractions(childPointerInputNode.pointerInputHandler)
+ }
+
+ @Test
+ fun process_pointerInputNodeRemovedDuringInput_cancelDispatchedToCorrectPointerInputNode() {
+
+ // Arrange
+
+ val childLayoutNode = LayoutNode(0, 0, 100, 100)
+ val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, childLayoutNode)
+ cancelHandler = spy(MyCancelHandler())
+ }
+ val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
+ emitInsertAt(0, childPointerInputNode)
+ }
+ val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, parentLayoutNode)
+ cancelHandler = spy(MyCancelHandler())
+ }
+ root.emitInsertAt(0, parentPointerInputNode)
+
+ val down =
+ PointerInputEvent(0, Uptime.Boot + 7.milliseconds, PxPosition(50.px, 50.px), true)
+
+ val up = PointerInputEvent(0, Uptime.Boot + 11.milliseconds, null, false)
+
+ // Act
+
+ pointerInputEventProcessor.process(down, IntPxPosition.Origin)
+ parentLayoutNode.emitRemoveAt(0, 1)
+ pointerInputEventProcessor.process(up, IntPxPosition.Origin)
+
+ // Assert
+ verify(childPointerInputNode.cancelHandler).invoke()
+ verify(parentPointerInputNode.cancelHandler, never()).invoke()
+ }
+
+ @Test
+ fun process_childLayoutNodeRemovedDuringInput_correctPointerInputChangesReceived() {
+
+ // Arrange
+
+ val childLayoutNode = LayoutNode(0, 0, 100, 100)
+ val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, childLayoutNode)
+ pointerInputHandler = spy(MyPointerInputHandler())
+ }
+ val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
+ emitInsertAt(0, childPointerInputNode)
+ }
+ val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, parentLayoutNode)
+ pointerInputHandler = spy(MyPointerInputHandler())
+ }
+ root.emitInsertAt(0, parentPointerInputNode)
+
+ val offset = PxPosition(50.px, 50.px)
+
+ val down = PointerInputEvent(0, Uptime.Boot + 7.milliseconds, offset, true)
+ val up = PointerInputEvent(0, Uptime.Boot + 11.milliseconds, null, false)
+
+ val expectedDownChange = PointerInputChange(
+ id = 0,
+ current = PointerInputData(Uptime.Boot + 7.milliseconds, offset, true),
+ previous = PointerInputData(null, null, false),
+ consumed = ConsumedData()
+ )
+
+ val expectedUpChange = PointerInputChange(
+ id = 0,
+ current = PointerInputData(Uptime.Boot + 11.milliseconds, null, false),
+ previous = PointerInputData(Uptime.Boot + 7.milliseconds, offset, true),
+ consumed = ConsumedData()
+ )
+
+ // Act
+
+ pointerInputEventProcessor.process(down, IntPxPosition.Origin)
+ childPointerInputNode.emitRemoveAt(0, 1)
+ pointerInputEventProcessor.process(up, IntPxPosition.Origin)
+
+ // Assert
+
+ PointerEventPass.values().forEach {
+ verify(parentPointerInputNode.pointerInputHandler)
+ .invoke(eq(listOf(expectedDownChange)), eq(it), any())
+ verify(childPointerInputNode.pointerInputHandler)
+ .invoke(eq(listOf(expectedDownChange)), eq(it), any())
+ verify(parentPointerInputNode.pointerInputHandler)
+ .invoke(eq(listOf(expectedUpChange)), eq(it), any())
+ }
+ verifyNoMoreInteractions(parentPointerInputNode.pointerInputHandler)
+ verifyNoMoreInteractions(childPointerInputNode.pointerInputHandler)
+ }
+
+ @Test
+ fun process_childLayoutNodeRemovedDuringInput_cancelDispatchedToCorrectPointerInputNode() {
+
+ // Arrange
+
+ val childLayoutNode = LayoutNode(0, 0, 100, 100)
+ val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, childLayoutNode)
+ cancelHandler = spy(MyCancelHandler())
+ }
+ val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
+ emitInsertAt(0, childPointerInputNode)
+ }
+ val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
+ emitInsertAt(0, parentLayoutNode)
+ cancelHandler = spy(MyCancelHandler())
+ }
+ root.emitInsertAt(0, parentPointerInputNode)
+
+ val down =
+ PointerInputEvent(0, Uptime.Boot + 7.milliseconds, PxPosition(50.px, 50.px), true)
+
+ val up = PointerInputEvent(0, Uptime.Boot + 11.milliseconds, null, false)
+
+ // Act
+
+ pointerInputEventProcessor.process(down, IntPxPosition.Origin)
+ childPointerInputNode.emitRemoveAt(0, 1)
+ pointerInputEventProcessor.process(up, IntPxPosition.Origin)
+
+ // Assert
+ verify(childPointerInputNode.cancelHandler).invoke()
+ verify(parentPointerInputNode.cancelHandler, never()).invoke()
+ }
}
\ No newline at end of file
diff --git a/ui/ui-test/api/0.1.0-dev03.txt b/ui/ui-test/api/0.1.0-dev03.txt
index 37ae58c..7859d02 100644
--- a/ui/ui-test/api/0.1.0-dev03.txt
+++ b/ui/ui-test/api/0.1.0-dev03.txt
@@ -4,6 +4,7 @@
public final class ActionsKt {
ctor public ActionsKt();
method public static androidx.ui.test.SemanticsNodeInteraction doClick(androidx.ui.test.SemanticsNodeInteraction);
+ method public static androidx.ui.test.SemanticsNodeInteraction doGesture(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.test.GestureScope,kotlin.Unit> block);
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
method public static boolean waitForIdleCompose();
}
@@ -30,6 +31,12 @@
method public static void verifyHierarchy(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
}
+ public final class BitmapHelpersKt {
+ ctor public BitmapHelpersKt();
+ method public static void assertPixels(android.graphics.Bitmap, androidx.ui.core.IntPxSize? expectedSize = null, kotlin.jvm.functions.Function1<? super androidx.ui.core.IntPxPosition,androidx.ui.graphics.Color> expectedColorProvider);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static android.graphics.Bitmap captureToBitmap(androidx.ui.test.SemanticsNodeInteraction);
+ }
+
public final class CollectedSizes {
ctor public CollectedSizes(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
method public androidx.ui.test.CollectedSizes assertHeightEqualsTo(androidx.ui.core.Dp expectedHeight);
@@ -95,6 +102,7 @@
}
public interface ComposeTestRule extends org.junit.rules.TestRule {
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.ui.core.Density getDensity();
@@ -124,6 +132,8 @@
ctor public FiltersKt();
method public static boolean getHasClickAction(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean getHasScrollAction(androidx.ui.core.semantics.SemanticsConfiguration);
+ method public static boolean hasSubstring(androidx.ui.core.semantics.SemanticsConfiguration, String substring, boolean ignoreCase = false);
+ method public static boolean hasText(androidx.ui.core.semantics.SemanticsConfiguration, String text, boolean ignoreCase = false);
method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
}
@@ -133,10 +143,25 @@
method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
+ method public static androidx.ui.test.SemanticsNodeInteraction findBySubstring(String text, boolean ignoreCase = false);
method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
}
+ public final class GestureScope {
+ }
+
+ public final class GestureScopeKt {
+ ctor public GestureScopeKt();
+ method public static void sendClick(androidx.ui.test.GestureScope, float x, float y);
+ method public static void sendClick(androidx.ui.test.GestureScope);
+ method public static void sendSwipe(androidx.ui.test.GestureScope, float x0, float y0, float x1, float y1, androidx.ui.core.Duration duration = 200.milliseconds);
+ method public static void sendSwipeDown(androidx.ui.test.GestureScope);
+ method public static void sendSwipeLeft(androidx.ui.test.GestureScope);
+ method public static void sendSwipeRight(androidx.ui.test.GestureScope);
+ method public static void sendSwipeUp(androidx.ui.test.GestureScope);
+ }
+
public final class GoldenSemanticsKt {
ctor public GoldenSemanticsKt();
method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
@@ -181,6 +206,7 @@
ctor public AndroidComposeTestRule(boolean disableTransitions, boolean shouldThrowOnRecomposeTimeout);
ctor public AndroidComposeTestRule();
method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<android.app.Activity> getActivityTestRule();
@@ -198,6 +224,10 @@
method public void evaluate();
}
+ public final class WindowCaptureKt {
+ ctor public WindowCaptureKt();
+ }
+
}
package androidx.ui.test.android.fake {
diff --git a/ui/ui-test/api/current.txt b/ui/ui-test/api/current.txt
index 37ae58c..7859d02 100644
--- a/ui/ui-test/api/current.txt
+++ b/ui/ui-test/api/current.txt
@@ -4,6 +4,7 @@
public final class ActionsKt {
ctor public ActionsKt();
method public static androidx.ui.test.SemanticsNodeInteraction doClick(androidx.ui.test.SemanticsNodeInteraction);
+ method public static androidx.ui.test.SemanticsNodeInteraction doGesture(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.test.GestureScope,kotlin.Unit> block);
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
method public static boolean waitForIdleCompose();
}
@@ -30,6 +31,12 @@
method public static void verifyHierarchy(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
}
+ public final class BitmapHelpersKt {
+ ctor public BitmapHelpersKt();
+ method public static void assertPixels(android.graphics.Bitmap, androidx.ui.core.IntPxSize? expectedSize = null, kotlin.jvm.functions.Function1<? super androidx.ui.core.IntPxPosition,androidx.ui.graphics.Color> expectedColorProvider);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static android.graphics.Bitmap captureToBitmap(androidx.ui.test.SemanticsNodeInteraction);
+ }
+
public final class CollectedSizes {
ctor public CollectedSizes(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
method public androidx.ui.test.CollectedSizes assertHeightEqualsTo(androidx.ui.core.Dp expectedHeight);
@@ -95,6 +102,7 @@
}
public interface ComposeTestRule extends org.junit.rules.TestRule {
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.ui.core.Density getDensity();
@@ -124,6 +132,8 @@
ctor public FiltersKt();
method public static boolean getHasClickAction(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean getHasScrollAction(androidx.ui.core.semantics.SemanticsConfiguration);
+ method public static boolean hasSubstring(androidx.ui.core.semantics.SemanticsConfiguration, String substring, boolean ignoreCase = false);
+ method public static boolean hasText(androidx.ui.core.semantics.SemanticsConfiguration, String text, boolean ignoreCase = false);
method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
}
@@ -133,10 +143,25 @@
method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
+ method public static androidx.ui.test.SemanticsNodeInteraction findBySubstring(String text, boolean ignoreCase = false);
method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
}
+ public final class GestureScope {
+ }
+
+ public final class GestureScopeKt {
+ ctor public GestureScopeKt();
+ method public static void sendClick(androidx.ui.test.GestureScope, float x, float y);
+ method public static void sendClick(androidx.ui.test.GestureScope);
+ method public static void sendSwipe(androidx.ui.test.GestureScope, float x0, float y0, float x1, float y1, androidx.ui.core.Duration duration = 200.milliseconds);
+ method public static void sendSwipeDown(androidx.ui.test.GestureScope);
+ method public static void sendSwipeLeft(androidx.ui.test.GestureScope);
+ method public static void sendSwipeRight(androidx.ui.test.GestureScope);
+ method public static void sendSwipeUp(androidx.ui.test.GestureScope);
+ }
+
public final class GoldenSemanticsKt {
ctor public GoldenSemanticsKt();
method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
@@ -181,6 +206,7 @@
ctor public AndroidComposeTestRule(boolean disableTransitions, boolean shouldThrowOnRecomposeTimeout);
ctor public AndroidComposeTestRule();
method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<android.app.Activity> getActivityTestRule();
@@ -198,6 +224,10 @@
method public void evaluate();
}
+ public final class WindowCaptureKt {
+ ctor public WindowCaptureKt();
+ }
+
}
package androidx.ui.test.android.fake {
diff --git a/ui/ui-test/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-test/api/public_plus_experimental_0.1.0-dev03.txt
index 37ae58c..7859d02 100644
--- a/ui/ui-test/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-test/api/public_plus_experimental_0.1.0-dev03.txt
@@ -4,6 +4,7 @@
public final class ActionsKt {
ctor public ActionsKt();
method public static androidx.ui.test.SemanticsNodeInteraction doClick(androidx.ui.test.SemanticsNodeInteraction);
+ method public static androidx.ui.test.SemanticsNodeInteraction doGesture(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.test.GestureScope,kotlin.Unit> block);
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
method public static boolean waitForIdleCompose();
}
@@ -30,6 +31,12 @@
method public static void verifyHierarchy(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
}
+ public final class BitmapHelpersKt {
+ ctor public BitmapHelpersKt();
+ method public static void assertPixels(android.graphics.Bitmap, androidx.ui.core.IntPxSize? expectedSize = null, kotlin.jvm.functions.Function1<? super androidx.ui.core.IntPxPosition,androidx.ui.graphics.Color> expectedColorProvider);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static android.graphics.Bitmap captureToBitmap(androidx.ui.test.SemanticsNodeInteraction);
+ }
+
public final class CollectedSizes {
ctor public CollectedSizes(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
method public androidx.ui.test.CollectedSizes assertHeightEqualsTo(androidx.ui.core.Dp expectedHeight);
@@ -95,6 +102,7 @@
}
public interface ComposeTestRule extends org.junit.rules.TestRule {
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.ui.core.Density getDensity();
@@ -124,6 +132,8 @@
ctor public FiltersKt();
method public static boolean getHasClickAction(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean getHasScrollAction(androidx.ui.core.semantics.SemanticsConfiguration);
+ method public static boolean hasSubstring(androidx.ui.core.semantics.SemanticsConfiguration, String substring, boolean ignoreCase = false);
+ method public static boolean hasText(androidx.ui.core.semantics.SemanticsConfiguration, String text, boolean ignoreCase = false);
method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
}
@@ -133,10 +143,25 @@
method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
+ method public static androidx.ui.test.SemanticsNodeInteraction findBySubstring(String text, boolean ignoreCase = false);
method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
}
+ public final class GestureScope {
+ }
+
+ public final class GestureScopeKt {
+ ctor public GestureScopeKt();
+ method public static void sendClick(androidx.ui.test.GestureScope, float x, float y);
+ method public static void sendClick(androidx.ui.test.GestureScope);
+ method public static void sendSwipe(androidx.ui.test.GestureScope, float x0, float y0, float x1, float y1, androidx.ui.core.Duration duration = 200.milliseconds);
+ method public static void sendSwipeDown(androidx.ui.test.GestureScope);
+ method public static void sendSwipeLeft(androidx.ui.test.GestureScope);
+ method public static void sendSwipeRight(androidx.ui.test.GestureScope);
+ method public static void sendSwipeUp(androidx.ui.test.GestureScope);
+ }
+
public final class GoldenSemanticsKt {
ctor public GoldenSemanticsKt();
method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
@@ -181,6 +206,7 @@
ctor public AndroidComposeTestRule(boolean disableTransitions, boolean shouldThrowOnRecomposeTimeout);
ctor public AndroidComposeTestRule();
method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<android.app.Activity> getActivityTestRule();
@@ -198,6 +224,10 @@
method public void evaluate();
}
+ public final class WindowCaptureKt {
+ ctor public WindowCaptureKt();
+ }
+
}
package androidx.ui.test.android.fake {
diff --git a/ui/ui-test/api/public_plus_experimental_current.txt b/ui/ui-test/api/public_plus_experimental_current.txt
index 37ae58c..7859d02 100644
--- a/ui/ui-test/api/public_plus_experimental_current.txt
+++ b/ui/ui-test/api/public_plus_experimental_current.txt
@@ -4,6 +4,7 @@
public final class ActionsKt {
ctor public ActionsKt();
method public static androidx.ui.test.SemanticsNodeInteraction doClick(androidx.ui.test.SemanticsNodeInteraction);
+ method public static androidx.ui.test.SemanticsNodeInteraction doGesture(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.test.GestureScope,kotlin.Unit> block);
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
method public static boolean waitForIdleCompose();
}
@@ -30,6 +31,12 @@
method public static void verifyHierarchy(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
}
+ public final class BitmapHelpersKt {
+ ctor public BitmapHelpersKt();
+ method public static void assertPixels(android.graphics.Bitmap, androidx.ui.core.IntPxSize? expectedSize = null, kotlin.jvm.functions.Function1<? super androidx.ui.core.IntPxPosition,androidx.ui.graphics.Color> expectedColorProvider);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static android.graphics.Bitmap captureToBitmap(androidx.ui.test.SemanticsNodeInteraction);
+ }
+
public final class CollectedSizes {
ctor public CollectedSizes(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
method public androidx.ui.test.CollectedSizes assertHeightEqualsTo(androidx.ui.core.Dp expectedHeight);
@@ -95,6 +102,7 @@
}
public interface ComposeTestRule extends org.junit.rules.TestRule {
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.ui.core.Density getDensity();
@@ -124,6 +132,8 @@
ctor public FiltersKt();
method public static boolean getHasClickAction(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean getHasScrollAction(androidx.ui.core.semantics.SemanticsConfiguration);
+ method public static boolean hasSubstring(androidx.ui.core.semantics.SemanticsConfiguration, String substring, boolean ignoreCase = false);
+ method public static boolean hasText(androidx.ui.core.semantics.SemanticsConfiguration, String text, boolean ignoreCase = false);
method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
}
@@ -133,10 +143,25 @@
method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
+ method public static androidx.ui.test.SemanticsNodeInteraction findBySubstring(String text, boolean ignoreCase = false);
method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
}
+ public final class GestureScope {
+ }
+
+ public final class GestureScopeKt {
+ ctor public GestureScopeKt();
+ method public static void sendClick(androidx.ui.test.GestureScope, float x, float y);
+ method public static void sendClick(androidx.ui.test.GestureScope);
+ method public static void sendSwipe(androidx.ui.test.GestureScope, float x0, float y0, float x1, float y1, androidx.ui.core.Duration duration = 200.milliseconds);
+ method public static void sendSwipeDown(androidx.ui.test.GestureScope);
+ method public static void sendSwipeLeft(androidx.ui.test.GestureScope);
+ method public static void sendSwipeRight(androidx.ui.test.GestureScope);
+ method public static void sendSwipeUp(androidx.ui.test.GestureScope);
+ }
+
public final class GoldenSemanticsKt {
ctor public GoldenSemanticsKt();
method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
@@ -181,6 +206,7 @@
ctor public AndroidComposeTestRule(boolean disableTransitions, boolean shouldThrowOnRecomposeTimeout);
ctor public AndroidComposeTestRule();
method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<android.app.Activity> getActivityTestRule();
@@ -198,6 +224,10 @@
method public void evaluate();
}
+ public final class WindowCaptureKt {
+ ctor public WindowCaptureKt();
+ }
+
}
package androidx.ui.test.android.fake {
diff --git a/ui/ui-test/api/restricted_0.1.0-dev03.txt b/ui/ui-test/api/restricted_0.1.0-dev03.txt
index 37ae58c..7859d02 100644
--- a/ui/ui-test/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-test/api/restricted_0.1.0-dev03.txt
@@ -4,6 +4,7 @@
public final class ActionsKt {
ctor public ActionsKt();
method public static androidx.ui.test.SemanticsNodeInteraction doClick(androidx.ui.test.SemanticsNodeInteraction);
+ method public static androidx.ui.test.SemanticsNodeInteraction doGesture(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.test.GestureScope,kotlin.Unit> block);
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
method public static boolean waitForIdleCompose();
}
@@ -30,6 +31,12 @@
method public static void verifyHierarchy(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
}
+ public final class BitmapHelpersKt {
+ ctor public BitmapHelpersKt();
+ method public static void assertPixels(android.graphics.Bitmap, androidx.ui.core.IntPxSize? expectedSize = null, kotlin.jvm.functions.Function1<? super androidx.ui.core.IntPxPosition,androidx.ui.graphics.Color> expectedColorProvider);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static android.graphics.Bitmap captureToBitmap(androidx.ui.test.SemanticsNodeInteraction);
+ }
+
public final class CollectedSizes {
ctor public CollectedSizes(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
method public androidx.ui.test.CollectedSizes assertHeightEqualsTo(androidx.ui.core.Dp expectedHeight);
@@ -95,6 +102,7 @@
}
public interface ComposeTestRule extends org.junit.rules.TestRule {
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.ui.core.Density getDensity();
@@ -124,6 +132,8 @@
ctor public FiltersKt();
method public static boolean getHasClickAction(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean getHasScrollAction(androidx.ui.core.semantics.SemanticsConfiguration);
+ method public static boolean hasSubstring(androidx.ui.core.semantics.SemanticsConfiguration, String substring, boolean ignoreCase = false);
+ method public static boolean hasText(androidx.ui.core.semantics.SemanticsConfiguration, String text, boolean ignoreCase = false);
method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
}
@@ -133,10 +143,25 @@
method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
+ method public static androidx.ui.test.SemanticsNodeInteraction findBySubstring(String text, boolean ignoreCase = false);
method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
}
+ public final class GestureScope {
+ }
+
+ public final class GestureScopeKt {
+ ctor public GestureScopeKt();
+ method public static void sendClick(androidx.ui.test.GestureScope, float x, float y);
+ method public static void sendClick(androidx.ui.test.GestureScope);
+ method public static void sendSwipe(androidx.ui.test.GestureScope, float x0, float y0, float x1, float y1, androidx.ui.core.Duration duration = 200.milliseconds);
+ method public static void sendSwipeDown(androidx.ui.test.GestureScope);
+ method public static void sendSwipeLeft(androidx.ui.test.GestureScope);
+ method public static void sendSwipeRight(androidx.ui.test.GestureScope);
+ method public static void sendSwipeUp(androidx.ui.test.GestureScope);
+ }
+
public final class GoldenSemanticsKt {
ctor public GoldenSemanticsKt();
method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
@@ -181,6 +206,7 @@
ctor public AndroidComposeTestRule(boolean disableTransitions, boolean shouldThrowOnRecomposeTimeout);
ctor public AndroidComposeTestRule();
method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<android.app.Activity> getActivityTestRule();
@@ -198,6 +224,10 @@
method public void evaluate();
}
+ public final class WindowCaptureKt {
+ ctor public WindowCaptureKt();
+ }
+
}
package androidx.ui.test.android.fake {
diff --git a/ui/ui-test/api/restricted_current.txt b/ui/ui-test/api/restricted_current.txt
index 37ae58c..7859d02 100644
--- a/ui/ui-test/api/restricted_current.txt
+++ b/ui/ui-test/api/restricted_current.txt
@@ -4,6 +4,7 @@
public final class ActionsKt {
ctor public ActionsKt();
method public static androidx.ui.test.SemanticsNodeInteraction doClick(androidx.ui.test.SemanticsNodeInteraction);
+ method public static androidx.ui.test.SemanticsNodeInteraction doGesture(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.test.GestureScope,kotlin.Unit> block);
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
method public static boolean waitForIdleCompose();
}
@@ -30,6 +31,12 @@
method public static void verifyHierarchy(androidx.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.String> assertionMessage, kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> condition);
}
+ public final class BitmapHelpersKt {
+ ctor public BitmapHelpersKt();
+ method public static void assertPixels(android.graphics.Bitmap, androidx.ui.core.IntPxSize? expectedSize = null, kotlin.jvm.functions.Function1<? super androidx.ui.core.IntPxPosition,androidx.ui.graphics.Color> expectedColorProvider);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static android.graphics.Bitmap captureToBitmap(androidx.ui.test.SemanticsNodeInteraction);
+ }
+
public final class CollectedSizes {
ctor public CollectedSizes(androidx.ui.core.PxSize size, androidx.ui.core.Density density);
method public androidx.ui.test.CollectedSizes assertHeightEqualsTo(androidx.ui.core.Dp expectedHeight);
@@ -95,6 +102,7 @@
}
public interface ComposeTestRule extends org.junit.rules.TestRule {
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.ui.core.Density getDensity();
@@ -124,6 +132,8 @@
ctor public FiltersKt();
method public static boolean getHasClickAction(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean getHasScrollAction(androidx.ui.core.semantics.SemanticsConfiguration);
+ method public static boolean hasSubstring(androidx.ui.core.semantics.SemanticsConfiguration, String substring, boolean ignoreCase = false);
+ method public static boolean hasText(androidx.ui.core.semantics.SemanticsConfiguration, String text, boolean ignoreCase = false);
method public static boolean isInMutuallyExclusiveGroup(androidx.ui.core.semantics.SemanticsConfiguration);
method public static boolean isToggleable(androidx.ui.core.semantics.SemanticsConfiguration);
}
@@ -133,10 +143,25 @@
method public static androidx.ui.test.SemanticsNodeInteraction find(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAll(kotlin.jvm.functions.Function1<? super androidx.ui.core.semantics.SemanticsConfiguration,java.lang.Boolean> selector);
method public static java.util.List<androidx.ui.test.SemanticsNodeInteraction> findAllByTag(String testTag);
+ method public static androidx.ui.test.SemanticsNodeInteraction findBySubstring(String text, boolean ignoreCase = false);
method public static androidx.ui.test.SemanticsNodeInteraction findByTag(String testTag);
method public static androidx.ui.test.SemanticsNodeInteraction findByText(String text, boolean ignoreCase = false);
}
+ public final class GestureScope {
+ }
+
+ public final class GestureScopeKt {
+ ctor public GestureScopeKt();
+ method public static void sendClick(androidx.ui.test.GestureScope, float x, float y);
+ method public static void sendClick(androidx.ui.test.GestureScope);
+ method public static void sendSwipe(androidx.ui.test.GestureScope, float x0, float y0, float x1, float y1, androidx.ui.core.Duration duration = 200.milliseconds);
+ method public static void sendSwipeDown(androidx.ui.test.GestureScope);
+ method public static void sendSwipeLeft(androidx.ui.test.GestureScope);
+ method public static void sendSwipeRight(androidx.ui.test.GestureScope);
+ method public static void sendSwipeUp(androidx.ui.test.GestureScope);
+ }
+
public final class GoldenSemanticsKt {
ctor public GoldenSemanticsKt();
method public static void assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration expected);
@@ -181,6 +206,7 @@
ctor public AndroidComposeTestRule(boolean disableTransitions, boolean shouldThrowOnRecomposeTimeout);
ctor public AndroidComposeTestRule();
method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<android.app.Activity> getActivityTestRule();
@@ -198,6 +224,10 @@
method public void evaluate();
}
+ public final class WindowCaptureKt {
+ ctor public WindowCaptureKt();
+ }
+
}
package androidx.ui.test.android.fake {
diff --git a/ui/ui-test/build.gradle b/ui/ui-test/build.gradle
index 78872d5..b4ccacaf 100644
--- a/ui/ui-test/build.gradle
+++ b/ui/ui-test/build.gradle
@@ -48,7 +48,7 @@
testImplementation(TRUTH)
androidTestImplementation(TRUTH)
-
+ androidTestImplementation project(":ui:ui-core")
androidTestImplementation project(':ui:ui-material')
}
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/BitmapCapturingTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/BitmapCapturingTest.kt
new file mode 100644
index 0000000..44ab5c4
--- /dev/null
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/BitmapCapturingTest.kt
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test
+
+import android.os.Build
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.ui.core.Alignment
+import androidx.ui.core.IntPxPosition
+import androidx.ui.core.IntPxSize
+import androidx.ui.core.TestTag
+import androidx.ui.core.ipx
+import androidx.ui.core.withDensity
+import androidx.ui.foundation.ColoredRect
+import androidx.ui.foundation.shape.DrawShape
+import androidx.ui.foundation.shape.RectangleShape
+import androidx.ui.graphics.Color
+import androidx.ui.graphics.SolidColor
+import androidx.ui.layout.Column
+import androidx.ui.layout.Container
+import androidx.ui.layout.Row
+import androidx.ui.semantics.Semantics
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@MediumTest
+@RunWith(JUnit4::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+class BitmapCapturingTest {
+
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ private val rootTag = "Root"
+ private val tag11 = "Rect11"
+ private val tag12 = "Rect12"
+ private val tag21 = "Rect21"
+ private val tag22 = "Rect22"
+
+ private val color11 = Color.Red
+ private val color12 = Color.Blue
+ private val color21 = Color.Green
+ private val color22 = Color.Yellow
+ private val colorBg = Color.Black
+
+ @Test
+ fun captureIndividualRects_checkSizeAndColors() {
+ composeCheckerboard()
+
+ var calledCount = 0
+ findByTag(tag11)
+ .captureToBitmap()
+ .assertPixels(expectedSize = IntPxSize(100.ipx, 50.ipx)) {
+ calledCount++
+ color11
+ }
+ assertThat(calledCount).isEqualTo(100 * 50)
+
+ findByTag(tag12)
+ .captureToBitmap()
+ .assertPixels(expectedSize = IntPxSize(100.ipx, 50.ipx)) {
+ color12
+ }
+ findByTag(tag21)
+ .captureToBitmap()
+ .assertPixels(expectedSize = IntPxSize(100.ipx, 50.ipx)) {
+ color21
+ }
+ findByTag(tag22)
+ .captureToBitmap()
+ .assertPixels(expectedSize = IntPxSize(100.ipx, 50.ipx)) {
+ color22
+ }
+ }
+
+ @Test
+ fun captureRootContainer_checkSizeAndColors() {
+ composeCheckerboard()
+
+ findByTag(rootTag)
+ .captureToBitmap()
+ .assertPixels(expectedSize = IntPxSize(200.ipx, 100.ipx)) {
+ if (it.y >= 100.ipx || it.x >= 200.ipx) {
+ throw AssertionError("$it is out of range!")
+ }
+ expectedColorProvider(it)
+ }
+ }
+
+ @Test
+ fun captureWholeWindow_checkSizeAndColors() {
+ composeCheckerboard()
+
+ composeTestRule
+ .captureScreenOnIdle()
+ .assertPixels() {
+ expectedColorProvider(it)
+ }
+ }
+
+ @Test(expected = AssertionError::class)
+ fun assertWrongColor_expectException() {
+ composeCheckerboard()
+
+ findByTag(tag11)
+ .captureToBitmap()
+ .assertPixels(expectedSize = IntPxSize(100.ipx, 50.ipx)) {
+ color22 // Assuming wrong color
+ }
+ }
+
+ @Test(expected = AssertionError::class)
+ fun assertWrongSize_expectException() {
+ composeCheckerboard()
+
+ findByTag(tag11)
+ .captureToBitmap()
+ .assertPixels(expectedSize = IntPxSize(10.ipx, 10.ipx)) {
+ color21
+ }
+ }
+
+ private fun expectedColorProvider(pos: IntPxPosition): Color {
+ if (pos.y < 50.ipx) {
+ if (pos.x < 100.ipx) {
+ return color11
+ } else if (pos.x < 200.ipx) {
+ return color12
+ }
+ } else if (pos.y < 100.ipx) {
+ if (pos.x < 100.ipx) {
+ return color21
+ } else if (pos.x < 200.ipx) {
+ return color22
+ }
+ }
+ return colorBg
+ }
+
+ private fun composeCheckerboard() {
+ withDensity(composeTestRule.density) {
+ composeTestRule.setContent {
+ Container(alignment = Alignment.TopLeft) {
+
+ DrawShape(RectangleShape, SolidColor(colorBg))
+
+ TestTag(rootTag) {
+ Semantics {
+ Column {
+ Row {
+ TestTag(tag11) {
+ Semantics {
+ ColoredRect(
+ color = color11,
+ width = 100.ipx.toDp(),
+ height = 50.ipx.toDp()
+ )
+ }
+ }
+ TestTag(tag12) {
+ Semantics {
+ ColoredRect(
+ color = color12,
+ width = 100.ipx.toDp(),
+ height = 50.ipx.toDp()
+ )
+ }
+ }
+ }
+ Row {
+ TestTag(tag21) {
+ Semantics {
+ ColoredRect(
+ color = color21,
+ width = 100.ipx.toDp(),
+ height = 50.ipx.toDp()
+ )
+ }
+ }
+ TestTag(tag22) {
+ Semantics {
+ ColoredRect(
+ color = color22,
+ width = 100.ipx.toDp(),
+ height = 50.ipx.toDp()
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/PointerInputRecorder.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/PointerInputRecorder.kt
new file mode 100644
index 0000000..c274abb
--- /dev/null
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/PointerInputRecorder.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test
+
+import androidx.ui.core.IntPxSize
+import androidx.ui.core.PointerEventPass
+import androidx.ui.core.PointerInputChange
+import androidx.ui.core.PointerInputData
+import com.google.common.truth.Truth
+
+class PointerInputRecorder {
+
+ data class DataPoint(val id: Int, val data: PointerInputData) {
+ val timestamp get() = data.uptime
+ val position get() = data.position
+ val down get() = data.down
+ }
+
+ private val _events = mutableListOf<DataPoint>()
+ val events get() = _events as List<DataPoint>
+
+ fun onPointerInput(
+ changes: List<PointerInputChange>,
+ pass: PointerEventPass,
+ @Suppress("UNUSED_PARAMETER") bounds: IntPxSize
+ ): List<PointerInputChange> {
+ if (pass == PointerEventPass.InitialDown) {
+ changes.forEach {
+ _events.add(DataPoint(it.id, it.current))
+ }
+ }
+ return changes
+ }
+
+ fun assertTimestampsAreIncreasing() {
+ events.reduce { prev, curr ->
+ Truth.assertThat(curr.timestamp).isAtLeast(prev.timestamp)
+ curr
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/SendSwipeTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/SendSwipeTest.kt
new file mode 100644
index 0000000..f16eb24
--- /dev/null
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/SendSwipeTest.kt
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test
+
+import androidx.compose.Composable
+import androidx.test.filters.MediumTest
+import androidx.ui.core.Alignment
+import androidx.ui.core.PointerInputWrapper
+import androidx.ui.core.TestTag
+import androidx.ui.core.dp
+import androidx.ui.foundation.shape.DrawShape
+import androidx.ui.foundation.shape.RectangleShape
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Align
+import androidx.ui.layout.Container
+import androidx.ui.semantics.Semantics
+import com.google.common.collect.Ordering
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@MediumTest
+@RunWith(JUnit4::class)
+class SendSwipeTest {
+
+ private val tag = "widget"
+
+ @get:Rule
+ val composeTestRule = createComposeRule(disableTransitions = true)
+
+ private lateinit var recorder: PointerInputRecorder
+
+ @Before
+ fun setup() {
+ recorder = PointerInputRecorder()
+ }
+
+ @Composable
+ fun Ui(alignment: Alignment) {
+ PointerInputWrapper(pointerInputHandler = recorder::onPointerInput) {
+ Align(alignment = alignment) {
+ TestTag(tag) {
+ Semantics {
+ Container(width = 100.dp, height = 100.dp) {
+ DrawShape(RectangleShape, Color.Yellow)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun swipeUp() {
+ composeTestRule.setContent { Ui(Alignment.TopLeft) }
+ findByTag(tag).doGesture { sendSwipeUp() }
+ recorder.run {
+ assertTimestampsAreIncreasing()
+ assertOnlyLastEventIsUp()
+ assertSwipeIsUp()
+ }
+ }
+
+ @Test
+ fun swipeDown() {
+ composeTestRule.setContent { Ui(Alignment.TopRight) }
+ findByTag(tag).doGesture { sendSwipeDown() }
+ recorder.run {
+ assertTimestampsAreIncreasing()
+ assertOnlyLastEventIsUp()
+ assertSwipeIsDown()
+ }
+ }
+
+ @Test
+ fun swipeLeft() {
+ composeTestRule.setContent { Ui(Alignment.BottomRight) }
+ findByTag(tag).doGesture { sendSwipeLeft() }
+ recorder.run {
+ assertTimestampsAreIncreasing()
+ assertOnlyLastEventIsUp()
+ assertSwipeIsLeft()
+ }
+ }
+
+ @Test
+ fun swipeRight() {
+ composeTestRule.setContent { Ui(Alignment.BottomLeft) }
+ findByTag(tag).doGesture { sendSwipeRight() }
+ recorder.run {
+ assertTimestampsAreIncreasing()
+ assertOnlyLastEventIsUp()
+ assertSwipeIsRight()
+ }
+ }
+}
+
+private fun PointerInputRecorder.assertOnlyLastEventIsUp() {
+ assertThat(events.last().down).isFalse()
+ assertThat(events.filter { !it.down }.size).isEqualTo(1)
+}
+
+private fun PointerInputRecorder.assertSwipeIsUp() {
+ // Must have at least two events to have a direction
+ assertThat(events.size).isAtLeast(2)
+ // Last event must be above first event
+ assertThat(events.last().position!!.y).isLessThan(events.first().position!!.y)
+ // All events in between only move up
+ events.map { it.position!!.x.value }.assertSame(tolerance = 0.001f)
+ events.map { it.position!!.y }.assertDecreasing()
+}
+
+private fun PointerInputRecorder.assertSwipeIsDown() {
+ // Must have at least two events to have a direction
+ assertThat(events.size).isAtLeast(2)
+ // Last event must be below first event
+ assertThat(events.last().position!!.y).isGreaterThan(events.first().position!!.y)
+ // All events in between only move down
+ events.map { it.position!!.x.value }.assertSame(tolerance = 0.001f)
+ events.map { it.position!!.y }.assertIncreasing()
+}
+
+private fun PointerInputRecorder.assertSwipeIsLeft() {
+ // Must have at least two events to have a direction
+ assertThat(events.size).isAtLeast(2)
+ // Last event must be to the left of first event
+ assertThat(events.last().position!!.x).isLessThan(events.first().position!!.x)
+ // All events in between only move to the left
+ events.map { it.position!!.x }.assertDecreasing()
+ events.map { it.position!!.y.value }.assertSame(tolerance = 0.001f)
+}
+
+private fun PointerInputRecorder.assertSwipeIsRight() {
+ // Must have at least two events to have a direction
+ assertThat(events.size).isAtLeast(2)
+ // Last event must be to the right of first event
+ assertThat(events.last().position!!.x).isGreaterThan(events.first().position!!.x)
+ // All events in between only move to the right
+ events.map { it.position!!.x }.assertIncreasing()
+ events.map { it.position!!.y.value }.assertSame(tolerance = 0.001f)
+}
+
+private fun List<Float>.assertSame(tolerance: Float = 0f) {
+ if (size <= 1) {
+ return
+ }
+ val baseValue = first()
+ assertThat(min()).isWithin(tolerance).of(baseValue)
+ assertThat(max()).isWithin(tolerance).of(baseValue)
+}
+
+private fun <E : Comparable<E>> List<E>.assertIncreasing() {
+ assertThat(this).isInOrder(Ordering.natural<E>())
+}
+
+private fun <E : Comparable<E>> List<E>.assertDecreasing() {
+ assertThat(this).isInOrder(Ordering.natural<E>().reverse<E>())
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Actions.kt b/ui/ui-test/src/main/java/androidx/ui/test/Actions.kt
index 86e74da..109498b 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Actions.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Actions.kt
@@ -27,18 +27,17 @@
* Performs a click action on the given component.
*/
fun SemanticsNodeInteraction.doClick(): SemanticsNodeInteraction {
- // TODO(b/129400818): uncomment this after Merge Semantics is merged
- // assertHasClickAction()
-
- // TODO(catalintudor): get real coordinates after Semantics API is ready (b/125702443)
- val globalRect = semanticsTreeNode.globalRect
- ?: throw AssertionError("Semantic Node has no child layout to perform click on!")
- val x = globalRect.left + 1f
- val y = globalRect.top + 1f
-
- semanticsTreeInteraction.sendClick(x, y)
-
- return this
+ // TODO(jellefresen): Replace with semantics action when semantics merging is done
+ // The problem we currently have is that the click action might be defined on a different
+ // semantics node than we're interacting with now, even though it is "semantically" the same.
+ // E.g., findByText(buttonText) finds the Text's semantics node, but the click action is
+ // defined on the wrapping Button's semantics node.
+ // Since in general the intended click action can be on a wrapping node or a child node, we
+ // can't just forward to the correct node, as we don't know if we should search up or down the
+ // tree.
+ return doGesture {
+ sendClick()
+ }
}
/**
@@ -85,4 +84,21 @@
return this
}
+/**
+ * Executes the gestures specified in the given block.
+ *
+ * Example usage:
+ * findByTag("myWidget")
+ * .doGesture {
+ * sendSwipeUp()
+ * }
+ */
+fun SemanticsNodeInteraction.doGesture(
+ block: GestureScope.() -> Unit
+): SemanticsNodeInteraction {
+ val scope = GestureScope(this)
+ scope.block()
+ return this
+}
+
fun waitForIdleCompose(): Boolean = semanticsTreeInteractionFactory({ true }).waitForIdleCompose()
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt b/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
index 8460a72..032295a 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
@@ -179,8 +179,8 @@
}
/**
- * Asserts the component's value equals the given value. This is used by
- * [CircularProgressIndicator] to check progress.
+ * Asserts the component's value equals the given value.
+ *
* For further details please check [SemanticsConfiguration.accessibilityValue].
* Throws [AssertionError] if the node's value is not equal to `value`, or if the node has no value
*/
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/BitmapHelpers.kt b/ui/ui-test/src/main/java/androidx/ui/test/BitmapHelpers.kt
new file mode 100644
index 0000000..7c3f390
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/BitmapHelpers.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test
+
+import android.graphics.Bitmap
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.ui.core.IntPxPosition
+import androidx.ui.core.IntPxSize
+import androidx.ui.core.ipx
+import androidx.ui.graphics.Color
+
+/**
+ * Captures the underlying component's surface into bitmap.
+ *
+ * This has currently several limitations. Currently we assume that the component is hosted in
+ * Activity's window. Also if there is another window covering part of the component if won't occur
+ * in the bitmap as this is taken from the component's window surface.
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+fun SemanticsNodeInteraction.captureToBitmap(): Bitmap {
+ return semanticsTreeInteraction.captureNodeToBitmap(semanticsTreeNode)
+}
+
+/**
+ * A helper function to run asserts on [Bitmap].
+ *
+ * @param expectedSize The expected size of the bitmap. Leave null to skip the check.
+ * @param expectedColorProvider Returns the expected color for the provided pixel position.
+ * The returned color is then asserted as the expected one on the given bitmap.
+ *
+ * @throws AssertionError if size or colors don't match.
+ */
+fun Bitmap.assertPixels(
+ expectedSize: IntPxSize? = null,
+ expectedColorProvider: (pos: IntPxPosition) -> Color?
+) {
+ if (expectedSize != null) {
+ if (width != expectedSize.width.value || height != expectedSize.height.value) {
+ throw AssertionError("Bitmap size is wrong! Expected '$expectedSize' but got " +
+ "'$width x $height'")
+ }
+ }
+
+ val pixels = IntArray(width * height)
+ getPixels(pixels, 0, width, 0, 0, width, height)
+
+ for (x in 0 until width) {
+ for (y in 0 until height) {
+ val pxPos = IntPxPosition(x.ipx, y.ipx)
+ val color = Color(pixels[width * y + x])
+ val expectedClr = expectedColorProvider(pxPos)
+ if (expectedClr != null && expectedClr != color) {
+ throw AssertionError("Comparison failed for $pxPos: expected $expectedClr $ " +
+ "but received $color")
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt b/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
index 0e01792..40ae06c 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
@@ -16,7 +16,10 @@
package androidx.ui.test
+import android.graphics.Bitmap
+import android.os.Build
import android.util.DisplayMetrics
+import androidx.annotation.RequiresApi
import androidx.compose.Composable
import androidx.ui.core.Density
import androidx.ui.test.android.AndroidComposeTestRule
@@ -59,6 +62,22 @@
*/
fun runOnUiThread(action: () -> Unit)
+ /**
+ * Takes screenshot of the Activity's window after Compose UI gets idle.
+ *
+ * This function blocks until complete.
+ *
+ * Note that this does not capture the full device screen as it has access only to the test
+ * Activity's window surface. The test Activity is the one that hosts the initial composition
+ * created via [setContent]. If there are windows on top of the Activity's window these won't
+ * be included. It will also not include any other Activities started afterwards.
+ *
+ * You can also use [SemanticsNodeInteraction.captureToBitmap] to capture individual components.
+ * That one does not require any specific Activity.
+ */
+ @RequiresApi(Build.VERSION_CODES.O)
+ fun captureScreenOnIdle(): Bitmap
+
// TODO(pavlis): Provide better abstraction for host side reusability
val displayMetrics: DisplayMetrics get
}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt b/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
index a2f1cec..1f839b0 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
@@ -20,22 +20,52 @@
import androidx.ui.core.semantics.getOrNull
import androidx.ui.foundation.semantics.FoundationSemanticsProperties
import androidx.ui.semantics.SemanticsActions
+import androidx.ui.semantics.SemanticsProperties
/**
- * Verifies that a component is checkable.
+ * Return whether the component is checkable.
*/
val SemanticsConfiguration.isToggleable: Boolean
get() = contains(FoundationSemanticsProperties.ToggleableState)
+/**
+ * Return whether the component has a semantics click action defined.
+ */
val SemanticsConfiguration.hasClickAction: Boolean
get() = SemanticsActions.OnClick in this
+/**
+ * Return whether the component has a semantics scrollable action defined.
+ */
val SemanticsConfiguration.hasScrollAction: Boolean
get() = SemanticsActions.ScrollTo in this
+/**
+ * Returns whether the component's label matches exactly to the given text.
+ *
+ * @param text Text to match.
+ * @param ignoreCase Whether case should be ignored.
+ * @see hasSubstring
+ */
+fun SemanticsConfiguration.hasText(text: String, ignoreCase: Boolean = false): Boolean {
+ return getOrNull(SemanticsProperties.AccessibilityLabel).equals(text, ignoreCase)
+}
+
+/**
+ * Returns whether the component's label contains the given substring.
+ *
+ * @param substring Substring to check.
+ * @param ignoreCase Whether case should be ignored.
+ * @see hasText
+ */
+fun SemanticsConfiguration.hasSubstring(substring: String, ignoreCase: Boolean = false): Boolean {
+ return getOrNull(SemanticsProperties.AccessibilityLabel)?.contains(substring, ignoreCase)
+ ?: false
+}
+
// TODO(ryanmentley/pavlis): Do we want these convenience functions?
/**
- * Verifies that a component is in a mutually exclusive group - that is,
+ * Verifies that the component is in a mutually exclusive group - that is,
* that [FoundationSemanticsProperties.InMutuallyExclusiveGroup] is set to true
*
*/
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt b/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt
index fdb1cf8..1a746fb 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Finders.kt
@@ -47,13 +47,26 @@
}
/**
- * Finds a component by the given text.
+ * Finds a component with label that matches the given text.
*
* For usage patterns see [SemanticsNodeInteraction]
+ * @see findBySubstring to search by substring instead of via exact match.
*/
fun findByText(text: String, ignoreCase: Boolean = false): SemanticsNodeInteraction {
return find {
- getOrNull(SemanticsProperties.AccessibilityLabel).equals(text, ignoreCase)
+ hasText(text, ignoreCase)
+ }
+}
+
+/**
+ * Finds a component with label that contains the given substring.
+ *
+ * For usage patterns see [SemanticsNodeInteraction]
+ * @see findByText to perform exact matches.
+ */
+fun findBySubstring(text: String, ignoreCase: Boolean = false): SemanticsNodeInteraction {
+ return find {
+ hasSubstring(text, ignoreCase)
}
}
@@ -62,6 +75,7 @@
* This tries to match exactly one element and throws [AssertionError] if more than one is matched.
*
* For usage patterns see [SemanticsNodeInteraction]
+ * @see findAll to work with multiple elements
*/
fun find(
selector: SemanticsConfiguration.() -> Boolean
@@ -70,6 +84,13 @@
.findOne()
}
+/**
+ * Finds all components that match the given condition.
+ *
+ * If you are working with elements that are not supposed to occur multiple times use [find]
+ * instead.
+ * @see find
+ */
fun findAll(
selector: SemanticsConfiguration.() -> Boolean
): List<SemanticsNodeInteraction> {
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/GestureScope.kt b/ui/ui-test/src/main/java/androidx/ui/test/GestureScope.kt
new file mode 100644
index 0000000..3d5daf2
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/GestureScope.kt
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test
+
+import androidx.ui.core.Duration
+import androidx.ui.core.SemanticsTreeNode
+import androidx.ui.core.milliseconds
+
+/**
+ * An object that has an associated component in which one can inject gestures. The gestures can
+ * be injected by calling methods defined on [GestureScope], such as [sendSwipeUp]. The associated
+ * component is the [SemanticsTreeNode] found by one of the finder methods such as [findByTag].
+ *
+ * Example usage:
+ * findByTag("myWidget")
+ * .doGesture {
+ * sendSwipeUp()
+ * }
+ */
+class GestureScope internal constructor(
+ internal val semanticsNodeInteraction: SemanticsNodeInteraction
+) {
+ internal inline val semanticsTreeNode
+ get() = semanticsNodeInteraction.semanticsTreeNode
+ internal inline val semanticsTreeInteraction
+ get() = semanticsNodeInteraction.semanticsTreeInteraction
+}
+
+/**
+ * The distance of a swipe's start position from the node's edge, in terms of the node's length.
+ * We do not start the swipe exactly on the node's edge, but somewhat more inward, since swiping
+ * from the exact edge may behave in an unexpected way (e.g. may open a navigation drawer).
+ */
+private const val edgeFuzzFactor = 0.083f
+
+/**
+ * Performs a click gesture on the given coordinate on the associated component. The coordinate
+ * ([x], [y]) is in the component's local coordinate system.
+ *
+ * Throws [AssertionError] when the component doesn't have a bounding rectangle set
+ */
+fun GestureScope.sendClick(x: Float, y: Float) {
+ val globalRect = semanticsTreeNode.globalRect
+ ?: throw AssertionError("Semantic Node has no child layout to perform click on!")
+ val xOffset = globalRect.left
+ val yOffset = globalRect.top
+
+ semanticsTreeInteraction.sendInput {
+ it.sendClick(x + xOffset, y + yOffset)
+ }
+}
+
+/**
+ * Performs a click gesture on the associated component. The click is done in the middle of the
+ * component's bounds.
+ *
+ * Throws [AssertionError] when the component doesn't have a bounding rectangle set
+ */
+fun GestureScope.sendClick() {
+ val globalRect = semanticsTreeNode.globalRect
+ ?: throw AssertionError("Semantic Node has no child layout to perform click on!")
+ val x = globalRect.width / 2
+ val y = globalRect.height / 2
+
+ sendClick(x, y)
+}
+
+/**
+ * Performs the swipe gesture on the associated component. The MotionEvents are linearly
+ * interpolated between ([x0], [y0]) and ([x1], [y1]). The coordinates are in the component's local
+ * coordinate system, i.e. (0, 0) is the top left corner of the component. The default duration is
+ * 200 milliseconds.
+ *
+ * Throws [AssertionError] when the component doesn't have a bounding rectangle set
+ */
+fun GestureScope.sendSwipe(
+ x0: Float,
+ y0: Float,
+ x1: Float,
+ y1: Float,
+ duration: Duration = 200.milliseconds
+) {
+ val globalRect = semanticsTreeNode.globalRect
+ ?: throw AssertionError("Semantic Node has no child layout to perform swipe on!")
+ val xOffset = globalRect.left
+ val yOffset = globalRect.top
+
+ semanticsTreeInteraction.sendInput {
+ it.sendSwipe(x0 + xOffset, y0 + yOffset, x1 + xOffset, y1 + yOffset, duration)
+ }
+}
+
+/**
+ * Performs a swipe up gesture on the associated component. The gesture starts slightly above the
+ * bottom of the component and ends at the top.
+ *
+ * Throws [AssertionError] when the component doesn't have a bounding rectangle set
+ */
+fun GestureScope.sendSwipeUp() {
+ val globalRect = semanticsTreeNode.globalRect
+ ?: throw AssertionError("Semantic Node has no child layout to perform swipe on!")
+ val x = globalRect.width / 2
+ val y0 = globalRect.height * (1 - edgeFuzzFactor)
+ val y1 = 0f
+
+ sendSwipe(x, y0, x, y1, 200.milliseconds)
+}
+
+/**
+ * Performs a swipe down gesture on the associated component. The gesture starts slightly below the
+ * top of the component and ends at the bottom.
+ *
+ * Throws [AssertionError] when the component doesn't have a bounding rectangle set
+ */
+fun GestureScope.sendSwipeDown() {
+ val globalRect = semanticsTreeNode.globalRect
+ ?: throw AssertionError("Semantic Node has no child layout to perform swipe on!")
+ val x = globalRect.width / 2
+ val y0 = globalRect.height * edgeFuzzFactor
+ val y1 = globalRect.height
+
+ sendSwipe(x, y0, x, y1, 200.milliseconds)
+}
+
+/**
+ * Performs a swipe left gesture on the associated component. The gesture starts slightly left of
+ * the right side of the component and ends at the left side.
+ *
+ * Throws [AssertionError] when the component doesn't have a bounding rectangle set
+ */
+fun GestureScope.sendSwipeLeft() {
+ val globalRect = semanticsTreeNode.globalRect
+ ?: throw AssertionError("Semantic Node has no child layout to perform swipe on!")
+ val x0 = globalRect.width * (1 - edgeFuzzFactor)
+ val x1 = 0f
+ val y = globalRect.height / 2
+
+ sendSwipe(x0, y, x1, y, 200.milliseconds)
+}
+
+/**
+ * Performs a swipe right gesture on the associated component. The gesture starts slightly right of
+ * the left side of the component and ends at the right side.
+ *
+ * Throws [AssertionError] when the component doesn't have a bounding rectangle set
+ */
+fun GestureScope.sendSwipeRight() {
+ val globalRect = semanticsTreeNode.globalRect
+ ?: throw AssertionError("Semantic Node has no child layout to perform swipe on!")
+ val x0 = globalRect.width * edgeFuzzFactor
+ val x1 = globalRect.width
+ val y = globalRect.height / 2
+
+ sendSwipe(x0, y, x1, y, 200.milliseconds)
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/InputDispatcher.kt b/ui/ui-test/src/main/java/androidx/ui/test/InputDispatcher.kt
new file mode 100644
index 0000000..c8b061a
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/InputDispatcher.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test
+
+import androidx.ui.core.Duration
+
+internal interface InputDispatcher {
+ /**
+ * Sends a click event at coordinate ([x], [y]). There will be 10ms in between the down and
+ * the up event. This method blocks until all input events have been dispatched.
+ */
+ fun sendClick(x: Float, y: Float)
+
+ /**
+ * Sends a swipe gesture from ([x0], [y0]) to ([x1], [y1]) with the given [duration]. This
+ * method blocks until all input events have been dispatched.
+ */
+ fun sendSwipe(x0: Float, y0: Float, x1: Float, y1: Float, duration: Duration)
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/SemanticsTreeInteraction.kt b/ui/ui-test/src/main/java/androidx/ui/test/SemanticsTreeInteraction.kt
index 94a780f..0c72173 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/SemanticsTreeInteraction.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/SemanticsTreeInteraction.kt
@@ -16,6 +16,10 @@
package androidx.ui.test
+import android.graphics.Bitmap
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.ui.core.SemanticsTreeNode
import androidx.ui.core.SemanticsTreeProvider
import androidx.ui.core.semantics.SemanticsConfiguration
import androidx.ui.engine.geometry.Rect
@@ -26,21 +30,24 @@
* extension functions. This class is expected to have Android and host side specific
* implementations.
*/
-internal abstract class SemanticsTreeInteraction {
+internal interface SemanticsTreeInteraction {
- internal abstract fun findAllMatching(): List<SemanticsNodeInteraction>
+ fun findAllMatching(): List<SemanticsNodeInteraction>
- internal abstract fun findOne(): SemanticsNodeInteraction
+ fun findOne(): SemanticsNodeInteraction
- internal abstract fun performAction(action: (SemanticsTreeProvider) -> Unit)
+ fun performAction(action: (SemanticsTreeProvider) -> Unit)
- internal abstract fun sendClick(x: Float, y: Float)
+ fun sendInput(action: (InputDispatcher) -> Unit)
- internal abstract fun contains(semanticsConfiguration: SemanticsConfiguration): Boolean
+ fun contains(semanticsConfiguration: SemanticsConfiguration): Boolean
- internal abstract fun isInScreenBounds(rectangle: Rect): Boolean
+ fun isInScreenBounds(rectangle: Rect): Boolean
- internal abstract fun waitForIdleCompose(): Boolean
+ fun waitForIdleCompose(): Boolean
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ fun captureNodeToBitmap(node: SemanticsTreeNode): Bitmap
}
internal var semanticsTreeInteractionFactory: (
@@ -58,4 +65,4 @@
* just wait for longer timeouts as the tests might still have a value.
*/
// TODO(pavlis): Turn this on by default for all our Compose tests
-internal var throwOnRecomposeTimeout = false
\ No newline at end of file
+internal var throwOnRecomposeTimeout = false
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
index 3971e79..39797ca 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
@@ -17,14 +17,20 @@
package androidx.ui.test.android
import android.app.Activity
+import android.graphics.Bitmap
+import android.os.Build
+import android.os.Handler
+import android.os.Looper
import android.util.DisplayMetrics
import android.view.ViewGroup
import android.view.ViewTreeObserver
+import androidx.annotation.RequiresApi
import androidx.compose.Composable
import androidx.test.rule.ActivityTestRule
import androidx.ui.animation.transitionsEnabled
import androidx.ui.core.Density
import androidx.ui.core.setContent
+import androidx.ui.engine.geometry.Rect
import androidx.ui.test.ComposeTestCase
import androidx.ui.test.ComposeTestCaseSetup
import androidx.ui.test.ComposeTestRule
@@ -44,6 +50,8 @@
val activityTestRule = ActivityTestRule<Activity>(Activity::class.java)
+ private val handler: Handler = Handler(Looper.getMainLooper())
+
override val density: Density get() = Density(activityTestRule.activity)
override val displayMetrics: DisplayMetrics get() =
@@ -111,6 +119,21 @@
)
}
+ @RequiresApi(Build.VERSION_CODES.O)
+ override fun captureScreenOnIdle(): Bitmap {
+ AndroidSemanticsTreeInteraction(throwOnRecomposeTimeOut = true, selector = { true })
+ .waitForIdleCompose()
+ val contentView = activityTestRule.activity.findViewById<ViewGroup>(android.R.id.content)
+
+ val screenRect = Rect.fromLTWH(
+ 0f,
+ 0f,
+ contentView.width.toFloat(),
+ contentView.height.toFloat()
+ )
+ return captureRegionToBitmap(screenRect, handler, activityTestRule.activity.window)
+ }
+
inner class AndroidComposeStatement(
private val base: Statement
) : Statement() {
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidInputDispatcher.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidInputDispatcher.kt
new file mode 100644
index 0000000..d7ab848
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidInputDispatcher.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test.android
+
+import android.os.Handler
+import android.os.Looper
+import android.os.SystemClock
+import android.view.MotionEvent
+import androidx.ui.core.Duration
+import androidx.ui.core.SemanticsTreeProvider
+import androidx.ui.core.inMilliseconds
+import androidx.ui.core.milliseconds
+import androidx.ui.lerp
+import androidx.ui.test.InputDispatcher
+import java.util.concurrent.CountDownLatch
+import kotlin.math.min
+import kotlin.math.roundToInt
+
+internal class AndroidInputDispatcher(
+ private val treeProvider: SemanticsTreeProvider
+) : InputDispatcher {
+ /**
+ * The minimum time between two successive injected MotionEvents. Ideally, the value should
+ * reflect a realistic pointer input sample rate, but that depends on too many factors. Instead,
+ * the value is chosen comfortably below the targeted frame rate (60 fps, equating to a 16ms
+ * period).
+ */
+ private val eventPeriod = 10.milliseconds.inMilliseconds()
+
+ private val handler = Handler(Looper.getMainLooper())
+
+ override fun sendClick(x: Float, y: Float) {
+ val downTime = SystemClock.uptimeMillis()
+ treeProvider.sendMotionEvent(downTime, downTime, MotionEvent.ACTION_DOWN, x, y)
+ treeProvider.sendMotionEvent(downTime, downTime + eventPeriod, MotionEvent.ACTION_UP, x, y)
+ }
+
+ override fun sendSwipe(x0: Float, y0: Float, x1: Float, y1: Float, duration: Duration) {
+ var step = 0
+ val steps = min(1, (duration.inMilliseconds() / eventPeriod.toFloat()).roundToInt())
+ val downTime = SystemClock.uptimeMillis()
+ val upTime = downTime + duration.inMilliseconds()
+
+ treeProvider.sendMotionEvent(downTime, downTime, MotionEvent.ACTION_DOWN, x0, y0)
+ while (step++ < steps) {
+ val progress = step / steps.toFloat()
+ val t = lerp(downTime, upTime, progress)
+ val x = lerp(x0, x1, progress)
+ val y = lerp(y0, y1, progress)
+ treeProvider.sendMotionEvent(downTime, t, MotionEvent.ACTION_MOVE, x, y)
+ }
+ treeProvider.sendMotionEvent(downTime, upTime, MotionEvent.ACTION_UP, x1, y1)
+ }
+
+ /**
+ * Sends an event with the given parameters. Method blocks depending on [waitUntilEventTime].
+ * @param waitUntilEventTime If `true`, blocks until [eventTime]
+ */
+ private fun SemanticsTreeProvider.sendMotionEvent(
+ downTime: Long,
+ eventTime: Long,
+ action: Int,
+ x: Float,
+ y: Float,
+ waitUntilEventTime: Boolean = true
+ ) {
+ if (waitUntilEventTime) {
+ val currTime = SystemClock.uptimeMillis()
+ if (currTime < eventTime) {
+ SystemClock.sleep(eventTime - currTime)
+ }
+ }
+ sendAndRecycleEvent(MotionEvent.obtain(downTime, eventTime, action, x, y, 0))
+ }
+
+ /**
+ * Sends the [event] to the [SemanticsTreeProvider] and [recycles][MotionEvent.recycle] it
+ * regardless of the result. This method blocks until the event is sent.
+ */
+ private fun SemanticsTreeProvider.sendAndRecycleEvent(event: MotionEvent) {
+ val latch = CountDownLatch(1)
+ handler.post {
+ try {
+ sendEvent(event)
+ } finally {
+ event.recycle()
+ latch.countDown()
+ }
+ }
+ latch.await()
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidSemanticsTreeInteraction.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidSemanticsTreeInteraction.kt
index 59feac9..d9a96a2 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidSemanticsTreeInteraction.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidSemanticsTreeInteraction.kt
@@ -20,13 +20,15 @@
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
+import android.graphics.Bitmap
+import android.os.Build
import android.os.Handler
import android.os.Looper
-import android.os.SystemClock
import android.view.Choreographer
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
+import androidx.annotation.RequiresApi
import androidx.compose.Recomposer
import androidx.test.espresso.Espresso
import androidx.test.espresso.NoMatchingViewException
@@ -38,6 +40,7 @@
import androidx.ui.core.px
import androidx.ui.core.semantics.SemanticsConfiguration
import androidx.ui.engine.geometry.Rect
+import androidx.ui.test.InputDispatcher
import androidx.ui.test.SemanticsNodeInteraction
import androidx.ui.test.SemanticsTreeInteraction
import java.util.concurrent.CountDownLatch
@@ -55,7 +58,7 @@
internal class AndroidSemanticsTreeInteraction internal constructor(
private val throwOnRecomposeTimeOut: Boolean,
private val selector: SemanticsConfiguration.() -> Boolean
-) : SemanticsTreeInteraction() {
+) : SemanticsTreeInteraction {
/**
* Whether after the latest performed action we waited for any pending changes in composition.
@@ -111,6 +114,11 @@
hadPendingChangesAfterLastAction = waitForIdleCompose()
}
+ override fun sendInput(action: (InputDispatcher) -> Unit) {
+ action(AndroidInputDispatcher(findActivityAndTreeProvider().treeProvider))
+ hadPendingChangesAfterLastAction = waitForIdleCompose()
+ }
+
/**
* Waits for Compose runtime to be idle - meaning it has no pending changes.
*
@@ -153,25 +161,6 @@
})
}
- override fun sendClick(x: Float, y: Float) {
- performAction { treeProvider ->
- val downTime = SystemClock.uptimeMillis()
- val eventDown = MotionEvent.obtain(
- downTime, downTime,
- MotionEvent.ACTION_DOWN, x, y, 0
- )
- treeProvider.sendEvent(eventDown)
- eventDown.recycle()
-
- val eventUp = MotionEvent.obtain(
- downTime, downTime + 10,
- MotionEvent.ACTION_UP, x, y, 0
- )
- treeProvider.sendEvent(eventUp)
- eventUp.recycle()
- }
- }
-
override fun contains(semanticsConfiguration: SemanticsConfiguration): Boolean {
waitForIdleCompose()
@@ -191,7 +180,6 @@
displayMetrics.widthPixels.px,
displayMetrics.heightPixels.px
)
-
val screenRect = Rect.fromLTWH(
0.px.value,
0.px.value,
@@ -203,6 +191,37 @@
screenRect.contains(rectangle.getBottomRight())
}
+ @RequiresApi(Build.VERSION_CODES.O)
+ override fun captureNodeToBitmap(node: SemanticsTreeNode): Bitmap {
+ val collectedInfo = findActivityAndTreeProvider()
+
+ // TODO: Share this code with contains() somehow?
+ val exists = collectedInfo.treeProvider
+ .getAllSemanticNodes()
+ .any { it.data == node.data }
+ if (!exists) {
+ throw AssertionError("The required node is no longer in the tree!")
+ }
+
+ if (collectedInfo.context !is Activity) {
+ // TODO(pavlis): Espresso might have the windows already somewhere internally ...
+ throw AssertionError("The context assigned to your composable holder view cannot be " +
+ "cast to Activity. So this function can't access its window to capture the " +
+ "bitmap.")
+ }
+ val window = collectedInfo.context.window
+
+ // TODO(pavlis): Consider doing assertIsDisplayed here. Will need to move things around.
+
+ // TODO(pavlis): Make sure that the Activity actually hosts the view. As in case of popup
+ // it wouldn't. This will require us rewriting the structure how we collect the nodes.
+
+ // TODO(pavlis): Add support for popups. So if we find composable hosted in popup we can
+ // grab its reference to its window (need to add a hook to popup).
+
+ return captureRegionToBitmap(node.globalRect!!, handler, window)
+ }
+
private fun findActivityAndTreeProvider(): CollectedInfo {
val viewForwarder = ViewForwarder()
@@ -281,4 +300,4 @@
val context: Context,
val treeProvider: SemanticsTreeProvider
)
-}
\ No newline at end of file
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/WindowCapture.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/WindowCapture.kt
new file mode 100644
index 0000000..e8573f0
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/WindowCapture.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test.android
+
+import android.graphics.Bitmap
+import android.os.Build
+import android.os.Handler
+import android.view.PixelCopy
+import android.view.Window
+import androidx.annotation.RequiresApi
+import androidx.ui.engine.geometry.Rect
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
+
+@RequiresApi(Build.VERSION_CODES.O)
+internal fun captureRegionToBitmap(
+ globalRect: Rect,
+ handler: Handler,
+ window: Window
+): Bitmap {
+ val destBitmap = Bitmap.createBitmap(
+ globalRect.width.roundToInt(),
+ globalRect.height.roundToInt(),
+ Bitmap.Config.ARGB_8888)
+
+ // TODO: This could go to some Android specific extensions.
+ val srcRect = android.graphics.Rect(
+ globalRect.left.roundToInt(),
+ globalRect.top.roundToInt(),
+ globalRect.right.roundToInt(),
+ globalRect.bottom.roundToInt())
+
+ val latch = CountDownLatch(1)
+ var copyResult = 0
+ val onCopyFinished = object : PixelCopy.OnPixelCopyFinishedListener {
+ override fun onPixelCopyFinished(result: Int) {
+ copyResult = result
+ latch.countDown()
+ }
+ }
+
+ PixelCopy.request(window, srcRect, destBitmap, onCopyFinished, handler)
+
+ if (!latch.await(1, TimeUnit.SECONDS)) {
+ throw AssertionError("Failed waiting for PixelCopy!")
+ }
+ if (copyResult != PixelCopy.SUCCESS) {
+ throw AssertionError("PixelCopy failed!")
+ }
+ return destBitmap
+}
diff --git a/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt b/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt
index c487f67..492e80d 100644
--- a/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt
+++ b/ui/ui-test/src/test/java/androidx/ui/test/FindersTests.kt
@@ -20,10 +20,12 @@
import androidx.ui.core.semantics.SemanticsConfiguration
import androidx.ui.core.semantics.getOrNull
import androidx.ui.semantics.SemanticsProperties
+import androidx.ui.semantics.accessibilityLabel
import androidx.ui.semantics.testTag
import androidx.ui.test.helpers.FakeSemanticsTreeInteraction
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
import org.junit.Test
+import java.lang.AssertionError
class FindersTests {
@Test
@@ -38,7 +40,7 @@
}
val foundNodes = findAll { getOrNull(SemanticsProperties.TestTag) == "myTestTag" }
- Truth.assertThat(foundNodes).isEmpty()
+ assertThat(foundNodes).isEmpty()
}
@Test
@@ -56,7 +58,7 @@
}
val foundNodes = findAll { getOrNull(SemanticsProperties.TestTag) == "myTestTag" }
- Truth.assertThat(foundNodes.map { it.semanticsTreeNode }).containsExactly(node1)
+ assertThat(foundNodes.map { it.semanticsTreeNode }).containsExactly(node1)
}
@Test
@@ -78,10 +80,70 @@
}
val foundNodes = findAll { getOrNull(SemanticsProperties.TestTag) == "myTestTag" }
- Truth.assertThat(foundNodes.map { it.semanticsTreeNode }).containsExactly(node1, node2)
+ assertThat(foundNodes.map { it.semanticsTreeNode }).containsExactly(node1, node2)
+ }
+
+ @Test
+ fun findByText_matches() {
+ semanticsTreeInteractionFactory = { selector ->
+ FakeSemanticsTreeInteraction(selector)
+ .withProperties(SemanticsConfiguration().also {
+ it.accessibilityLabel = "Hello World"
+ })
+ }
+
+ findByText("Hello World")
+ }
+
+ @Test(expected = AssertionError::class)
+ fun findByText_fails() {
+ semanticsTreeInteractionFactory = { selector ->
+ FakeSemanticsTreeInteraction(selector)
+ .withProperties(SemanticsConfiguration().also {
+ it.accessibilityLabel = "Hello World"
+ })
+ }
+
+ findByText("World")
+ }
+
+ @Test
+ fun findBySubstring_matches() {
+ semanticsTreeInteractionFactory = { selector ->
+ FakeSemanticsTreeInteraction(selector)
+ .withProperties(SemanticsConfiguration().also {
+ it.accessibilityLabel = "Hello World"
+ })
+ }
+
+ findBySubstring("World")
+ }
+
+ @Test
+ fun findBySubstring_ignoreCase_matches() {
+ semanticsTreeInteractionFactory = { selector ->
+ FakeSemanticsTreeInteraction(selector)
+ .withProperties(SemanticsConfiguration().also {
+ it.accessibilityLabel = "Hello World"
+ })
+ }
+
+ findBySubstring("world", ignoreCase = true)
+ }
+
+ @Test(expected = AssertionError::class)
+ fun findBySubstring_wrongCase_fails() {
+ semanticsTreeInteractionFactory = { selector ->
+ FakeSemanticsTreeInteraction(selector)
+ .withProperties(SemanticsConfiguration().also {
+ it.accessibilityLabel = "Hello World"
+ })
+ }
+
+ findBySubstring("world")
}
private fun newNode(properties: SemanticsConfiguration): SemanticsTreeNode {
- return SemanticsTreeNodeStub(/* data= */ properties)
+ return SemanticsTreeNodeStub(data = properties)
}
}
\ No newline at end of file
diff --git a/ui/ui-test/src/test/java/androidx/ui/test/helpers/FakeSemanticsTreeInteraction.kt b/ui/ui-test/src/test/java/androidx/ui/test/helpers/FakeSemanticsTreeInteraction.kt
index d580c4c..280390c 100644
--- a/ui/ui-test/src/test/java/androidx/ui/test/helpers/FakeSemanticsTreeInteraction.kt
+++ b/ui/ui-test/src/test/java/androidx/ui/test/helpers/FakeSemanticsTreeInteraction.kt
@@ -16,10 +16,12 @@
package androidx.ui.test.helpers
+import android.graphics.Bitmap
import androidx.ui.core.SemanticsTreeNode
import androidx.ui.core.SemanticsTreeProvider
import androidx.ui.core.semantics.SemanticsConfiguration
import androidx.ui.engine.geometry.Rect
+import androidx.ui.test.InputDispatcher
import androidx.ui.test.SemanticsNodeInteraction
import androidx.ui.test.SemanticsTreeInteraction
import androidx.ui.test.SemanticsTreeNodeStub
@@ -27,7 +29,7 @@
internal class FakeSemanticsTreeInteraction internal constructor(
private val selector: SemanticsConfiguration.() -> Boolean
-) : SemanticsTreeInteraction() {
+) : SemanticsTreeInteraction {
private lateinit var semanticsToUse: List<SemanticsNodeInteraction>
@@ -69,7 +71,7 @@
TODO("replace with host side interaction")
}
- override fun sendClick(x: Float, y: Float) {
+ override fun sendInput(action: (InputDispatcher) -> Unit) {
TODO("replace with host side interaction")
}
@@ -86,4 +88,8 @@
override fun waitForIdleCompose(): Boolean {
return semanticsTreeInteractionFactory(selector).waitForIdleCompose()
}
+
+ override fun captureNodeToBitmap(node: SemanticsTreeNode): Bitmap {
+ TODO("not implemented")
+ }
}
\ No newline at end of file
diff --git a/ui/ui-text/api/0.1.0-dev03.txt b/ui/ui-text/api/0.1.0-dev03.txt
index 36ba5b6..9bc931f 100644
--- a/ui/ui-text/api/0.1.0-dev03.txt
+++ b/ui/ui-text/api/0.1.0-dev03.txt
@@ -220,14 +220,14 @@
}
public static final class AnnotatedString.Item<T> {
- ctor public AnnotatedString.Item(T! style, int start, int end);
+ ctor public AnnotatedString.Item(T! item, int start, int end);
method public T! component1();
method public int component2();
method public int component3();
- method public androidx.ui.text.AnnotatedString.Item<T> copy(T! style, int start, int end);
+ method public androidx.ui.text.AnnotatedString.Item<T> copy(T! item, int start, int end);
method public int getEnd();
+ method public T! getItem();
method public int getStart();
- method public T! getStyle();
}
public final class AnnotatedStringKt {
diff --git a/ui/ui-text/api/current.txt b/ui/ui-text/api/current.txt
index 36ba5b6..9bc931f 100644
--- a/ui/ui-text/api/current.txt
+++ b/ui/ui-text/api/current.txt
@@ -220,14 +220,14 @@
}
public static final class AnnotatedString.Item<T> {
- ctor public AnnotatedString.Item(T! style, int start, int end);
+ ctor public AnnotatedString.Item(T! item, int start, int end);
method public T! component1();
method public int component2();
method public int component3();
- method public androidx.ui.text.AnnotatedString.Item<T> copy(T! style, int start, int end);
+ method public androidx.ui.text.AnnotatedString.Item<T> copy(T! item, int start, int end);
method public int getEnd();
+ method public T! getItem();
method public int getStart();
- method public T! getStyle();
}
public final class AnnotatedStringKt {
diff --git a/ui/ui-text/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-text/api/public_plus_experimental_0.1.0-dev03.txt
index 36ba5b6..9bc931f 100644
--- a/ui/ui-text/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-text/api/public_plus_experimental_0.1.0-dev03.txt
@@ -220,14 +220,14 @@
}
public static final class AnnotatedString.Item<T> {
- ctor public AnnotatedString.Item(T! style, int start, int end);
+ ctor public AnnotatedString.Item(T! item, int start, int end);
method public T! component1();
method public int component2();
method public int component3();
- method public androidx.ui.text.AnnotatedString.Item<T> copy(T! style, int start, int end);
+ method public androidx.ui.text.AnnotatedString.Item<T> copy(T! item, int start, int end);
method public int getEnd();
+ method public T! getItem();
method public int getStart();
- method public T! getStyle();
}
public final class AnnotatedStringKt {
diff --git a/ui/ui-text/api/public_plus_experimental_current.txt b/ui/ui-text/api/public_plus_experimental_current.txt
index 36ba5b6..9bc931f 100644
--- a/ui/ui-text/api/public_plus_experimental_current.txt
+++ b/ui/ui-text/api/public_plus_experimental_current.txt
@@ -220,14 +220,14 @@
}
public static final class AnnotatedString.Item<T> {
- ctor public AnnotatedString.Item(T! style, int start, int end);
+ ctor public AnnotatedString.Item(T! item, int start, int end);
method public T! component1();
method public int component2();
method public int component3();
- method public androidx.ui.text.AnnotatedString.Item<T> copy(T! style, int start, int end);
+ method public androidx.ui.text.AnnotatedString.Item<T> copy(T! item, int start, int end);
method public int getEnd();
+ method public T! getItem();
method public int getStart();
- method public T! getStyle();
}
public final class AnnotatedStringKt {
diff --git a/ui/ui-text/api/restricted_0.1.0-dev03.txt b/ui/ui-text/api/restricted_0.1.0-dev03.txt
index 8e81f5f..b3433b2 100644
--- a/ui/ui-text/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-text/api/restricted_0.1.0-dev03.txt
@@ -222,14 +222,14 @@
}
public static final class AnnotatedString.Item<T> {
- ctor public AnnotatedString.Item(T! style, int start, int end);
+ ctor public AnnotatedString.Item(T! item, int start, int end);
method public T! component1();
method public int component2();
method public int component3();
- method public androidx.ui.text.AnnotatedString.Item<T> copy(T! style, int start, int end);
+ method public androidx.ui.text.AnnotatedString.Item<T> copy(T! item, int start, int end);
method public int getEnd();
+ method public T! getItem();
method public int getStart();
- method public T! getStyle();
}
public final class AnnotatedStringKt {
diff --git a/ui/ui-text/api/restricted_current.txt b/ui/ui-text/api/restricted_current.txt
index 8e81f5f..b3433b2 100644
--- a/ui/ui-text/api/restricted_current.txt
+++ b/ui/ui-text/api/restricted_current.txt
@@ -222,14 +222,14 @@
}
public static final class AnnotatedString.Item<T> {
- ctor public AnnotatedString.Item(T! style, int start, int end);
+ ctor public AnnotatedString.Item(T! item, int start, int end);
method public T! component1();
method public int component2();
method public int component3();
- method public androidx.ui.text.AnnotatedString.Item<T> copy(T! style, int start, int end);
+ method public androidx.ui.text.AnnotatedString.Item<T> copy(T! item, int start, int end);
method public int getEnd();
+ method public T! getItem();
method public int getStart();
- method public T! getStyle();
}
public final class AnnotatedStringKt {
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
index 7cb184f..e12a544 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
@@ -1181,17 +1181,17 @@
val text = AnnotatedString(
text = "ab",
paragraphStyles = listOf(
- AnnotatedString.Item(
- style = ParagraphStyle(
+ ParagraphStyleSpan(
+ item = ParagraphStyle(
textDirectionAlgorithm = TextDirectionAlgorithm.ContentOrLtr
),
start = 0,
end = "a".length
),
- AnnotatedString.Item(
+ ParagraphStyleSpan(
// skip setting [TextDirectionAlgorithm] on purpose, should inherit from the
// main [ParagraphStyle]
- style = ParagraphStyle(),
+ item = ParagraphStyle(),
start = "a".length,
end = "ab".length
)
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntrinsicIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntrinsicIntegrationTest.kt
index 1ddfcf5..50eee9a 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntrinsicIntegrationTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntrinsicIntegrationTest.kt
@@ -101,8 +101,8 @@
text = text,
fontSize = fontSize,
textStyles = listOf(
- AnnotatedString.Item(
- style = TextStyle(fontSize = styledFontSize),
+ TextStyleSpan(
+ item = TextStyle(fontSize = styledFontSize),
start = "a ".length,
end = "a bb ".length
)
@@ -187,8 +187,8 @@
text = text,
fontSize = fontSize,
textStyles = listOf(
- AnnotatedString.Item(
- style = TextStyle(fontSize = styledFontSize),
+ TextStyleSpan(
+ item = TextStyle(fontSize = styledFontSize),
start = "a".length,
end = "a bb ".length
)
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt b/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt
index 4e835e8..88bc1cc 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/AnnotatedString.kt
@@ -21,13 +21,25 @@
import java.util.SortedSet
/**
+ * The class changes the character level style of the specified range.
+ * @see AnnotatedString.Builder
+ */
+typealias TextStyleSpan = Item<TextStyle>
+
+/**
+ * The class changes the paragraph level style of the specified range.
+ * @see AnnotatedString.Builder
+ */
+typealias ParagraphStyleSpan = Item<ParagraphStyle>
+
+/**
* The basic data structure of text with multiple styles. To construct an [AnnotatedString] you
* can use [Builder].
*/
data class AnnotatedString(
val text: String,
- val textStyles: List<Item<TextStyle>> = listOf(),
- val paragraphStyles: List<Item<ParagraphStyle>> = listOf()
+ val textStyles: List<TextStyleSpan> = listOf(),
+ val paragraphStyles: List<ParagraphStyleSpan> = listOf()
) {
init {
@@ -52,11 +64,11 @@
/**
* The information attached on the text such as a TextStyle.
*
- * @param style The style being applied on this part of [AnnotatedString]
- * @param start The start of the range where [style] takes effect. It's inclusive
- * @param end The end of the range where [style] takes effect. It's exclusive
+ * @param item The object attached to [AnnotatedString]s.
+ * @param start The start of the range where [item] takes effect. It's inclusive
+ * @param end The end of the range where [item] takes effect. It's exclusive
*/
- data class Item<T>(val style: T, val start: Int, val end: Int) {
+ data class Item<T>(val item: T, val start: Int, val end: Int) {
init {
require(start <= end) { "Reversed range is not supported" }
}
@@ -73,7 +85,7 @@
class Builder(capacity: Int = 16) {
private data class MutableItem<T>(
- val style: T,
+ val item: T,
val start: Int,
var end: Int = Int.MIN_VALUE
) {
@@ -85,7 +97,7 @@
fun toItem(defaultEnd: Int = Int.MIN_VALUE): Item<T> {
val end = if (end == Int.MIN_VALUE) defaultEnd else end
check(end != Int.MIN_VALUE) { "Item.end should be set first" }
- return Item(style = style, start = start, end = end)
+ return Item(item = item, start = start, end = end)
}
}
@@ -143,10 +155,10 @@
this.text.append(text.text)
// offset every style with start and add to the builder
text.textStyles.forEach {
- addStyle(it.style, start + it.start, start + it.end)
+ addStyle(it.item, start + it.start, start + it.end)
}
text.paragraphStyles.forEach {
- addStyle(it.style, start + it.start, start + it.end)
+ addStyle(it.item, start + it.start, start + it.end)
}
}
@@ -158,7 +170,7 @@
* @param end the exclusive end offset of the range
*/
fun addStyle(style: TextStyle, start: Int, end: Int) {
- textStyles.add(MutableItem(style = style, start = start, end = end))
+ textStyles.add(MutableItem(item = style, start = start, end = end))
}
/**
@@ -170,7 +182,7 @@
* @param end the exclusive end offset of the range
*/
fun addStyle(style: ParagraphStyle, start: Int, end: Int) {
- paragraphStyles.add(MutableItem(style = style, start = start, end = end))
+ paragraphStyles.add(MutableItem(item = style, start = start, end = end))
}
/**
@@ -182,7 +194,7 @@
* @param style TextStyle to be applied
*/
fun pushStyle(style: TextStyle): Int {
- MutableItem(style = style, start = text.length).also {
+ MutableItem(item = style, start = text.length).also {
styleStack.add(it)
textStyles.add(it)
}
@@ -198,7 +210,7 @@
* @param style ParagraphStyle to be applied
*/
fun pushStyle(style: ParagraphStyle): Int {
- MutableItem(style = style, start = text.length).also {
+ MutableItem(item = style, start = text.length).also {
styleStack.add(it)
paragraphStyles.add(it)
}
@@ -262,12 +274,12 @@
*/
internal fun AnnotatedString.normalizedParagraphStyles(
defaultParagraphStyle: ParagraphStyle
-): List<Item<ParagraphStyle>> {
+): List<ParagraphStyleSpan> {
val length = text.length
val paragraphStyles = paragraphStyles
var lastOffset = 0
- val result = mutableListOf<Item<ParagraphStyle>>()
+ val result = mutableListOf<ParagraphStyleSpan>()
for ((style, start, end) in paragraphStyles) {
if (start != lastOffset) {
result.add(Item(defaultParagraphStyle, lastOffset, start))
@@ -297,7 +309,7 @@
private fun AnnotatedString.getLocalStyles(
start: Int,
end: Int
-): List<Item<TextStyle>> {
+): List<TextStyleSpan> {
if (start == end) {
return listOf()
}
@@ -308,7 +320,7 @@
return textStyles.filter { it.start < end && it.end > start }
.map {
Item(
- it.style,
+ it.item,
it.start.coerceIn(start, end) - start,
it.end.coerceIn(start, end) - start
)
@@ -338,7 +350,7 @@
defaultParagraphStyle: ParagraphStyle,
crossinline block: (
annotatedString: AnnotatedString,
- paragraphStyle: Item<ParagraphStyle>
+ paragraphStyle: ParagraphStyleSpan
) -> T
): List<T> {
return normalizedParagraphStyles(defaultParagraphStyle).map { paragraphStyleItem ->
@@ -456,14 +468,14 @@
offsetMap.put(end, resultStr.length)
}
- val newTextStyles = mutableListOf<Item<TextStyle>>()
- val newParaStyles = mutableListOf<Item<ParagraphStyle>>()
+ val newTextStyles = mutableListOf<TextStyleSpan>()
+ val newParaStyles = mutableListOf<ParagraphStyleSpan>()
for (textStyle in textStyles) {
// The offset map must have mapping entry from all style start, end position.
newTextStyles.add(
Item(
- textStyle.style,
+ textStyle.item,
offsetMap[textStyle.start]!!,
offsetMap[textStyle.end]!!
)
@@ -473,7 +485,7 @@
for (paraStyle in paragraphStyles) {
newParaStyles.add(
Item(
- paraStyle.style,
+ paraStyle.item,
offsetMap[paraStyle.start]!!,
offsetMap[paraStyle.end]!!
)
@@ -577,7 +589,7 @@
(it.start == start) || !(it.end <= start || it.start >= end)
}.map {
Item(
- style = it.style,
+ item = it.item,
start = (if (it.start < start) start else it.start) - start,
end = (if (end < it.end) end else it.end) - start
)
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraphIntrinsics.kt b/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraphIntrinsics.kt
index 487adde..00faf94 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraphIntrinsics.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/MultiParagraphIntrinsics.kt
@@ -57,7 +57,7 @@
intrinsics = ParagraphIntrinsics(
text = annotatedString.text,
paragraphStyle = resolveTextDirection(
- paragraphStyleItem.style,
+ paragraphStyleItem.item,
paragraphStyle
),
textStyles = annotatedString.textStyles,
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt b/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt
index 06b1733..20f4e07 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt
@@ -205,7 +205,7 @@
for (textStyle in textStyles) {
val start = textStyle.start
val end = textStyle.end
- val style = textStyle.style
+ val style = textStyle.item
if (start < 0 || start >= text.length || end <= start || end > text.length) continue
diff --git a/ui/ui-text/src/test/java/androidx/ui/text/AnnotatedStringBuilderTest.kt b/ui/ui-text/src/test/java/androidx/ui/text/AnnotatedStringBuilderTest.kt
index a48d2c9..e1ff10f 100644
--- a/ui/ui-text/src/test/java/androidx/ui/text/AnnotatedStringBuilderTest.kt
+++ b/ui/ui-text/src/test/java/androidx/ui/text/AnnotatedStringBuilderTest.kt
@@ -148,26 +148,26 @@
val expectedString = "$text$appendedText"
val expectedTextStyles = listOf(
- AnnotatedString.Item(
- style = TextStyle(color),
+ TextStyleSpan(
+ item = TextStyle(color),
start = 0,
end = text.length
),
- AnnotatedString.Item(
- style = TextStyle(appendedColor),
+ TextStyleSpan(
+ item = TextStyle(appendedColor),
start = text.length,
end = expectedString.length
)
)
val expectedParagraphStyles = listOf(
- AnnotatedString.Item(
- style = ParagraphStyle(lineHeight = lineHeight),
+ ParagraphStyleSpan(
+ item = ParagraphStyle(lineHeight = lineHeight),
start = 0,
end = text.length
),
- AnnotatedString.Item(
- style = ParagraphStyle(lineHeight = appendedLineHeight),
+ ParagraphStyleSpan(
+ item = ParagraphStyle(lineHeight = appendedLineHeight),
start = text.length,
end = expectedString.length
)
@@ -190,7 +190,7 @@
assertThat(buildResult.text).isEqualTo(text)
assertThat(buildResult.textStyles).hasSize(1)
- assertThat(buildResult.textStyles[0].style).isEqualTo(style)
+ assertThat(buildResult.textStyles[0].item).isEqualTo(style)
assertThat(buildResult.textStyles[0].start).isEqualTo(0)
assertThat(buildResult.textStyles[0].end).isEqualTo(buildResult.length)
}
@@ -216,7 +216,7 @@
assertThat(buildResult.textStyles).hasSize(3)
styles.forEachIndexed { index, textStyle ->
- assertThat(buildResult.textStyles[index].style).isEqualTo(textStyle)
+ assertThat(buildResult.textStyles[index].item).isEqualTo(textStyle)
assertThat(buildResult.textStyles[index].end).isEqualTo(buildResult.length)
}
@@ -243,11 +243,11 @@
assertThat(buildResult.text).isEqualTo("Test me")
assertThat(buildResult.textStyles).hasSize(2)
- assertThat(buildResult.textStyles[0].style).isEqualTo(textStyle1)
+ assertThat(buildResult.textStyles[0].item).isEqualTo(textStyle1)
assertThat(buildResult.textStyles[0].start).isEqualTo(0)
assertThat(buildResult.textStyles[0].end).isEqualTo(buildResult.length)
- assertThat(buildResult.textStyles[1].style).isEqualTo(textStyle2)
+ assertThat(buildResult.textStyles[1].item).isEqualTo(textStyle2)
assertThat(buildResult.textStyles[1].start).isEqualTo("Test".length)
assertThat(buildResult.textStyles[1].end).isEqualTo(buildResult.length)
}
@@ -271,7 +271,7 @@
assertThat(buildResult.text).isEmpty()
assertThat(buildResult.textStyles).hasSize(3)
styles.forEachIndexed { index, textStyle ->
- assertThat(buildResult.textStyles[index].style).isEqualTo(textStyle)
+ assertThat(buildResult.textStyles[index].item).isEqualTo(textStyle)
assertThat(buildResult.textStyles[index].start).isEqualTo(buildResult.length)
assertThat(buildResult.textStyles[index].end).isEqualTo(buildResult.length)
}
@@ -305,7 +305,7 @@
assertThat(buildResult.textStyles).hasSize(4)
styles.forEachIndexed { index, textStyle ->
- assertThat(buildResult.textStyles[index].style).isEqualTo(textStyle)
+ assertThat(buildResult.textStyles[index].item).isEqualTo(textStyle)
}
}
@@ -338,7 +338,7 @@
assertThat(buildResult.textStyles).hasSize(4)
styles.forEachIndexed { index, textStyle ->
- assertThat(buildResult.textStyles[index].style).isEqualTo(textStyle)
+ assertThat(buildResult.textStyles[index].item).isEqualTo(textStyle)
}
}
@@ -368,11 +368,11 @@
assertThat(buildResult.textStyles).hasSize(2)
// the order is first applied is in the second
- assertThat(buildResult.textStyles[0].style).isEqualTo((textStyle1))
+ assertThat(buildResult.textStyles[0].item).isEqualTo((textStyle1))
assertThat(buildResult.textStyles[0].start).isEqualTo(("Style0".length))
assertThat(buildResult.textStyles[0].end).isEqualTo(("Style0Style1".length))
- assertThat(buildResult.textStyles[1].style).isEqualTo((textStyle2))
+ assertThat(buildResult.textStyles[1].item).isEqualTo((textStyle2))
assertThat(buildResult.textStyles[1].start).isEqualTo(("Style0Style1".length))
assertThat(buildResult.textStyles[1].end).isEqualTo(("Style0Style1Style2".length))
}
@@ -451,7 +451,7 @@
assertThat(buildResult.paragraphStyles).isEmpty()
assertThat(buildResult.textStyles).isEqualTo(
- listOf(AnnotatedString.Item(style, 0, buildResult.length))
+ listOf(TextStyleSpan(style, 0, buildResult.length))
)
}
@@ -467,7 +467,7 @@
assertThat(buildResult.textStyles).isEmpty()
assertThat(buildResult.paragraphStyles).isEqualTo(
- listOf(AnnotatedString.Item(style, 0, buildResult.length))
+ listOf(ParagraphStyleSpan(style, 0, buildResult.length))
)
}
@@ -506,12 +506,12 @@
val expectedString = "$text1 $text2"
val expectedTextStyles = listOf(
- AnnotatedString.Item(textStyle1, 0, text1.length),
- AnnotatedString.Item(textStyle2, text1.length + 1, expectedString.length)
+ TextStyleSpan(textStyle1, 0, text1.length),
+ TextStyleSpan(textStyle2, text1.length + 1, expectedString.length)
)
val expectedParagraphStyles = listOf(
- AnnotatedString.Item(paragraphStyle1, 0, text1.length),
- AnnotatedString.Item(paragraphStyle2, text1.length + 1, expectedString.length)
+ ParagraphStyleSpan(paragraphStyle1, 0, text1.length),
+ ParagraphStyleSpan(paragraphStyle2, text1.length + 1, expectedString.length)
)
assertThat(buildResult.text).isEqualTo(expectedString)
@@ -571,15 +571,15 @@
return AnnotatedString(
text = text,
textStyles = listOf(
- AnnotatedString.Item(
- style = TextStyle(color),
+ TextStyleSpan(
+ item = TextStyle(color),
start = 0,
end = text.length
)
),
paragraphStyles = listOf(
- AnnotatedString.Item(
- style = ParagraphStyle(lineHeight = lineHeight),
+ ParagraphStyleSpan(
+ item = ParagraphStyle(lineHeight = lineHeight),
start = 0,
end = text.length
)
diff --git a/ui/ui-text/src/test/java/androidx/ui/text/TextSpanTest.kt b/ui/ui-text/src/test/java/androidx/ui/text/TextSpanTest.kt
index 6d3988a..78d9250 100644
--- a/ui/ui-text/src/test/java/androidx/ui/text/TextSpanTest.kt
+++ b/ui/ui-text/src/test/java/androidx/ui/text/TextSpanTest.kt
@@ -164,7 +164,7 @@
// By default includeRootStyle = true and TextStyle on root node should be converted.
assertThat(annotatedString.textStyles.size).isEqualTo(1)
- assertThat(annotatedString.textStyles[0].style).isEqualTo(textStyle)
+ assertThat(annotatedString.textStyles[0].item).isEqualTo(textStyle)
assertThat(annotatedString.textStyles[0].start).isEqualTo(0)
assertThat(annotatedString.textStyles[0].end).isEqualTo(text.length)
}
@@ -202,11 +202,11 @@
assertThat(annotatedString.text).isEqualTo(text1 + text2)
assertThat(annotatedString.textStyles.size).isEqualTo(2)
- assertThat(annotatedString.textStyles[0].style).isEqualTo(textStyle1)
+ assertThat(annotatedString.textStyles[0].item).isEqualTo(textStyle1)
assertThat(annotatedString.textStyles[0].start).isEqualTo(0)
assertThat(annotatedString.textStyles[0].end).isEqualTo((text1 + text2).length)
- assertThat(annotatedString.textStyles[1].style).isEqualTo(textStyle2)
+ assertThat(annotatedString.textStyles[1].item).isEqualTo(textStyle2)
assertThat(annotatedString.textStyles[1].start).isEqualTo(text1.length)
assertThat(annotatedString.textStyles[1].end).isEqualTo((text1 + text2).length)
}
@@ -258,25 +258,25 @@
assertThat(annotatedString.text).isEqualTo(text1 + text2 + text3)
assertThat(annotatedString.textStyles.size).isEqualTo(5)
- assertThat(annotatedString.textStyles[0].style).isEqualTo(textStyleRoot)
+ assertThat(annotatedString.textStyles[0].item).isEqualTo(textStyleRoot)
assertThat(annotatedString.textStyles[0].start).isEqualTo(0)
assertThat(annotatedString.textStyles[0].end)
.isEqualTo((text1 + text2 + text3).length)
- assertThat(annotatedString.textStyles[1].style).isEqualTo(textStyleLeaf1)
+ assertThat(annotatedString.textStyles[1].item).isEqualTo(textStyleLeaf1)
assertThat(annotatedString.textStyles[1].start).isEqualTo(0)
assertThat(annotatedString.textStyles[1].end).isEqualTo(text1.length)
- assertThat(annotatedString.textStyles[2].style).isEqualTo(textStyleInner)
+ assertThat(annotatedString.textStyles[2].item).isEqualTo(textStyleInner)
assertThat(annotatedString.textStyles[2].start).isEqualTo(text1.length)
assertThat(annotatedString.textStyles[2].end)
.isEqualTo((text1 + text2 + text3).length)
- assertThat(annotatedString.textStyles[3].style).isEqualTo(textStyleLeaf2)
+ assertThat(annotatedString.textStyles[3].item).isEqualTo(textStyleLeaf2)
assertThat(annotatedString.textStyles[3].start).isEqualTo(text1.length)
assertThat(annotatedString.textStyles[3].end).isEqualTo((text1 + text2).length)
- assertThat(annotatedString.textStyles[4].style).isEqualTo(textStyleLeaf3)
+ assertThat(annotatedString.textStyles[4].item).isEqualTo(textStyleLeaf3)
assertThat(annotatedString.textStyles[4].start).isEqualTo((text1 + text2).length)
assertThat(annotatedString.textStyles[4].end)
.isEqualTo((text1 + text2 + text3).length)
diff --git a/versionedparcelable/annotation/build.gradle b/versionedparcelable/annotation/build.gradle
index 1d9c857..ce1c3e1 100644
--- a/versionedparcelable/annotation/build.gradle
+++ b/versionedparcelable/annotation/build.gradle
@@ -19,7 +19,7 @@
apply plugin: 'java'
dependencies {
- compile(JAVAPOET)
+ implementation(JAVAPOET)
}
// The "javadoc" task is unused so we don't want it to appear in the output of `./gradlew tasks`
diff --git a/webkit/integration-tests/testapp/README.md b/webkit/integration-tests/testapp/README.md
index 7e48107..34e18f1 100644
--- a/webkit/integration-tests/testapp/README.md
+++ b/webkit/integration-tests/testapp/README.md
@@ -10,7 +10,7 @@
cd frameworks/support/
# Optional: you can use Android Studio as your editor
-./studiow -y
+./studiow
# Build the app
./gradlew :webkit:integration-tests:testapp:assembleDebug
diff --git a/webkit/integration-tests/testapp/src/main/AndroidManifest.xml b/webkit/integration-tests/testapp/src/main/AndroidManifest.xml
index a31db81..845bc22 100644
--- a/webkit/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/webkit/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -102,5 +102,11 @@
<activity
android:name=".FullscreenActivity"
android:exported="true" />
+ <activity
+ android:name=".JsJavaInteractionActivity"
+ android:exported="true" />
+ <activity
+ android:name=".WebMessageListenerActivity"
+ android:exported="true" />
</application>
</manifest>
diff --git a/webkit/integration-tests/testapp/src/main/assets/www/web_message_listener.html b/webkit/integration-tests/testapp/src/main/assets/www/web_message_listener.html
new file mode 100644
index 0000000..11ed1b0
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/assets/www/web_message_listener.html
@@ -0,0 +1,83 @@
+<html>
+<!-- Copyright 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<head>
+ <script type="text/javascript">
+ let timestamp = 0;
+ replyObject.onmessage = function(event) {
+ document.getElementById("result").innerHTML = event.data;
+ };
+ // Send a message to app, so app could get a JsReplyProxy to reply back to JavaScript.
+ replyObject.postMessage("initialization");
+
+ const channel = new MessageChannel();
+ channel.port2.onmessage = function(event) {
+ document.getElementById("port_result").innerHTML = event.data;
+ };
+ replyWithMessagePortObject.postMessage("send port", [channel.port1]);
+
+ let messageCounter = 0;
+ multipleMessagesObject.addEventListener("message", function(event) {
+ const i = parseInt(event.data);
+ if (i < 4999) {
+ multipleMessagesObject.postMessage((i + 1).toString());
+ if (i % 100 === 0) {
+ const counterInfo = (messageCounter + i)+ " messages sent.";
+ document.getElementById("multiple_messages").innerHTML = counterInfo;
+ }
+ } else {
+ let average = (performance.now() - timestamp) / 5000;
+ let result = "Average time over 5000 messages: " + average.toFixed(2) + "ms.";
+ document.getElementById("multiple_messages").innerHTML = result;
+ messageCounter += i + 1;
+ document.getElementById("multiple_button").disabled = false;
+ }
+ });
+ function startPostMessage(e) {
+ e.preventDefault();
+ document.getElementById("multiple_button").disabled = true;
+ timestamp = performance.now();
+ multipleMessagesObject.postMessage("0");
+ }
+
+ function showToast(e) {
+ e.preventDefault();
+ const message = document.getElementById("toast_message").value;
+ toastObject.postMessage(message);
+ }
+ </script>
+</head>
+<body>
+ <h1>Web content (within WebView)</h1>
+ <div>
+ <span>Message from app: </span>
+ <span id="result" style="color:red">Not received.</span>
+ </div>
+ <div>
+ <span>Message from app (via MessagePort): </span>
+ <span id="port_result" style="color:red">Not received.</span>
+ </div>
+ <div>
+ <input value="toast!" id="toast_message">
+ <button type="button" onclick="showToast(event)">Show Toast</button>
+ </div>
+ <div>
+ <button id="multiple_button" type="button" onclick="startPostMessage(event)">
+ Send 5000 messages
+ </button>
+ <div id="multiple_messages"></div>
+ </div>
+</body>
+</html>
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/JsJavaInteractionActivity.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/JsJavaInteractionActivity.java
new file mode 100644
index 0000000..5f58f3e
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/JsJavaInteractionActivity.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.androidx.webkit;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+/**
+ * An {@link Activity} to exercise Js Java interaction related functionality.
+ */
+public class JsJavaInteractionActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_js_java_interaction);
+ setTitle(R.string.js_java_interaction_activity_title);
+ WebkitHelpers.appendWebViewVersionToTitle(this);
+
+ final Context activityContext = this;
+ MenuListView listView = findViewById(R.id.js_java_interaction_list);
+ MenuListView.MenuItem[] menuItems = new MenuListView.MenuItem[] {
+ new MenuListView.MenuItem(
+ getResources().getString(R.string.web_message_listener_activity_title),
+ new Intent(activityContext, WebMessageListenerActivity.class)),
+ };
+ listView.setItems(menuItems);
+ }
+}
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java
index 7c55bc6..f20cc0b 100644
--- a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java
@@ -66,6 +66,9 @@
new MenuListView.MenuItem(
getResources().getString(R.string.fullscreen_activity_title),
new Intent(activityContext, FullscreenActivity.class)),
+ new MenuListView.MenuItem(
+ getResources().getString(R.string.js_java_interaction_activity_title),
+ new Intent(activityContext, JsJavaInteractionActivity.class)),
};
listView.setItems(menuItems);
}
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/WebMessageListenerActivity.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/WebMessageListenerActivity.java
new file mode 100644
index 0000000..6ebec6e
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/WebMessageListenerActivity.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.androidx.webkit;
+
+import static androidx.webkit.WebViewAssetLoader.AssetsPathHandler;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.style.AbsoluteSizeSpan;
+import android.view.View;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebResourceResponse;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.webkit.JsReplyProxy;
+import androidx.webkit.WebMessageCompat;
+import androidx.webkit.WebMessagePortCompat;
+import androidx.webkit.WebViewAssetLoader;
+import androidx.webkit.WebViewCompat;
+import androidx.webkit.WebViewFeature;
+
+import java.util.Arrays;
+
+/**
+ * An {@link Activity} to exercise WebMessageListener related functionality.
+ */
+@SuppressLint("RestrictedApi")
+public class WebMessageListenerActivity extends AppCompatActivity {
+ private TextView mTextView;
+ private final Uri mExampleUri = new Uri.Builder()
+ .scheme("https")
+ .authority("example.com")
+ .appendPath("androidx_webkit")
+ .appendPath("example")
+ .appendPath("assets")
+ .build();
+ private Button mReplyProxyButton;
+ private Button mPortButton;
+
+ private static class MyWebViewClient extends WebViewClient {
+ private final WebViewAssetLoader mAssetLoader;
+
+ MyWebViewClient(WebViewAssetLoader loader) {
+ mAssetLoader = loader;
+ }
+
+ @Override
+ @RequiresApi(21)
+ public WebResourceResponse shouldInterceptRequest(WebView view,
+ WebResourceRequest request) {
+ return mAssetLoader.shouldInterceptRequest(request.getUrl());
+ }
+
+ @Override
+ @SuppressWarnings("deprecation") // use the old one for compatibility with all API levels.
+ public WebResourceResponse shouldInterceptRequest(WebView view, String request) {
+ return mAssetLoader.shouldInterceptRequest(Uri.parse(request));
+ }
+ }
+
+ private static class ReplyMessageListener implements WebViewCompat.WebMessageListener {
+ private final Context mContext;
+ private JsReplyProxy mReplyProxy;
+
+ ReplyMessageListener(Context context, Button button) {
+ mContext = context;
+ button.setOnClickListener((View v) -> {
+ if (mReplyProxy == null) return;
+ mReplyProxy.postMessage("ReplyProxy button clicked.");
+ });
+ }
+
+ @Override
+ public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
+ boolean isMainFrame, JsReplyProxy replyProxy) {
+ if (message.getData().equals("initialization")) {
+ mReplyProxy = replyProxy;
+ }
+ }
+ }
+
+ private static class MessagePortMessageListener implements WebViewCompat.WebMessageListener {
+ private final Context mContext;
+ private WebMessagePortCompat mPort;
+
+ MessagePortMessageListener(Context context, Button button) {
+ mContext = context;
+ button.setOnClickListener((View v) -> {
+ if (mPort == null) return;
+ mPort.postMessage(new WebMessageCompat("Port button clicked."));
+ });
+ }
+
+ @Override
+ public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
+ boolean isMainFrame, JsReplyProxy replyProxy) {
+ if (message.getData().equals("send port")) {
+ mPort = message.getPorts()[0];
+ }
+ }
+ }
+
+ private static class ToastMessageListener implements WebViewCompat.WebMessageListener {
+ private final Context mContext;
+
+ ToastMessageListener(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
+ boolean isMainFrame, JsReplyProxy replyProxy) {
+ Toast.makeText(mContext, "Toast: " + message.getData(), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private static class MultipleMessagesListener implements WebViewCompat.WebMessageListener {
+ private final Context mContext;
+ private final TextView mTextView;
+ private int mCounter = 0;
+
+ MultipleMessagesListener(Context context, TextView textView) {
+ mContext = context;
+ mTextView = textView;
+ }
+
+ @Override
+ public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
+ boolean isMainFrame, JsReplyProxy replyProxy) {
+ replyProxy.postMessage(message.getData());
+ mCounter++;
+ if (mCounter % 100 == 0) {
+ mTextView.setText(TextUtils.concat(
+ createNativeTitle(), "\n", "" + mCounter + " messages received."));
+ }
+ }
+ }
+
+ @SuppressLint("SetJavascriptEnabled")
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_web_message_listener);
+ setTitle(R.string.web_message_listener_activity_title);
+ WebkitHelpers.appendWebViewVersionToTitle(this);
+
+ // Use WebViewAssetLoader to load html page from app's assets.
+ WebViewAssetLoader assetLoader =
+ new WebViewAssetLoader.Builder()
+ .setDomain("example.com")
+ .addPathHandler(mExampleUri.getPath() + "/", new AssetsPathHandler(this))
+ .build();
+
+ mTextView = findViewById(R.id.textview);
+ mTextView.setText(createNativeTitle());
+
+ mReplyProxyButton = findViewById(R.id.button_reply_proxy);
+ mPortButton = findViewById(R.id.button_port);
+
+ WebView webView = findViewById(R.id.webview);
+ webView.setWebViewClient(new MyWebViewClient(assetLoader));
+ webView.getSettings().setJavaScriptEnabled(true);
+
+ // Add WebMessageListeners.
+ if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
+ WebViewCompat.addWebMessageListener(webView, "replyObject",
+ Arrays.asList("https://example.com"),
+ new ReplyMessageListener(this, mReplyProxyButton));
+ WebViewCompat.addWebMessageListener(webView, "replyWithMessagePortObject",
+ Arrays.asList("https://example.com"),
+ new MessagePortMessageListener(this, mPortButton));
+ WebViewCompat.addWebMessageListener(webView, "toastObject",
+ Arrays.asList("https://example.com"), new ToastMessageListener(this));
+ WebViewCompat.addWebMessageListener(webView, "multipleMessagesObject",
+ Arrays.asList("https://example.com"),
+ new MultipleMessagesListener(this, mTextView));
+ }
+
+ webView.loadUrl(
+ Uri.withAppendedPath(mExampleUri, "www/web_message_listener.html").toString());
+ }
+
+ private static CharSequence createNativeTitle() {
+ final String title = "Native View";
+ SpannableString ss = new SpannableString(title);
+ ss.setSpan(new AbsoluteSizeSpan(55, true), 0, title.length(),
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return ss;
+ }
+}
diff --git a/webkit/integration-tests/testapp/src/main/res/layout/activity_js_java_interaction.xml b/webkit/integration-tests/testapp/src/main/res/layout/activity_js_java_interaction.xml
new file mode 100644
index 0000000..aecae37
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/res/layout/activity_js_java_interaction.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/activity_js_java_interaction"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.example.androidx.webkit.MenuListView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/js_java_interaction_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+</LinearLayout>
diff --git a/webkit/integration-tests/testapp/src/main/res/layout/activity_web_message_listener.xml b/webkit/integration-tests/testapp/src/main/res/layout/activity_web_message_listener.xml
new file mode 100644
index 0000000..1c64937
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/res/layout/activity_web_message_listener.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/activity_web_message_listener"
+ android:orientation="vertical"
+ android:weightSum="3"
+ android:background="#FF0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <WebView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/webview"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="2"/>
+ <TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/textview"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+ <Button
+ android:id="@+id/button_reply_proxy"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:text="Reply via ReplyProxy" />
+ <Button
+ android:id="@+id/button_port"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button1"
+ android:text="Reply via Port" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/webkit/integration-tests/testapp/src/main/res/values/strings.xml b/webkit/integration-tests/testapp/src/main/res/values/strings.xml
index 7ac3fe6..d955806 100644
--- a/webkit/integration-tests/testapp/src/main/res/values/strings.xml
+++ b/webkit/integration-tests/testapp/src/main/res/values/strings.xml
@@ -70,4 +70,6 @@
<string name="renderer_terminated_description">WebView renderer was terminated.</string>
<string name="renderer_unresponsive_description">WebView renderer has become unresponsive.</string>
<string name="fullscreen_activity_title">Fullscreen web contents Demo</string>
+ <string name="js_java_interaction_activity_title">JavaScript - Java communication</string>
+ <string name="web_message_listener_activity_title">WebMessageListener Demo</string>
</resources>