Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smooth rotation on orientation change #162

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8a8e5c5
Update versions and version naming
JolandaVerhoef Mar 29, 2024
cdf76e0
Fixes #55. Latest ktlint and spotless do not complain about composabl…
JolandaVerhoef Mar 29, 2024
f366230
Merge branch 'main' into jv/cleanup
JolandaVerhoef Mar 29, 2024
bb84056
Get rid of lint warnings
JolandaVerhoef Mar 29, 2024
46a3b36
Fix Compose issues (mostly modifier order)
JolandaVerhoef Mar 29, 2024
297999f
Allow for a smooth rotation while running the app. Replaced the quick…
JolandaVerhoef Mar 29, 2024
ce9a178
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir Apr 19, 2024
24352dc
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir Apr 21, 2024
009a8b8
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir May 7, 2024
72fa358
Respond to display rotation so images and videos are captured in corr…
temcguir May 9, 2024
b0ae518
Reduce number of recompositions
temcguir May 8, 2024
73dcf43
Adjust source rotation relative to screen orientation inline
temcguir May 8, 2024
5867abb
apply spotless
temcguir May 9, 2024
778f611
Switch to using OrientationEventListener to set orientation of captur…
temcguir May 23, 2024
74256ab
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir May 23, 2024
10891dd
Rename DisplayRotation to DeviceRotation
temcguir May 23, 2024
7018558
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir May 24, 2024
7336f34
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir May 29, 2024
98baff4
Ensure orientation is initialized correctly
temcguir May 29, 2024
9832e2b
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir May 30, 2024
a93d753
Merge remote-tracking branch 'origin/main' into jv/rotation
temcguir Jun 5, 2024
f767fa5
Merge remote-tracking branch 'origin' into jv/rotation
temcguir Jun 11, 2024
71ce1ae
Rename setDisplayRotation -> setDeviceRotation in CameraUseCase
temcguir Jun 11, 2024
cbf4a78
Log device rotation changes in Camera coroutine
temcguir Jun 11, 2024
c63f30a
Restore previous rotation animation/system bars behavior in SmoothImm…
temcguir Jun 12, 2024
cf5094c
Make Modifier.rotateLayout apply immediately
temcguir Jun 12, 2024
b6165de
Make Modifier.rotatedLayout keep the layout of natural orientation
temcguir Jun 12, 2024
689b6ff
apply spotless
temcguir Jun 12, 2024
b0116ad
Merge remote-tracking branch 'origin' into jv/rotation
temcguir Jun 12, 2024
c777a3d
Pad bottom camera controls for insets
temcguir Jun 14, 2024
9d8aac5
Animate icons to rotate upright
temcguir Jun 15, 2024
54670bf
Animate quicksettings layout transitions
temcguir Jun 17, 2024
476d0b9
Make quicksettings centered after rotation
temcguir Jun 19, 2024
2e7eca9
Merge remote-tracking branch 'origin' into jv/rotation
temcguir Jun 19, 2024
b232e8d
Rotate audio amplitude icon when device is rotated
temcguir Jun 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 10 additions & 9 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,22 @@ plugins {
}

android {
compileSdk = libs.versions.compileSdk.get().toInt()
namespace = "com.google.jetpackcamera"
compileSdk = 34

defaultConfig {
applicationId = "com.google.jetpackcamera"
minSdk = 21
targetSdk = 34
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 1
versionName = "0.1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}

buildTypes {
getByName("debug") {
signingConfig = signingConfigs.getByName("debug")
}
release {
isMinifyEnabled = true
proguardFiles(
Expand All @@ -60,16 +59,18 @@ android {
jvmToolchain(17)
}
buildFeatures {
buildConfig = true
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.0"
kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
}
packagingOptions {
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
@Suppress("UnstableApiUsage")
testOptions {
managedDevices {
localDevices {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
<profileable android:shell="true"/>
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden|navigation|uiMode|smallestScreenSize"
android:exported="true"
android:screenOrientation="nosensor"
android:theme="@style/Theme.JetpackCamera">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/google/jetpackcamera/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
Expand Down Expand Up @@ -102,6 +103,7 @@ class MainActivity : ComponentActivity() {
}

is Success -> {
val previewMode = remember { getPreviewMode() }
// TODO(kimblebee@): add app setting to enable/disable dynamic color
JetpackCameraTheme(
darkTheme = isInDarkMode(uiState = uiState),
Expand All @@ -117,7 +119,7 @@ class MainActivity : ComponentActivity() {
) {
JcaApp(
onPreviewViewModel = { previewViewModel = it },
previewMode = getPreviewMode()
previewMode = previewMode
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import kotlinx.coroutines.flow.stateIn

@HiltViewModel
class MainActivityViewModel @Inject constructor(
val settingsRepository: SettingsRepository
settingsRepository: SettingsRepository
) : ViewModel() {
val uiState: StateFlow<MainActivityUiState> = settingsRepository.cameraAppSettings.map {
Success(it)
Expand All @@ -42,6 +42,6 @@ class MainActivityViewModel @Inject constructor(
}

sealed interface MainActivityUiState {
object Loading : MainActivityUiState
data object Loading : MainActivityUiState
data class Success(val cameraAppSettings: CameraAppSettings) : MainActivityUiState
}
15 changes: 9 additions & 6 deletions app/src/main/java/com/google/jetpackcamera/ui/JcaApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,21 @@ import com.google.jetpackcamera.ui.Routes.SETTINGS_ROUTE
fun JcaApp(
onPreviewViewModel: (PreviewViewModel) -> Unit,
/*TODO(b/306236646): remove after still capture*/
previewMode: PreviewMode
previewMode: PreviewMode,
modifier: Modifier = Modifier
) {
val permissionState =
rememberPermissionState(permission = Manifest.permission.CAMERA)

if (permissionState.status.isGranted) {
JetpackCameraNavHost(
onPreviewViewModel = onPreviewViewModel,
previewMode = previewMode
previewMode = previewMode,
modifier = modifier
)
} else {
CameraPermission(
modifier = Modifier.fillMaxSize(),
modifier = modifier.fillMaxSize(),
cameraPermissionState = permissionState
)
}
Expand All @@ -61,10 +63,11 @@ fun JcaApp(
@Composable
private fun JetpackCameraNavHost(
onPreviewViewModel: (PreviewViewModel) -> Unit,
navController: NavHostController = rememberNavController(),
previewMode: PreviewMode
previewMode: PreviewMode,
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController()
) {
NavHost(navController = navController, startDestination = PREVIEW_ROUTE) {
NavHost(navController = navController, startDestination = PREVIEW_ROUTE, modifier = modifier) {
composable(PREVIEW_ROUTE) {
PreviewScreen(
onPreviewViewModel = onPreviewViewModel,
Expand Down
24 changes: 12 additions & 12 deletions app/src/main/java/com/google/jetpackcamera/ui/PermissionsUi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import com.google.jetpackcamera.R

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun CameraPermission(modifier: Modifier = Modifier, cameraPermissionState: PermissionState) {
fun CameraPermission(cameraPermissionState: PermissionState, modifier: Modifier = Modifier) {
PermissionTemplate(
modifier = modifier,
permissionState = cameraPermissionState,
Expand All @@ -64,14 +64,14 @@ fun CameraPermission(modifier: Modifier = Modifier, cameraPermissionState: Permi
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun PermissionTemplate(
modifier: Modifier = Modifier,
permissionState: PermissionState,
onSkipPermission: (() -> Unit)? = null,
painter: Painter,
iconAccessibilityText: String,
title: String,
bodyText: String,
requestButtonText: String
requestButtonText: String,
modifier: Modifier = Modifier,
onSkipPermission: (() -> Unit)? = null
) {
Column(
modifier = modifier.background(MaterialTheme.colorScheme.primary),
Expand Down Expand Up @@ -110,7 +110,7 @@ fun PermissionTemplate(
}

@Composable
fun PermissionImage(modifier: Modifier = Modifier, painter: Painter, accessibilityText: String) {
fun PermissionImage(painter: Painter, accessibilityText: String, modifier: Modifier = Modifier) {
Box(modifier = modifier) {
Icon(
modifier = Modifier
Expand All @@ -126,9 +126,9 @@ fun PermissionImage(modifier: Modifier = Modifier, painter: Painter, accessibili
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun PermissionButtonSection(
modifier: Modifier = Modifier,
permissionState: PermissionState,
requestButtonText: String,
modifier: Modifier = Modifier,
onSkipPermission: (() -> Unit)?
) {
Box(modifier = modifier) {
Expand Down Expand Up @@ -159,9 +159,9 @@ fun PermissionButtonSection(
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun PermissionButton(
modifier: Modifier = Modifier,
permissionState: PermissionState,
requestButtonText: String
requestButtonText: String,
modifier: Modifier = Modifier
) {
Button(
modifier = modifier,
Expand All @@ -181,13 +181,13 @@ fun PermissionButton(
}

@Composable
fun PermissionText(modifier: Modifier = Modifier, title: String, bodyText: String) {
fun PermissionText(title: String, bodyText: String, modifier: Modifier = Modifier) {
Box(
modifier = modifier
.height(IntrinsicSize.Min)
) {
Column(
modifier = modifier
modifier = Modifier
.fillMaxSize()
.align(Alignment.Center)
) {
Expand All @@ -213,7 +213,7 @@ fun PermissionText(modifier: Modifier = Modifier, title: String, bodyText: Strin
}

@Composable
fun PermissionTitleText(modifier: Modifier = Modifier, text: String, color: Color) {
fun PermissionTitleText(text: String, color: Color, modifier: Modifier = Modifier) {
Text(
modifier = modifier,
color = color,
Expand All @@ -224,7 +224,7 @@ fun PermissionTitleText(modifier: Modifier = Modifier, text: String, color: Colo
}

@Composable
fun PermissionBodyText(modifier: Modifier = Modifier, text: String, color: Color) {
fun PermissionBodyText(text: String, color: Color, modifier: Modifier = Modifier) {
Text(
modifier = modifier,
color = color,
Expand Down
5 changes: 3 additions & 2 deletions benchmark/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ plugins {

android {
namespace = "com.google.jetpackcamera.benchmark"
compileSdk = 34
compileSdk = libs.versions.compileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
Expand All @@ -35,7 +35,7 @@ android {
defaultConfig {
//Our app has a minSDK of 21, but in order for the benchmark tool to function, it must be 23
minSdk = 23
targetSdk = 34
targetSdk = libs.versions.targetSdk.get().toInt()

// allows the benchmark to be run on an emulator
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] =
Expand All @@ -56,6 +56,7 @@ android {
}

targetProjectPath = ":app"
@Suppress("UnstableApiUsage")
experimentalProperties["android.experimental.self-instrumenting"] = true
// required for benchmark:
// self instrumentation required for the tests to be able to compile, start, or kill the app
Expand Down
10 changes: 10 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,14 @@ gradle.taskGraph.whenReady {
task.dependsOn(tasks["installGitHooks"])
}
}
}

// Task to print all the module paths in the project e.g. :core:data
// Used by module graph generator script
tasks.register("printModulePaths") {
subprojects {
if (subprojects.size == 0) {
println(this.path)
}
}
}
7 changes: 4 additions & 3 deletions core/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ plugins {

android {
namespace = "com.google.jetpackcamera.core.common"
compileSdk = 34
compileSdk = libs.versions.compileSdk.get().toInt()

defaultConfig {
minSdk = 21
targetSdk = 34
minSdk = libs.versions.minSdk.get().toInt()
testOptions.targetSdk = libs.versions.targetSdk.get().toInt()
lint.targetSdk = libs.versions.targetSdk.get().toInt()

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
Expand Down
8 changes: 5 additions & 3 deletions data/settings/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ plugins {

android {
namespace = "com.google.jetpackcamera.data.settings"
compileSdk = 34
compileSdk = libs.versions.compileSdk.get().toInt()

defaultConfig {
minSdk = 21
targetSdk = 34
minSdk = libs.versions.minSdk.get().toInt()
testOptions.targetSdk = libs.versions.targetSdk.get().toInt()
lint.targetSdk = libs.versions.targetSdk.get().toInt()

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
Expand All @@ -51,6 +52,7 @@ android {
jvmToolchain(17)
}

@Suppress("UnstableApiUsage")
testOptions {
managedDevices {
localDevices {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ enum class AspectRatio(val ratio: Rational) {
/** returns the AspectRatio enum equivalent of a provided AspectRatioProto */
fun fromProto(aspectRatioProto: AspectRatioProto): AspectRatio {
return when (aspectRatioProto) {
AspectRatioProto.ASPECT_RATIO_NINE_SIXTEEN -> AspectRatio.NINE_SIXTEEN
AspectRatioProto.ASPECT_RATIO_ONE_ONE -> AspectRatio.ONE_ONE
AspectRatioProto.ASPECT_RATIO_NINE_SIXTEEN -> NINE_SIXTEEN
AspectRatioProto.ASPECT_RATIO_ONE_ONE -> ONE_ONE

// defaults to 3:4 aspect ratio
AspectRatioProto.ASPECT_RATIO_THREE_FOUR,
AspectRatioProto.ASPECT_RATIO_UNDEFINED,
AspectRatioProto.UNRECOGNIZED
-> AspectRatio.THREE_FOUR
-> THREE_FOUR
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions domain/camera/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ plugins {

android {
namespace = "com.google.jetpackcamera.data.camera"
compileSdk = 34
compileSdk = libs.versions.compileSdk.get().toInt()

defaultConfig {
minSdk = 21
targetSdk = 34
minSdk = libs.versions.minSdk.get().toInt()
testOptions.targetSdk = libs.versions.targetSdk.get().toInt()
lint.targetSdk = libs.versions.targetSdk.get().toInt()

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
Expand Down Expand Up @@ -55,8 +56,8 @@ dependencies {
// Testing
testImplementation(libs.junit)
testImplementation(libs.truth)
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
testImplementation("org.mockito:mockito-core:5.2.0")
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.mockito.core)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)

Expand All @@ -74,7 +75,7 @@ dependencies {
kapt(libs.dagger.hilt.compiler)

// Tracing
implementation("androidx.tracing:tracing-ktx:1.2.0")
implementation(libs.androidx.tracing)

// Project dependencies
implementation(project(":data:settings"))
Expand Down
2 changes: 1 addition & 1 deletion domain/camera/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@ class FakeCameraUseCase(
override fun getZoomScale(): StateFlow<Float> = _zoomScale.asStateFlow()

private val _surfaceRequest = MutableStateFlow<SurfaceRequest?>(null)
fun setSurfaceRequest(surfaceRequest: SurfaceRequest) {
_surfaceRequest.value = surfaceRequest
}
override fun getSurfaceRequest(): StateFlow<SurfaceRequest?> = _surfaceRequest.asStateFlow()

override fun getScreenFlashEvents() = screenFlashEvents
Expand Down
Loading
Loading