Add testing CLI scripts for profileinstaller
Test: "Is test utility"
Change-Id: If20cb62b48f3e17a429ecbeb6e5a3fa00fd26c65
diff --git a/profileinstaller/cli/README.md b/profileinstaller/cli/README.md
new file mode 100644
index 0000000..b1b5c73
--- /dev/null
+++ b/profileinstaller/cli/README.md
@@ -0,0 +1,21 @@
+# Useful utilities for debugging profiles
+
+This package is a collection of scripts of various polish to help interactively verify aot profiles,
+or the behavior of various versions of Android when art compiles profiles.
+
+## Don't depend on these scripts
+The scripts in this directory are not maintained, and should never be used in a production
+dependency such as CI.
+
+## Contributing
+
+Feel free to add any useful scripts you've developed here. If you find yourself doing similar things
+repeatedly, please consider wrapping up the commands in a script.
+
+Things to check before contributing:
+
+1. AOSP header is added to all files
+2. Script contains a usage output
+3. Script can run without depending on files in other directories, or takes all dependencies as
+ command line arguments
+4. Is reasonably useful.
\ No newline at end of file
diff --git a/profileinstaller/cli/logcat_filtercompile.sh b/profileinstaller/cli/logcat_filtercompile.sh
new file mode 100755
index 0000000..5d1afb3
--- /dev/null
+++ b/profileinstaller/cli/logcat_filtercompile.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+#
+# Copyright 2021 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.
+#
+
+adb logcat | grep -E "(profman|dex2oat)" -B5 -A5
\ No newline at end of file
diff --git a/profileinstaller/cli/lsprofile.sh b/profileinstaller/cli/lsprofile.sh
new file mode 100755
index 0000000..61d1c93
--- /dev/null
+++ b/profileinstaller/cli/lsprofile.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+#
+# Copyright 2021 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.
+#
+
+usage() {
+ echo "Usage: ./lsprofile.sh -p packagename"
+ echo " -p is the packagename to check"
+ echo ""
+ echo "This script displays the sizes of ref and cur profiles."
+ exit 1
+}
+
+while getopts p: flag; do
+ case $flag in
+ p)
+ PACKAGE=$OPTARG
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+if [ -z "${PACKAGE}" ]; then
+ usage
+fi
+
+run() {
+ echo -n "cur: "
+ adb shell ls -la "/data/misc/profiles/cur/0/${PACKAGE}/primary.prof" | cut -f5 -d" "
+ echo -n "ref: "
+ adb shell ls -la "/data/misc/profiles/ref/${PACKAGE}/primary.prof" | cut -f5 -d" "
+}
+
+run
\ No newline at end of file
diff --git a/profileinstaller/cli/profman.sh b/profileinstaller/cli/profman.sh
new file mode 100755
index 0000000..acc6cdd
--- /dev/null
+++ b/profileinstaller/cli/profman.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+#
+# Copyright 2021 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.
+#
+
+
+usage() {
+ echo "Usage: ./profman.sh -p packagename [-c] [-r]"
+ echo " -p is the packagename to check"
+ echo " -c display the cur profile"
+ echo " -r display the ref profile"
+ echo ""
+ echo "Dump the profile in cur or ref (or both)"
+ exit 1
+}
+
+CUR=0
+REF=0
+while getopts crp: flag; do
+ case $flag in
+ p)
+ PACKAGE=$OPTARG
+ ;;
+ c)
+ CUR=1
+ ;;
+ r)
+ REF=1
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+if [ -z "${PACKAGE}" ]; then
+ usage
+fi
+
+if [[ $CUR -gt 0 ]]; then
+ adb shell profman --dump-only --profile-file="/data/misc/profiles/ref/${PACKAGE}/primary.prof"
+fi
+
+if [[ $REF -gt 0 ]]; then
+ adb shell profman --dump-only --profile-file="/data/misc/profiles/cur/0/${PACKAGE}/primary.prof"
+fi
\ No newline at end of file
diff --git a/profileinstaller/cli/showcompiledclasses.sh b/profileinstaller/cli/showcompiledclasses.sh
new file mode 100755
index 0000000..2bad613
--- /dev/null
+++ b/profileinstaller/cli/showcompiledclasses.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+#
+# Copyright 2021 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.
+#
+
+usage() {
+ echo "Usage: ./showcompiledclasses.sh -p packagename [-c]"
+ echo " -p is the packagename to check"
+ echo " -c just display the counts"
+ echo ""
+ echo "This script greps the odex file for a package and prints the classes have been\
+ compiled by art."
+ exit 1
+}
+
+COUNT=0
+while getopts cp: flag; do
+ case $flag in
+ p)
+ PACKAGE=$OPTARG
+ ;;
+ c)
+ COUNT=1
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+if [ -z "${PACKAGE}" ]; then
+ usage
+fi
+
+OAT=$(adb shell dumpsys package dexopt | grep -A 1 $PACKAGE | grep status | cut -d":" -f2 |\
+ cut -d "[" -f1 | cut -d " " -f 2)
+RESULTS="$(adb shell oatdump --oat-file="${OAT}" |\
+ grep -E "(OatClassSomeCompiled|OatClassAllCompiled)")"
+if [[ $COUNT -eq 0 ]]; then
+ echo "${RESULTS}"
+else
+ echo -n "OatClassAllCompiled: "
+ echo "${RESULTS}" | grep "OatClassAllCompiled" -c
+ echo -n "OatClassSomeCompiled: "
+ echo "${RESULTS}" | grep "OatClassSomeCompiled" -c
+fi
\ No newline at end of file
diff --git a/profileinstaller/integration-tests/testapp/build.gradle b/profileinstaller/integration-tests/testapp/build.gradle
deleted file mode 100644
index e8f97cc..0000000
--- a/profileinstaller/integration-tests/testapp/build.gradle
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2021 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("AndroidXPlugin")
- id("AndroidXComposePlugin")
- id("com.android.application")
- id("org.jetbrains.kotlin.android")
-}
-
-dependencies {
- kotlinPlugin(project(":compose:compiler:compiler"))
-
- implementation(libs.kotlinStdlib)
- implementation(project(":compose:foundation:foundation"))
- implementation(project(":compose:foundation:foundation-layout"))
- implementation(project(":compose:integration-tests:demos:common"))
- implementation(project(":compose:material:material"))
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:ui:ui"))
-
- implementation(libs.kotlinStdlib)
- implementation("androidx.activity:activity-compose:1.3.0")
- implementation(project(":profileinstaller:profileinstaller"))
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testCore)
-}
-
-android {
- defaultConfig {
- minSdkVersion 21
- }
- lintOptions {
- checkReleaseBuilds false
- }
- buildTypes {
- release {
- minifyEnabled true
- }
- }
-}
diff --git a/profileinstaller/integration-tests/testapp/cli/all_compose_profile.txt b/profileinstaller/integration-tests/testapp/cli/all_compose_profile.txt
deleted file mode 100644
index af6955b..0000000
--- a/profileinstaller/integration-tests/testapp/cli/all_compose_profile.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# This reference file is only for testing profgen, and should not be used in production
-# Any method inside of androidx.compose should be marked as "hot" and "startup"
-HSLandroidx/compose/**->**(**)**
-# Any class inside of androidx.compose.runtime should be marked as "startup"
-Landroidx/compose/runtime/*;
\ No newline at end of file
diff --git a/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh b/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh
deleted file mode 100755
index ad3ab2b..0000000
--- a/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# Copyright 2021 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.
-#
-
-# CHANGEME:
-DEBUG=false
-
-SCRIPT=`realpath $0`
-SCRIPT_DIR=`dirname $SCRIPT`
-SUPPORT_DIR=$SCRIPT_DIR/../../../../
-TMP_DIR=`mktemp -d`
-
-pushd $SUPPORT_DIR
-
-echo "===START=== Rebuilding apk..."
-ANDROIDX_PROJECTS=COMPOSE ./gradlew \
- :profileinstaller:integration-tests:testapp:clean
-if [ $DEBUG = true ]; then
- ANDROIDX_PROJECTS=COMPOSE ./gradlew \
- :profileinstaller:integration-tests:testapp:assembleDebug
-else
- ANDROIDX_PROJECTS=COMPOSE ./gradlew \
- :profileinstaller:integration-tests:testapp:assembleRelease
-fi
-echo "===/DONE=== Rebuilding apk..."
-
-echo "===START=== Uninstalling..."
-adb uninstall androidx.profileinstaller.integration.testapp
-echo "===/DONE=== Uninstalling"
-
-echo "===START=== Repackaging apk..."
-if [ $DEBUG = true ]; then
- $SCRIPT_DIR/repackage.py --out $TMP_DIR/out.apk --debug true
-else
- $SCRIPT_DIR/repackage.py --out $TMP_DIR/out.apk
-fi
-echo "===/DONE=== Repackaging apk..."
-
-echo "===START=== Installing apk..."
-adb install $TMP_DIR/out.apk > /dev/null
-echo "===/DONE=== Installing apk..."
-
-echo "===START=== Installing apk..."
-adb shell am start -n androidx.profileinstaller.integration.testapp/.MainActivity
-echo "===/DONE==="
-
-echo "===START=== Waiting 10 seconds for profile..."
-sleep 10
-echo "===/DONE=== Waiting 10 seconds for profile..."
-
-echo "===START=== Force stopping app"
-adb shell am force-stop androidx.profileinstaller.integration.testapp
-echo "===/DONE=== Force stopping app"
-
-echo "===START=== Root + Remount"
-adb root >/dev/null
-adb remount 2>/dev/null
-echo "===/DONE=== Root + Remount"
-
-echo "Profile found written to cur directory..."
-CUR_SIZE=$(adb shell stat -c%s /data/misc/profiles/cur/0/androidx.profileinstaller.integration.testapp/primary.prof 2>/dev/null)
-REF_SIZE=$(adb shell stat -c%s /data/misc/profiles/ref/androidx.profileinstaller.integration.testapp/primary.prof 2>/dev/null)
-echo "Cur: $CUR_SIZE"
-echo "Ref: $REF_SIZE"
-
-echo "===START=== Compile speed-profile"
-adb shell cmd package compile -m speed-profile -f androidx.profileinstaller.integration.testapp
-echo "===/DONE=== Compile speed-profile"
-
-CUR_SIZE=$(adb shell stat -c%s /data/misc/profiles/cur/0/androidx.profileinstaller.integration.testapp/primary.prof 2>/dev/null)
-REF_SIZE=$(adb shell stat -c%s /data/misc/profiles/ref/androidx.profileinstaller.integration.testapp/primary.prof 2>/dev/null)
-echo "Cur: $CUR_SIZE"
-echo "Ref: $REF_SIZE"
-
-APK_LOCATION=$(adb shell dumpsys package dexopt | grep "\[androidx\.profileinstaller\.integration\.testapp\]" -A1 | tail -n 1 | cut -d':' -f 2)
-APK_DIR=$(dirname $APK_LOCATION)
-
-adb shell ls -la $APK_DIR/oat/arm64/
-
diff --git a/profileinstaller/integration-tests/testapp/cli/instructions.md b/profileinstaller/integration-tests/testapp/cli/instructions.md
deleted file mode 100644
index ec0c412..0000000
--- a/profileinstaller/integration-tests/testapp/cli/instructions.md
+++ /dev/null
@@ -1,30 +0,0 @@
-
-== Repackage tool
-
-
-== Profgen CLI tool
-`profgen-cli.jar` is generated in `studio-master-dev` by the _gradle_ task:
-
-Edit the `build.gradle` for profgen-cli to add a jar clause:
-
-```
-jar {
- manifest {
- attributes "Main-Class": "com.android.tools.profgen.cli.main"
- attributes "Class-Path": configurations.compile.collect { it.name }.join(' ')
- }
-
- from { configurations.runtimeClasspath.collect { zipTree(it) } }
- duplicatesStrategy = DuplicatesStrategy.INCLUDE
-}
-```
-
-Then generate a fat jar with gradle:
-
-```
-cd <studio-master-dev-checkout>/studio-master-dev/tools
-./gradlew :base:profgen-cli:clean :base:profgen-cli:jar
-ls ../out/build/base/profgen-cli/build/libs/profgen-cli*.jar
-```
-
-Copy the resulting file to this directory and name it `profgen-cli.jar`
\ No newline at end of file
diff --git a/profileinstaller/integration-tests/testapp/cli/profgen-cli.jar b/profileinstaller/integration-tests/testapp/cli/profgen-cli.jar
deleted file mode 100644
index f6ca02b..0000000
--- a/profileinstaller/integration-tests/testapp/cli/profgen-cli.jar
+++ /dev/null
Binary files differ
diff --git a/profileinstaller/integration-tests/testapp/cli/repackage.py b/profileinstaller/integration-tests/testapp/cli/repackage.py
deleted file mode 100755
index 8c2a466..0000000
--- a/profileinstaller/integration-tests/testapp/cli/repackage.py
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/usr/bin/env python3
-
-import argparse
-import os
-import shutil
-import subprocess
-import sys
-import tempfile
-from pathlib import Path
-from zipfile import ZipFile
-
-# CHANGEME:
-# PATH_TO_APKSIGNER = '/Users/lelandr/Library/Android/sdk/build-tools/30.0.3/apksigner'
-PATH_TO_APKSIGNER = 'apksigner'
-
-SCRIPT_PATH = Path(__file__).parent.absolute()
-SUPPORT_PATH = (SCRIPT_PATH / Path("../../../..")).resolve()
-ROOT_DIR = (SUPPORT_PATH / Path("../..")).resolve()
-BUILD_OUT_DIR = (Path(SUPPORT_PATH) / Path(
- "../../out/androidx/profileinstaller/integration-tests/"
- "testapp/build/outputs/apk/")).resolve()
-MAPPING_OUT_PATH = (Path(SUPPORT_PATH) / Path(
- "../../out/androidx/profileinstaller/integration-tests/"
- "testapp/build/outputs/mapping/release/mapping.txt")).resolve()
-
-APK_PREFIX = "testapp"
-APK_PROFILE_FILE = "baseline.prof"
-
-def parse_args():
- parser = argparse.ArgumentParser()
- parser.add_argument('--profile', '-p', required=False, default=str(Path(SCRIPT_PATH) / Path(
- "all_compose_profile.txt")))
- parser.add_argument('--apk-path', '-f', required=False, help='apk path to for processing a '
- 'single apk')
- parser.add_argument('--jar', '-j', required=False, default=str(Path(SCRIPT_PATH) /
- Path("profgen-cli.jar")))
- parser.add_argument('--output', '-o', required=False, default="out.apk")
- parser.add_argument('--debug', type=bool, required=False, default=False)
- parser.add_argument('--apk-signer', required=False, default=PATH_TO_APKSIGNER)
- args = parser.parse_args()
- return args
-
-def dir_for_buildtype(debug, path):
- if (path is not None):
- return Path(path).absolute()
- type = 'debug' if debug else 'release'
- newpath = BUILD_OUT_DIR / Path(type) / Path(APK_PREFIX + "-" + type + ".apk")
- return newpath.resolve()
-
-def profile_from(pathStr):
- return Path(pathStr)
-
-def jar_from(jarPathStr):
- return Path(jarPathStr)
-
-def output_apk_from(outPathStr):
- return Path(outPathStr)
-
-def check_env(apk_src, profile, jar, out_apk, apk_signer):
- if not apk_src.exists():
- print("ERROR: APK source does not exist, build it using gradle.")
- print(apk_src)
- sys.exit(-1)
-
- if not profile.exists():
- print("ERROR: Profile path does not exist")
- print(profile)
- sys.exit(-1)
-
- if not jar.exists():
- print("ERROR: Jar file does not exist")
- print(jar)
- sys.exit(-1)
-
- if shutil.which(apk_signer) is None:
- print("ERROR: missing command line tool `apksigner`")
- print("please install it on your system or modify the constant PATH_TO_APKSIGNER")
- sys.exit(-1)
-
- if out_apk.exists():
- print("WARNING: Output apk already exists, overwriting")
-
- print(f"Apk source: //{apk_src.relative_to(ROOT_DIR)}")
- print(f"Profile: //{profile.relative_to(ROOT_DIR)}")
- print(f"Profgen: {jar.absolute()}")
- print(f"Output: {output_apk.absolute()}")
-
-def run_profgen(tmpDirName, apk_src, profile, jar, output_file, debug):
- print(f"Running profgen:")
- print(f"Profile: {profile.absolute()}")
- print(f"Apk: {apk_src.absolute()}")
- print(f"Output: {output_file.absolute()}")
- jar_command = [
- 'java',
- '-jar',
- str(jar.absolute()),
- 'generate',
- str(profile.absolute()),
- '--apk',
- str(apk_src.absolute()),
- '--output',
- str(output_file.absolute()),
- '--verbose'
- ] + ([] if debug else [
- '--map',
- str(MAPPING_OUT_PATH.absolute())
- ])
- subprocess.run(jar_command, stdout=sys.stdout)
- if not output_file.exists():
- print(f"Failed to generate output file from profgen")
- print(" ".join(jar_command))
- sys.exit(-1)
-
- output_size = os.stat(output_file.absolute()).st_size
- print(f"Successfully created profile. Size: {output_size}")
-
-def repackage_jar(apk_src, profile, apk_dest, tmp_dir, apksigner):
- working_dir = tmp_dir / Path("working/")
- working_dir.mkdir()
- working_apk = working_dir / Path("working.apk")
- shutil.copyfile(apk_src, working_apk)
- with ZipFile(working_apk, 'a') as zip:
- profile_destination = Path('assets/dexopt/') / Path(APK_PROFILE_FILE)
- if str(profile_destination) in [it.filename for it in zip.infolist()]:
- print("ERROR: profile already in apk, aborting")
- print(profile_destination)
- sys.exit(-1)
- zip.write(profile, profile_destination)
-
- keystore = Path.home() / Path(".android/debug.keystore")
- apksigner_command = [
- apksigner,
- 'sign',
- '-ks',
- str(keystore.absolute()),
- '--ks-pass',
- 'pass:android',
- str(working_apk.absolute())
- ]
- subprocess.check_output(apksigner_command)
-
- shutil.copyfile(working_apk, apk_dest)
-
-def generate_apk(apk_src, profile, jar, out_apk, debug, apk_signer):
- check_env(apk_src, profile, jar, out_apk, apk_signer)
- with tempfile.TemporaryDirectory() as tmpDirName:
- output_profile = Path(tmpDirName) / Path("out.prof")
- print(f"Output profile: {output_profile.absolute()}")
- run_profgen(tmpDirName, apk_src, profile, jar, output_profile, debug)
- repackage_jar(apk_src, output_profile, out_apk, Path(tmpDirName), apk_signer)
-
-if __name__ == "__main__":
- args = parse_args()
- apk_src = dir_for_buildtype(args.debug, args.apk_path)
- profile = profile_from(args.profile)
- jar = jar_from(args.jar)
- output_apk = output_apk_from(args.output)
- generate_apk(apk_src, profile, jar, output_apk, args.debug, args.apk_signer)
diff --git a/profileinstaller/integration-tests/testapp/src/main/AndroidManifest.xml b/profileinstaller/integration-tests/testapp/src/main/AndroidManifest.xml
deleted file mode 100644
index ffa6ce6..0000000
--- a/profileinstaller/integration-tests/testapp/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="androidx.profileinstaller.integration.testapp">
-
- <application android:label="profileinstaller test app">
- <activity android:name=".MainActivity" android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
\ No newline at end of file
diff --git a/profileinstaller/integration-tests/testapp/src/main/java/androidx/profileinstaller/integration/testapp/MainActivity.kt b/profileinstaller/integration-tests/testapp/src/main/java/androidx/profileinstaller/integration/testapp/MainActivity.kt
deleted file mode 100644
index d4316ce..0000000
--- a/profileinstaller/integration-tests/testapp/src/main/java/androidx/profileinstaller/integration/testapp/MainActivity.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2021 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.profileinstaller.integration.testapp
-
-import android.os.Bundle
-import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.lazy.rememberLazyListState
-import androidx.compose.material.Text
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import java.io.File
-
-val LotsOfItems = Array<String>(5_000) { position ->
- "A very long list item, #$position"
-}
-
-class ProfileWatcher {
- var profilePresent by mutableStateOf(false)
- private set
-
- suspend fun pollForProfiles() {
- withContext(Dispatchers.IO) {
- while (!profilePresent) {
- profilePresent = checkProfile()
- delay(100)
- }
- }
- }
-
- private fun checkProfile(): Boolean {
- val file = File(
- "/data/misc/profiles/cur/0/" +
- "androidx.profileinstaller.integration.testapp/primary.prof"
- )
- return file.exists()
- }
-}
-
-class MainActivity : ComponentActivity() {
- @Suppress("EXPERIMENTAL_ANNOTATION_ON_OVERRIDE_WARNING")
- @ExperimentalFoundationApi
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- setContent {
- val profileState = remember { ProfileWatcher() }
- val lazyState = rememberLazyListState()
- LaunchedEffect(Unit) {
- launch { profileState.pollForProfiles() }
- while (true) {
- lazyState.animateScrollToItem(LotsOfItems.size - 1)
- lazyState.animateScrollToItem(0)
- delay(100)
- }
- }
- LazyColumn(Modifier.fillMaxSize(1f), state = lazyState) {
- stickyHeader {
- if (!profileState.profilePresent) {
- Text(
- "⏳ waiting for profile",
- Modifier.background(Color.Yellow)
- .fillMaxWidth()
- .height(100.dp)
- )
- } else {
- Text(
- "\uD83C\uDF89 profile installed",
- Modifier.background(Color.Gray)
- .fillMaxWidth()
- .height(100.dp)
- )
- }
- }
- items(LotsOfItems) { item ->
- Text(item, Modifier.fillMaxWidth().height(100.dp))
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index a274db9..ce4e620 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -564,7 +564,6 @@
includeProject(":profileinstaller:profileinstaller", "profileinstaller/profileinstaller", [BuildType.MAIN, BuildType.COMPOSE])
includeProject(":profileinstaller:integration-tests:init-macrobenchmark", "profileinstaller/integration-tests/init-macrobenchmark", [BuildType.MAIN])
includeProject(":profileinstaller:integration-tests:init-macrobenchmark-target", "profileinstaller/integration-tests/init-macrobenchmark-target", [BuildType.MAIN])
-includeProject(":profileinstaller:integration-tests:testapp", "profileinstaller/integration-tests/testapp", [BuildType.COMPOSE])
includeProject(":profileinstaller:profileinstaller-benchmark", "profileinstaller/profileinstaller-benchmark", [BuildType.MAIN])
includeProject(":recommendation:recommendation", "recommendation/recommendation", [BuildType.MAIN])
includeProject(":recyclerview:recyclerview", "recyclerview/recyclerview", [BuildType.MAIN])