Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f6e15d0
Initial CustomizeExportScreen.kt
riggaroo Jul 4, 2025
f85b5ef
Add GenericTool and Tool options for ratio and background.
riggaroo Jul 4, 2025
90c4a86
Add GenericTool and Tool options for ratio and background.
riggaroo Jul 4, 2025
01bca3a
Setup Background tool and Aspect ratio tools to render correctly.
riggaroo Jul 4, 2025
5f08b44
Spotless
riggaroo Jul 4, 2025
8851abe
Large screen layout optimizations
riggaroo Jul 7, 2025
095cd85
Large screen layout optimizations
riggaroo Jul 7, 2025
9cd777d
Large screen layout optimizations
riggaroo Jul 7, 2025
e601d21
Basic offscreen rendering implementation.
riggaroo Jul 9, 2025
3f44474
Basic offscreen rendering implementation.
riggaroo Jul 9, 2025
54eeacc
Fix KSP warning
riggaroo Jul 9, 2025
95171db
Clean up aspect ratio code, dont make it smaller and smaller in size.
riggaroo Jul 9, 2025
80e0c6d
Remove custom aspect ratio and create option for now
riggaroo Jul 10, 2025
79d667d
Add background presets
riggaroo Jul 10, 2025
6da4679
More background tweaks to fit the content in the correct area.
riggaroo Jul 10, 2025
2b416ae
Fixing up the backgrounds and export image size to match the aspect R…
riggaroo Jul 10, 2025
c7cc647
Merge branch 'main' into feature/customize-export
riggaroo Jul 10, 2025
e624ea7
Code review comments
riggaroo Jul 10, 2025
a188f34
Code review comments
riggaroo Jul 10, 2025
1b8f218
Build fixes
riggaroo Jul 10, 2025
02fb993
Build fixes
riggaroo Jul 10, 2025
15f2177
Redo logic around sizing and positioning of droid on top of content t…
riggaroo Jul 11, 2025
4375b10
Spotless
riggaroo Jul 11, 2025
2a68733
Logic fixes for keeping the selected background option when moving in…
riggaroo Jul 14, 2025
2da9f95
Merge branch 'main' into feature/customize-export
riggaroo Jul 14, 2025
f884baf
spotless
riggaroo Jul 14, 2025
ff22caa
Create FakeComposableBitmapRenderer.kt and fix CustomizeExportViewMod…
riggaroo Jul 14, 2025
620b43d
Remove snapshot dependencies
riggaroo Jul 15, 2025
02f752b
Add a "plain" option for exporting images
riggaroo Jul 15, 2025
308a759
Lint debug
riggaroo Jul 15, 2025
cea9ee0
Added CustomizeStateTest.kt
riggaroo Jul 16, 2025
9a363a9
[WIP] add animateBounds on CustomizeExportScreen.kt
riggaroo Jul 16, 2025
8367bd2
[WIP] add animateBounds on CustomizeExportScreen.kt
riggaroo Jul 16, 2025
9706213
[WIP] add animateBounds on CustomizeExportScreen.kt
riggaroo Jul 17, 2025
b21b17c
Spotless
riggaroo Jul 17, 2025
0c67e2d
Fixed up ratio change animations.
riggaroo Jul 17, 2025
f629ffe
Spotless
riggaroo Jul 17, 2025
63e9558
CustomizeExportScreen.kt properly support large screen with weights
riggaroo Jul 17, 2025
ba7612f
CustomizeExportScreen.kt properly support large screen with weights
riggaroo Jul 17, 2025
4184076
CustomizeExportScreen.kt properly support large screen with weights
riggaroo Jul 17, 2025
ba74146
Merge branch 'feature/customize-export' of https://github.com/android…
riggaroo Jul 17, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package com.android.developers.androidify

import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.WindowManager
import android.window.TrustedPresentationThresholds
import androidx.activity.ComponentActivity
Expand Down Expand Up @@ -73,15 +72,17 @@ class MainActivity : ComponentActivity() {
val minFractionRendered = 0.25f
val stabilityRequirements = 500
val presentationThreshold = TrustedPresentationThresholds(
minAlpha, minFractionRendered, stabilityRequirements
minAlpha,
minFractionRendered,
stabilityRequirements,
)

val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
windowManager.registerTrustedPresentationListener(
window.decorView.windowToken,
presentationThreshold,
mainExecutor,
presentationListener
presentationListener,
)
}
}
Expand All @@ -93,5 +94,4 @@ class MainActivity : ComponentActivity() {
windowManager.unregisterTrustedPresentationListener(presentationListener)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import androidx.compose.animation.scaleOut
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand Down Expand Up @@ -121,7 +120,7 @@ fun MainNavigation() {
},
onLicensesClicked = {
context.startActivity(Intent(context, OssLicensesMenuActivity::class.java))
}
},
)
}
},
Expand Down
203 changes: 148 additions & 55 deletions core/network/src/main/res/xml/remote_config_defaults.xml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions core/testing/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ dependencies {
implementation(projects.data)
implementation(projects.core.network)
implementation(projects.core.util)
implementation(projects.feature.results)

ksp(libs.hilt.compiler)

androidTestImplementation(platform(libs.androidx.compose.bom))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/*
* Copyright 2025 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
*
* https://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.android.developers.testing.repository

import android.net.Uri
Expand All @@ -18,7 +33,5 @@ class FakeDropImageFactory : DropBehaviourFactory {
override fun onDrop(event: DragAndDropEvent): Boolean {
return false
}

}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2025 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
*
* https://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.android.developers.testing.util

import android.graphics.Bitmap
import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Size
import androidx.core.graphics.createBitmap
import com.android.developers.androidify.customize.ComposableBitmapRenderer

class FakeComposableBitmapRenderer : ComposableBitmapRenderer {
override fun initialize() {
}

override fun dispose() {
}

override suspend fun renderComposableToBitmap(
canvasSize: Size,
composableContent: @Composable (() -> Unit),
): Bitmap? {
return createBitmap(1, 1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Matrix
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.layout.LookaheadScope
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
Expand All @@ -77,6 +78,10 @@ val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope> {
throw IllegalStateException("No SharedTransitionScope provided")
}

val LocalAnimateBoundsScope = compositionLocalOf<LookaheadScope?> {
null
}

@OptIn(
ExperimentalMaterial3ExpressiveApi::class,
ExperimentalSharedTransitionApi::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import com.android.developers.androidify.theme.sharedBoundsReveal
@OptIn(ExperimentalMaterial3Api::class)
fun AndroidifyTopAppBar(
modifier: Modifier = Modifier,
titleText: String = stringResource(R.string.androidify_title),
isMediumWindowSize: Boolean = false,
backEnabled: Boolean = false,
aboutEnabled: Boolean = true,
Expand Down Expand Up @@ -84,7 +85,7 @@ fun AndroidifyTopAppBar(
} else {
Spacer(modifier.size(16.dp))
}
AndroidifyTitle()
AndroidifyTitle(titleText)
}

Box(
Expand All @@ -109,7 +110,7 @@ fun AndroidifyTopAppBar(
} else {
CenterAlignedTopAppBar(
title = {
AndroidifyTitle()
AndroidifyTitle(titleText)
},
modifier = modifier
.statusBarsPadding()
Expand Down Expand Up @@ -146,13 +147,14 @@ private fun BackButton(onBackPressed: () -> Unit) {
@Composable
fun AndroidifyTranslucentTopAppBar(
modifier: Modifier = Modifier,
titleText: String = stringResource(R.string.androidify_title),
isMediumSizeLayout: Boolean = false,
) {
if (isMediumSizeLayout) {
TopAppBar(
title = {
Spacer(Modifier.statusBarsPadding())
AndroidifyTitle()
AndroidifyTitle(titleText)
},
modifier = modifier.clip(
MaterialTheme.shapes.large.copy(topStart = CornerSize(0f), topEnd = CornerSize(0f)),
Expand All @@ -163,7 +165,7 @@ fun AndroidifyTranslucentTopAppBar(
CenterAlignedTopAppBar(
title = {
Spacer(Modifier.statusBarsPadding())
AndroidifyTitle()
AndroidifyTitle(titleText)
},
modifier = modifier.clip(
MaterialTheme.shapes.large.copy(topStart = CornerSize(0f), topEnd = CornerSize(0f)),
Expand All @@ -174,8 +176,8 @@ fun AndroidifyTranslucentTopAppBar(
}

@Composable
private fun AndroidifyTitle() {
Text(stringResource(R.string.androidify_title), fontWeight = FontWeight.Bold)
private fun AndroidifyTitle(text: String) {
Text(text, fontWeight = FontWeight.Bold)
}

@OptIn(ExperimentalSharedTransitionApi::class)
Expand Down
28 changes: 28 additions & 0 deletions core/theme/src/main/res/drawable/outline_share_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 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

https://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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="960"
android:viewportHeight="960">

<path
android:fillColor="@android:color/white"
android:pathData="M680,880Q630,880 595,845Q560,810 560,760Q560,754 563,732L282,568Q266,583 245,591.5Q224,600 200,600Q150,600 115,565Q80,530 80,480Q80,430 115,395Q150,360 200,360Q224,360 245,368.5Q266,377 282,392L563,228Q561,221 560.5,214.5Q560,208 560,200Q560,150 595,115Q630,80 680,80Q730,80 765,115Q800,150 800,200Q800,250 765,285Q730,320 680,320Q656,320 635,311.5Q614,303 598,288L317,452Q319,459 319.5,465.5Q320,472 320,480Q320,488 319.5,494.5Q319,501 317,508L598,672Q614,657 635,648.5Q656,640 680,640Q730,640 765,675Q800,710 800,760Q800,810 765,845Q730,880 680,880ZM680,800Q697,800 708.5,788.5Q720,777 720,760Q720,743 708.5,731.5Q697,720 680,720Q663,720 651.5,731.5Q640,743 640,760Q640,777 651.5,788.5Q663,800 680,800ZM200,520Q217,520 228.5,508.5Q240,497 240,480Q240,463 228.5,451.5Q217,440 200,440Q183,440 171.5,451.5Q160,463 160,480Q160,497 171.5,508.5Q183,520 200,520ZM680,240Q697,240 708.5,228.5Q720,217 720,200Q720,183 708.5,171.5Q697,160 680,160Q663,160 651.5,171.5Q640,183 640,200Q640,217 651.5,228.5Q663,240 680,240ZM680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760ZM200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480ZM680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Z" />

</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ interface LocalFileProvider {
@Singleton
class LocalFileProviderImpl @Inject constructor(
private val application: Application,
@Named("IO") private val ioDispatcher: CoroutineDispatcher
@Named("IO") private val ioDispatcher: CoroutineDispatcher,
) : LocalFileProvider {

override suspend fun saveBitmapToFile(bitmap: Bitmap, file: File) = withContext(ioDispatcher) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
/*
* Copyright 2025 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
*
* https://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.android.developers.androidify.util

import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateOf

val LocalOcclusion = compositionLocalOf { mutableStateOf(false) }

Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/*
* Copyright 2025 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
*
* https://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.android.developers.androidify.data

import android.graphics.BitmapFactory
Expand All @@ -13,7 +28,6 @@ import kotlinx.coroutines.launch
import java.util.UUID
import javax.inject.Inject


interface DropBehaviourFactory {
fun shouldStartDragAndDrop(event: DragAndDropEvent): Boolean
fun createTargetCallback(
Expand Down Expand Up @@ -83,4 +97,4 @@ class DropBehaviourFactoryImpl @Inject constructor(val localFileProvider: LocalF
return true
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ package com.android.developers.androidify.creation
import android.net.Uri
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
Expand Down Expand Up @@ -68,7 +69,6 @@ import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ButtonDefaults
Expand Down Expand Up @@ -127,6 +127,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade
import com.android.developers.androidify.customize.CustomizeAndExportScreen
import com.android.developers.androidify.customize.CustomizeExportViewModel
import com.android.developers.androidify.data.DropBehaviourFactory
import com.android.developers.androidify.results.ResultsScreen
import com.android.developers.androidify.theme.AndroidifyTheme
Expand Down Expand Up @@ -228,8 +230,27 @@ fun CreationScreen(
viewModel = hiltViewModel(key = key),
onAboutPress = onAboutPressed,
onBackPress = onBackPressed,
onNextPress = creationViewModel::customizeExportClicked,
)
}

ScreenState.CUSTOMIZE -> {
val prompt = uiState.descriptionText.text.toString()
val key = if (uiState.descriptionText.text.isBlank()) {
uiState.imageUri.toString()
} else {
prompt
}
uiState.resultBitmap?.let { bitmap ->
CustomizeAndExportScreen(
resultImage = bitmap,
originalImageUri = uiState.imageUri,
onBackPress = onBackPressed,
onInfoPress = onAboutPressed,
viewModel = hiltViewModel<CustomizeExportViewModel>(key = key),
)
}
}
}
}

Expand Down Expand Up @@ -416,7 +437,7 @@ private fun MainCreationPane(
val alternateDropAreaBackgroundColor = MaterialTheme.colorScheme.surfaceVariant
var background by remember { mutableStateOf(defaultDropAreaBackgroundColor) }

val activity = LocalContext.current as ComponentActivity
val activity = LocalActivity.current as ComponentActivity
val externalAppCallback = remember {
dropBehaviourFactory.createTargetCallback(
activity = activity,
Expand All @@ -426,7 +447,6 @@ private fun MainCreationPane(
)
}


Box(
modifier = modifier,
) {
Expand Down
Loading