Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 6f96c15

Browse files
Merge pull request #379 from tikurahul/feature/app_startup
Minor improvements to PR #376
2 parents 6e6963a + c6d4467 commit 6f96c15

File tree

20 files changed

+342
-51
lines changed

20 files changed

+342
-51
lines changed

buildSrc/src/main/java/Libs.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ object Libs {
1818
const val ACTIVITY_COMPOSE = "androidx.activity:activity-compose"
1919
const val ACTIVITY_KTX = "androidx.activity:activity-ktx"
2020
const val APPCOMPAT = "androidx.appcompat:appcompat"
21+
const val APP_STARTUP = "androidx.startup:startup-runtime"
2122
const val ARCH_TESTING = "androidx.arch.core:core-testing"
2223
const val ARCORE = "com.google.ar:core"
2324
const val BENCHMARK = "androidx.benchmark:benchmark-junit4"
25+
const val BENCHMARK_MACRO = "androidx.benchmark:benchmark-macro-junit4"
2426
const val BROWSER = "androidx.browser:browser"
2527
const val CARDVIEW = "androidx.cardview:cardview"
2628
const val CONSTRAINT_LAYOUT = "androidx.constraintlayout:constraintlayout"
@@ -87,4 +89,5 @@ object Libs {
8789
const val TIMBER = "com.jakewharton.timber:timber"
8890
const val VIEWMODEL_COMPOSE = "androidx.lifecycle:lifecycle-viewmodel-compose"
8991
const val VIEWPAGER2 = "androidx.viewpager2:viewpager2"
92+
const val UI_AUTOMATOR = "androidx.test.uiautomator:uiautomator"
9093
}

buildSrc/src/main/java/Versions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object Versions {
2323
const val TARGET_SDK = 30
2424
const val MIN_SDK = 21
2525

26-
const val ANDROID_GRADLE_PLUGIN = "7.0.0-beta03"
26+
const val ANDROID_GRADLE_PLUGIN = "7.0.0-beta05"
2727
const val BENCHMARK = "1.0.0"
2828
const val COMPOSE = "1.0.0-beta04"
2929
const val FIREBASE_CRASHLYTICS = "2.3.0"

depconstraints/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ plugins {
2222
val appcompat = "1.1.0"
2323
val activity = "1.2.0-rc01"
2424
val activityCompose = "1.3.0-alpha03"
25+
val appStartup = "1.1.0-beta01"
2526
val cardview = "1.0.0"
2627
val archTesting = "2.0.0"
2728
val arcore = "1.7.0"
2829
val benchmark = "1.0.0"
30+
val benchmarkMacro = "1.1.0-alpha02"
2931
val browser = "1.0.0"
3032
val compose = Versions.COMPOSE
3133
val constraintLayout = "1.1.3"
@@ -70,16 +72,19 @@ val threetenabp = "1.0.5"
7072
val timber = "4.7.1"
7173
val viewpager2 = "1.0.0"
7274
val viewModelCompose = "1.0.0-alpha02"
75+
val uiAutomator = "2.2.0"
7376

7477
dependencies {
7578
constraints {
7679
api("${Libs.ACTIVITY_COMPOSE}:$activityCompose")
7780
api("${Libs.ACTIVITY_KTX}:$activity")
7881
api("${Libs.APPCOMPAT}:$appcompat")
82+
api("${Libs.APP_STARTUP}:$appStartup")
7983
api("${Libs.CARDVIEW}:$cardview")
8084
api("${Libs.ARCH_TESTING}:$archTesting")
8185
api("${Libs.ARCORE}:$arcore")
8286
api("${Libs.BENCHMARK}:$benchmark")
87+
api("${Libs.BENCHMARK_MACRO}:$benchmarkMacro")
8388
api("${Libs.BROWSER}:$browser")
8489
api("${Libs.COMPOSE_ANIMATION}:$compose")
8590
api("${Libs.COMPOSE_MATERIAL}:$compose")
@@ -145,6 +150,7 @@ dependencies {
145150
api("${Libs.TIMBER}:$timber")
146151
api("${Libs.VIEWPAGER2}:$viewpager2")
147152
api("${Libs.VIEWMODEL_COMPOSE}:$viewModelCompose")
153+
api("${Libs.UI_AUTOMATOR}:$uiAutomator")
148154
}
149155
}
150156

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Wed Feb 10 08:38:31 CET 2021
22
distributionBase=GRADLE_USER_HOME
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
44
distributionPath=wrapper/dists
55
zipStorePath=wrapper/dists
66
zipStoreBase=GRADLE_USER_HOME

macrobenchmark/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

macrobenchmark/build.gradle

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
plugins {
2+
id 'com.android.test'
3+
id 'kotlin-android'
4+
}
5+
6+
android {
7+
compileSdkVersion 30
8+
defaultConfig {
9+
minSdkVersion 29
10+
targetSdkVersion 30
11+
12+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13+
}
14+
15+
compileOptions {
16+
sourceCompatibility JavaVersion.VERSION_1_8
17+
targetCompatibility JavaVersion.VERSION_1_8
18+
}
19+
kotlinOptions {
20+
jvmTarget = '1.8'
21+
}
22+
23+
buildTypes {
24+
// declare a build type (release) to match the target app's build type
25+
release {
26+
debuggable = true
27+
signingConfig = debug.signingConfig
28+
}
29+
}
30+
31+
targetProjectPath = ":mobile"
32+
experimentalProperties["android.experimental.self-instrumenting"] = true
33+
}
34+
35+
androidComponents {
36+
beforeVariants(selector().all()) {
37+
// enable only the release buildType, since we only want to measure
38+
// release build performance
39+
enabled = buildType == 'release'
40+
}
41+
}
42+
43+
dependencies {
44+
api platform(project(":depconstraints"))
45+
implementation Libs.BENCHMARK_MACRO
46+
implementation Libs.ESPRESSO_CORE
47+
implementation Libs.EXT_JUNIT
48+
implementation Libs.KOTLIN_STDLIB
49+
implementation Libs.UI_AUTOMATOR
50+
}

macrobenchmark/consumer-rules.pro

Whitespace-only changes.

macrobenchmark/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Copyright 2021 Google LLC
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ https://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
18+
xmlns:tools="http://schemas.android.com/tools"
19+
package="com.google.samples.apps.iosched.macrobenchmark">
20+
21+
<uses-permission
22+
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
23+
tools:ignore="ScopedStorage" />
24+
25+
</manifest>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.iosched.macrobenchmark
18+
19+
import androidx.benchmark.macro.StartupMode
20+
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
21+
import androidx.test.filters.LargeTest
22+
import org.junit.Rule
23+
import org.junit.Test
24+
import org.junit.runner.RunWith
25+
import org.junit.runners.Parameterized
26+
27+
@LargeTest
28+
@RunWith(Parameterized::class)
29+
class StartupBenchmark(private val startupMode: StartupMode) {
30+
@get:Rule
31+
val benchmarkRule = MacrobenchmarkRule()
32+
33+
@Test
34+
fun startup() = benchmarkRule.measureStartup(
35+
profileCompiled = false,
36+
startupMode = startupMode,
37+
iterations = 3
38+
) {
39+
action = "com.google.samples.apps.iosched.STARTUP_ACTIVITY"
40+
}
41+
42+
companion object {
43+
@Parameterized.Parameters(name = "mode={0}")
44+
@JvmStatic
45+
fun parameters(): List<Array<Any>> {
46+
return listOf(StartupMode.COLD, StartupMode.WARM, StartupMode.HOT)
47+
.map { arrayOf(it) }
48+
}
49+
}
50+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.iosched.macrobenchmark
18+
19+
import android.content.Intent
20+
import androidx.benchmark.macro.CompilationMode
21+
import androidx.benchmark.macro.StartupMode
22+
import androidx.benchmark.macro.StartupTimingMetric
23+
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
24+
25+
const val TARGET_PACKAGE = "com.google.samples.apps.iosched"
26+
27+
fun MacrobenchmarkRule.measureStartup(
28+
profileCompiled: Boolean,
29+
startupMode: StartupMode,
30+
iterations: Int = 3,
31+
setupIntent: Intent.() -> Unit = {}
32+
) = measureRepeated(
33+
packageName = TARGET_PACKAGE,
34+
metrics = listOf(StartupTimingMetric()),
35+
compilationMode = if (profileCompiled) {
36+
CompilationMode.SpeedProfile(warmupIterations = 3)
37+
} else {
38+
CompilationMode.None
39+
},
40+
iterations = iterations,
41+
startupMode = startupMode
42+
) {
43+
pressHome()
44+
val intent = Intent()
45+
intent.setPackage(TARGET_PACKAGE)
46+
setupIntent(intent)
47+
startActivityAndWait(intent)
48+
}

mobile/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ dependencies {
204204
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
205205

206206
implementation(Libs.CORE_KTX)
207+
implementation(Libs.APP_STARTUP)
207208

208209
// UI
209210
implementation(Libs.ACTIVITY_KTX)

mobile/src/main/AndroidManifest.xml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@
5858
</activity>
5959

6060
<activity
61-
android:name=".ui.MainActivity" />
61+
android:name=".ui.MainActivity" >
62+
<intent-filter>
63+
<action android:name="com.google.samples.apps.iosched.STARTUP_ACTIVITY" />
64+
<category android:name="android.intent.category.DEFAULT" />
65+
</intent-filter>
66+
</activity>
6267

6368
<activity
6469
android:name=".ui.onboarding.OnboardingActivity"
@@ -87,6 +92,27 @@
8792
android:exported="false" />
8893
<receiver android:name=".shared.notifications.CancelNotificationBroadcastReceiver"
8994
android:exported="false" />
95+
96+
<provider
97+
android:name="androidx.startup.InitializationProvider"
98+
android:authorities="${applicationId}.androidx-startup"
99+
android:exported="false"
100+
tools:node="merge">
101+
<meta-data
102+
android:name="com.google.samples.apps.iosched.util.initializers.AndroidThreeTenInitializer"
103+
android:value="androidx.startup" />
104+
<meta-data
105+
android:name="com.google.samples.apps.iosched.util.initializers.StrictModeInitializer"
106+
android:value="androidx.startup" />
107+
<meta-data
108+
android:name="com.google.samples.apps.iosched.util.initializers.TimberInitializer"
109+
android:value="androidx.startup" />
110+
111+
</provider>
112+
<!-- enable profiling by macrobenchmark -->
113+
<profileable
114+
android:shell="true"
115+
tools:targetApi="q" />
90116
</application>
91117

92118
</manifest>

mobile/src/main/java/com/google/samples/apps/iosched/MainApplication.kt

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,49 +17,7 @@
1717
package com.google.samples.apps.iosched
1818

1919
import android.app.Application
20-
import android.os.StrictMode
21-
import android.os.StrictMode.ThreadPolicy.Builder
22-
import com.google.samples.apps.iosched.shared.analytics.AnalyticsHelper
23-
import com.google.samples.apps.iosched.util.CrashlyticsTree
24-
import com.jakewharton.threetenabp.AndroidThreeTen
2520
import dagger.hilt.android.HiltAndroidApp
26-
import timber.log.Timber
27-
import javax.inject.Inject
2821

29-
/**
30-
* Initialization of libraries.
31-
*/
3222
@HiltAndroidApp
33-
class MainApplication : Application() {
34-
35-
// Even if the var isn't used, needs to be initialized at application startup.
36-
@Inject lateinit var analyticsHelper: AnalyticsHelper
37-
38-
override fun onCreate() {
39-
// ThreeTenBP for times and dates, called before super to be available for objects
40-
AndroidThreeTen.init(this)
41-
42-
// Enable strict mode before Dagger creates graph
43-
if (BuildConfig.DEBUG) {
44-
enableStrictMode()
45-
}
46-
super.onCreate()
47-
48-
if (BuildConfig.DEBUG) {
49-
Timber.plant(Timber.DebugTree())
50-
} else {
51-
Timber.plant(CrashlyticsTree())
52-
}
53-
}
54-
55-
private fun enableStrictMode() {
56-
StrictMode.setThreadPolicy(
57-
Builder()
58-
.detectDiskReads()
59-
.detectDiskWrites()
60-
.detectNetwork()
61-
.penaltyLog()
62-
.build()
63-
)
64-
}
65-
}
23+
class MainApplication : Application()

mobile/src/main/java/com/google/samples/apps/iosched/di/AppModule.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,10 @@ class AppModule {
8585
@Provides
8686
fun provideAnalyticsHelper(
8787
@ApplicationScope applicationScope: CoroutineScope,
88-
@ApplicationContext context: Context,
8988
signInDelegate: SignInViewModelDelegate,
9089
preferenceStorage: PreferenceStorage
9190
): AnalyticsHelper =
92-
FirebaseAnalyticsHelper(applicationScope, context, signInDelegate, preferenceStorage)
91+
FirebaseAnalyticsHelper(applicationScope, signInDelegate, preferenceStorage)
9392

9493
@Singleton
9594
@Provides

0 commit comments

Comments
 (0)