Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
chikoski authored Aug 22, 2023
2 parents 5a3bcae + 39741e7 commit 3b52a22
Show file tree
Hide file tree
Showing 253 changed files with 2,777 additions and 380 deletions.
91 changes: 91 additions & 0 deletions ActivityEmbeddingWithPredictiveBack/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2023 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.
*/

plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}

android {
namespace 'com.google.sample.ae.pb'
compileSdk 33

defaultConfig {
applicationId "com.google.sample.ae.pb"
minSdk 24
targetSdk 33
versionCode 1
versionName "1.0"

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

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.3.2'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.activity:activity-compose:1.6.1'

implementation "androidx.window:window:1.1.0-alpha04"
implementation "androidx.activity:activity:1.6.1"
implementation "androidx.startup:startup-runtime:1.1.1"

implementation platform('androidx.compose:compose-bom:2022.10.00')
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.compose.material3:material3'
implementation platform('androidx.compose:compose-bom:2022.10.00')

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00')
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00')

debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ActivityEmbeddingAndPredictiveBack"
android:enableOnBackInvokedCallback="true"
tools:targetApi="31">
<activity
android:name=".PlaceholderActivity"
android:exported="false"
android:label="@string/title_activity_placeholder"
android:theme="@style/Theme.ActivityEmbeddingAndPredictiveBack" />
<activity
android:name=".MainActivity"
android:exported="true"
android:resizeableActivity="true"
android:theme="@style/Theme.ActivityEmbeddingAndPredictiveBack">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">

<!-- This entry makes ExampleWindowInitializer discoverable. -->
<meta-data
android:name="com.google.sample.ae.pb.WindowInitializer"
android:value="androidx.startup" />
</provider>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* Copyright (C) 2023 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.google.sample.ae.pb

import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.sample.ae.pb.ui.theme.ActivityEmbeddingAndPredictiveBackTheme

/***
* This sample is an implementation of Activity Embedding API
* (https://developer.android.com/guide/topics/large-screens/activity-embedding) with a focus on
* embedding another app when there is enough space on the screen.
*
* It will also show how to start another app in multi-window mode from the host app.
*/

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
ActivityEmbeddingAndPredictiveBackTheme {
Surface(
modifier = Modifier.fillMaxSize(),
) {
HostUi(
multiWindow = this::launchSecondActivityInMultiWindow,
activityEmbedding = this::launchSecondActivityEmbedded
)
}
}
}
}

/***
* This method launches the embedded app with Activity Embedding API, so that on areas wider
* than 600dp two activities can be displayed at the same time. On smaller areas the embedded
* activity will just open at full screen.
*/
private fun launchSecondActivityEmbedded() {
val intent = Intent().apply {
component = ComponentName(
"com.google.sample.ae.guestapp",
"com.google.sample.ae.guestapp.MainGuestActivity"
)
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
startActivity(intent)
}

/***
* This method launches the target Activity in Multi-Window mode: it will split the screen in
* half - either vertically on compact screens, or horizontally on medium and expanded screens -
* and display the two activities side by side
*/
private fun launchSecondActivityInMultiWindow() {
val intent = Intent().apply {
component = ComponentName(
"com.google.sample.ae.guestapp",
"com.google.sample.ae.guestapp.MainGuestActivity"
)
addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
}
startActivity(intent)
}
}

@Composable
fun HostUi(
modifier: Modifier = Modifier,
multiWindow: () -> Unit = {},
activityEmbedding: () -> Unit = {}
) {

Column(
modifier = modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.secondary),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(R.string.host_app_message),
color = MaterialTheme.colorScheme.onSecondary,
style = MaterialTheme.typography.headlineMedium
)

Spacer(modifier = Modifier.height(24.dp))

Button(onClick = activityEmbedding) {
Text(text = stringResource(R.string.activity_embedding_message))
}

Spacer(modifier = Modifier.height(24.dp))

Button(onClick = multiWindow) {
Text(text = stringResource(R.string.multi_window_message))
}
}
}

@Preview(name = "EXPANDED", showBackground = true, widthDp = 840)
@Preview(name = "COMPACT", showBackground = true, showSystemUi = true)
annotation class UiPreview

@UiPreview
@Composable
fun SmallUiPreview() {
ActivityEmbeddingAndPredictiveBackTheme {
HostUi()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2023 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.google.sample.ae.pb

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.google.sample.ae.pb.ui.theme.ActivityEmbeddingAndPredictiveBackTheme

/***
* This Activity will be displayed alongside with the host one on areas wider than 600dp, as a
* placeholder for where the guest activity will be displayed. On areas smaller than 600dp this
* Activity will not be displayed at all.
*/
class PlaceholderActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ActivityEmbeddingAndPredictiveBackTheme {
Surface(
modifier = Modifier.fillMaxSize()
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.tertiary),
contentAlignment = Alignment.Center
) {
Text(
text = "I'm a placeholder!",
color = MaterialTheme.colorScheme.onTertiary,
style = MaterialTheme.typography.headlineMedium
)
}
}
}
}
}
}
Loading

0 comments on commit 3b52a22

Please sign in to comment.