diff --git a/.crowdin/config.example.yml b/.crowdin/config.example.yml deleted file mode 100644 index 4ef788a3..00000000 --- a/.crowdin/config.example.yml +++ /dev/null @@ -1,10 +0,0 @@ -project_id: "372633" -api_token: "" -base_path: "../app/src/main" -base_url: "https://api.crowdin.com" -preserve_hierarchy: true - -files: -- source: "res/values/strings.xml" - dest: "strings.xml" - translation: "res/values-%android_code%/%original_file_name%" diff --git a/.github/workflows/build-app-workflow.yaml b/.github/workflows/build-app-workflow.yaml index d3c55f8e..ab511ab7 100644 --- a/.github/workflows/build-app-workflow.yaml +++ b/.github/workflows/build-app-workflow.yaml @@ -35,7 +35,7 @@ jobs: sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm - name: Tests - uses: reactivecircus/android-emulator-runner@6b0df4b0efb23bb0ec63d881db79aefbc976e4b2 + uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d with: api-level: 31 arch: x86_64 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d4570016..b575535b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -14,6 +14,7 @@ jobs: actions: read contents: read security-events: write + if: github.event_name != 'schedule' || github.repository == 'beemdevelopment/Aegis' steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml index e0fd559c..e7898362 100644 --- a/.github/workflows/crowdin.yml +++ b/.github/workflows/crowdin.yml @@ -13,19 +13,13 @@ jobs: - uses: actions/checkout@v4 - name: Install crowdin-cli run: | - wget https://github.com/crowdin/crowdin-cli/releases/download/3.7.2/crowdin-cli.zip - echo "ee9f838b819ccedc33c9b2537055e5ba7d7934561b24df1e1a6274cbd6e27f2d crowdin-cli.zip" | sha256sum -c + wget https://github.com/crowdin/crowdin-cli/releases/download/4.6.1/crowdin-cli.zip + echo "7afd70de3a747ac631a5bad7866008163ae1d50c4606b5773f0b90a5481ffde2 crowdin-cli.zip" | sha256sum -c unzip crowdin-cli.zip -d crowdin-cli - name: Upload to Crowdin env: - CROWDIN_TOKEN: "${{ secrets.CROWDIN_TOKEN }}" + CROWDIN_PERSONAL_TOKEN: "${{ secrets.CROWDIN_TOKEN }}" run: | - java -jar ./crowdin-cli/3.7.2/crowdin-cli.jar upload sources \ + java -jar ./crowdin-cli/4.6.1/crowdin-cli.jar upload sources \ --no-progress \ - --token "$CROWDIN_TOKEN" \ - --project-id 372633 \ - --base-path app/src/main \ - --source res/values/strings.xml \ - --translation "res/values-%android_code%/%original_file_name%" \ - --dest strings.xml \ --branch master diff --git a/FAQ.md b/FAQ.md index 815490aa..6d514574 100644 --- a/FAQ.md +++ b/FAQ.md @@ -86,6 +86,14 @@ Another common setup is to configure Aegis to back up to a folder on local storage of your device and then have a separate app (like [Syncthing](https://syncthing.net/)) sync that folder anywhere you want. +## Encrypted Backups + +### Why do I not get prompted to enter an encryption password when exporting? + +Aegis uses the same password you have configured to encrypt your vault as the +password which is used when exporting and importing your vault; so when prompted, +you will enter that when importing your vault. + ## Importing ### When importing from Authenticator Plus, an error is shown claiming that Accounts.txt is missing diff --git a/README.md b/README.md index 2892a537..195bd4ed 100644 --- a/README.md +++ b/README.md @@ -123,24 +123,33 @@ documentation](docs/iconpacks.md). Unofficial monochrome-styled 2FA icons. [aegis-icons preview](https://github.com/aegis-icons/aegis-icons) + src="metadata/en-US/images/iconPacks/aegis-icons.png">](https://github.com/aegis-icons/aegis-icons) - [delta-aegis-icons](https://github.com/Delta-Icons/aegis-icons) Delta version of the unofficial monochrome-styled 2FA icon pack aegis-icons. -- [aegis-simple-icons](https://github.com/alexbakker/aegis-simple-icons) * + [delta-icons preview](https://github.com/Delta-Icons/aegis-icons) + +- [aegis-simple-icons](https://github.com/alexbakker/aegis-simple-icons) \* This project periodically generates an icon pack for Aegis based on [Simple Icons](https://simpleicons.org/). -- [aegis-simple-icons-outlined](https://github.com/michaelschattgen/aegis-simple-icons-outlined) * + [aegis-simple-icons preview](https://github.com/alexbakker/aegis-simple-icons) + +- [aegis-simple-icons-outlined](https://github.com/michaelschattgen/aegis-simple-icons-outlined) \* This is a variant on the aegis-simple-icons pack where the icons contain no solid background and just the outlines are being used. - + + [aegis-simple-icons-outlined preview](https://github.com/michaelschattgen/aegis-simple-icons-outlined) + \* The icons are automatically generated, so - not all of them are as high quality as the ones you'll find in - [aegis-icons](https://github.com/aegis-icons/aegis-icons). +not all of them are as high quality as the ones you'll find in +[aegis-icons](https://github.com/aegis-icons/aegis-icons). ## Contributing @@ -155,3 +164,9 @@ Swing by our Matrix room to interact with other contributors: This project is licensed under the GNU General Public License v3.0. See the [LICENSE](LICENSE) file for details. + +A couple of libraries vendored in Aegis' repository are licensed under a +different license: + +- [TextDrawable](app/src/main/java/com/amulyakhare/textdrawable) +- [TrustedIntents](app/src/main/java/info/guardianproject/trustedintents) diff --git a/app/build.gradle b/app/build.gradle index 92d6ccfa..43512d69 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,21 +20,27 @@ def fileProviderAuthority = "${packageName}.fileprovider" def fileProviderAuthorityDebug = "${packageName}.debug.fileprovider" android { - compileSdk 34 + compileSdk 35 namespace packageName defaultConfig { applicationId "${packageName}" - minSdkVersion 21 - targetSdkVersion 34 - versionCode 67 - versionName "3.1" + minSdkVersion 23 + targetSdkVersion 35 + versionCode 79 + versionName "3.4" multiDexEnabled true buildConfigField "String", "GIT_HASH", "\"${getGitHash()}\"" buildConfigField "String", "GIT_BRANCH", "\"${getGitBranch()}\"" buildConfigField "java.util.concurrent.atomic.AtomicBoolean", "TEST", "new java.util.concurrent.atomic.AtomicBoolean(false)" + javaCompileOptions { + annotationProcessorOptions { + arguments = ["room.schemaLocation": "$projectDir/schemas"] + } + } + testInstrumentationRunner "com.beemdevelopment.aegis.AegisTestRunner" testInstrumentationRunnerArguments clearPackageData: 'true' } @@ -87,22 +93,35 @@ android { } } + // Required to make the APK reproducible + aaptOptions { + cruncherEnabled = false + } + defaultConfig { + vectorDrawables.generatedDensities = [] + } + packagingOptions { // R8 doesn't remove these resources, so exclude them manually. This reduces APK size by 4MB. resources { - excludes += ['/org/bouncycastle/pqc/**/*.properties'] + excludes += [ + '/org/bouncycastle/pqc/**/*.properties', + 'META-INF/versions/9/OSGI-INF/MANIFEST.MF' + ] } } compileOptions { - targetCompatibility 1.8 - sourceCompatibility 1.8 + targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_17 coreLibraryDesugaringEnabled true } lint { abortOnError true checkDependencies true - disable 'MissingQuantity', 'MissingTranslation' + } + buildFeatures { + buildConfig true } } @@ -133,36 +152,34 @@ aboutLibraries { } dependencies { - def cameraxVersion = '1.3.1' + def cameraxVersion = '1.4.2' def glideVersion = '4.16.0' - def guavaVersion = '33.0.0' - def hiltVersion = '2.50' + def guavaVersion = '33.4.8' + def hiltVersion = '2.56.2' def junitVersion = '4.13.2' - def libsuVersion = '5.2.2' - def roomVersion = "2.6.1" + def libsuVersion = '6.0.0' + def roomVersion = '2.7.1' - - annotationProcessor 'androidx.annotation:annotation:1.7.1' + annotationProcessor 'androidx.annotation:annotation:1.9.1' + annotationProcessor "androidx.room:room-compiler:$roomVersion" annotationProcessor "com.google.dagger:hilt-compiler:$hiltVersion" annotationProcessor "com.github.bumptech.glide:compiler:${glideVersion}" - annotationProcessor "androidx.room:room-compiler:$roomVersion" implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.activity:activity:1.8.2' - implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'androidx.activity:activity:1.10.1' + implementation 'androidx.appcompat:appcompat:1.7.0' implementation "androidx.biometric:biometric:1.1.0" implementation "androidx.camera:camera-camera2:$cameraxVersion" implementation "androidx.camera:camera-lifecycle:$cameraxVersion" implementation "androidx.camera:camera-view:$cameraxVersion" - implementation "androidx.core:core:1.12.0" - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'androidx.documentfile:documentfile:1.0.1' - implementation "androidx.lifecycle:lifecycle-process:2.6.2" + implementation 'androidx.core:core:1.16.0' + implementation 'androidx.constraintlayout:constraintlayout:2.2.1' + implementation 'androidx.documentfile:documentfile:1.1.0' + implementation 'androidx.lifecycle:lifecycle-process:2.9.0' implementation "androidx.preference:preference:1.2.1" - implementation 'androidx.recyclerview:recyclerview:1.3.2' + implementation 'androidx.recyclerview:recyclerview:1.4.0' implementation "androidx.room:room-runtime:$roomVersion" - implementation "androidx.viewpager2:viewpager2:1.0.0" - implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' + implementation 'androidx.viewpager2:viewpager2:1.1.0' implementation 'com.caverock:androidsvg-aar:1.4' implementation "com.google.dagger:hilt-android:$hiltVersion" implementation 'com.github.avito-tech:krop:0.52' @@ -174,37 +191,35 @@ dependencies { implementation "com.github.topjohnwu.libsu:core:${libsuVersion}" implementation "com.github.topjohnwu.libsu:io:${libsuVersion}" implementation "com.google.guava:guava:${guavaVersion}-android" - implementation 'com.google.android.material:material:1.11.0' - implementation 'com.google.protobuf:protobuf-javalite:3.25.1' - implementation 'com.google.zxing:core:3.5.2' - implementation("com.mikepenz:aboutlibraries:11.1.0") { + implementation 'com.google.android.material:material:1.12.0' + implementation 'com.google.protobuf:protobuf-javalite:4.31.0' + implementation 'com.google.zxing:core:3.5.3' + implementation('com.mikepenz:aboutlibraries:11.2.3') { exclude group: 'com.mikepenz', module: 'aboutlibraries-core' } - implementation "com.mikepenz:aboutlibraries-core-android:11.1.0" - implementation 'com.nulab-inc:zxcvbn:1.8.2' - implementation 'de.hdodenhof:circleimageview:3.1.0' + implementation 'com.mikepenz:aboutlibraries-core-android:11.2.3' + implementation 'com.nulab-inc:zxcvbn:1.9.0' implementation 'net.lingala.zip4j:zip4j:2.11.5' - implementation 'info.guardianproject.trustedintents:trustedintents:0.2' - implementation 'org.bouncycastle:bcprov-jdk18on:1.77' - implementation "org.simpleflatmapper:sfm-csv:8.2.3" + implementation 'org.bouncycastle:bcprov-jdk18on:1.80' + implementation 'org.simpleflatmapper:sfm-csv:8.2.3' androidTestAnnotationProcessor "com.google.dagger:hilt-android-compiler:$hiltVersion" androidTestImplementation "com.google.dagger:hilt-android-testing:$hiltVersion" - androidTestImplementation 'androidx.test:core:1.5.0' - androidTestImplementation 'androidx.test:runner:1.5.2' - androidTestImplementation 'androidx.test:rules:1.5.0' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1' - androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1' + androidTestImplementation 'androidx.test:core:1.6.1' + androidTestImplementation 'androidx.test:runner:1.6.2' + androidTestImplementation 'androidx.test:rules:1.6.1' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1' androidTestImplementation "junit:junit:${junitVersion}" - androidTestUtil 'androidx.test:orchestrator:1.4.2' + androidTestUtil 'androidx.test:orchestrator:1.5.1' - testImplementation 'androidx.test:core:1.5.0' + testImplementation 'androidx.test:core:1.6.1' testImplementation "com.google.guava:guava:${guavaVersion}-jre" testImplementation "junit:junit:${junitVersion}" - testImplementation 'org.json:json:20231013' - testImplementation 'org.robolectric:robolectric:4.11.1' + testImplementation 'org.json:json:20250517' + testImplementation 'org.robolectric:robolectric:4.14.1' - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' } diff --git a/app/config/libraries/textdrawable.json b/app/config/libraries/textdrawable.json index 529ea1bd..528a6354 100644 --- a/app/config/libraries/textdrawable.json +++ b/app/config/libraries/textdrawable.json @@ -1,5 +1,14 @@ { "uniqueId": "com.amulyakhare:com.amulyakhare.textdrawable", + "funding": [ + + ], + "developers": [ + + ], + "artifactVersion": "1.0.1", + "description": "This light-weight library provides images with letter/text like the Gmail app. It extends the Drawable class thus can be used with existing/custom/network ImageView classes. Also included is a fluent interface for creating drawables and a customizable ColorGenerator.", + "name": "textdrawable", "licenses": [ "MIT" ] diff --git a/app/config/libraries/trustedintents.json b/app/config/libraries/trustedintents.json new file mode 100644 index 00000000..5ba89066 --- /dev/null +++ b/app/config/libraries/trustedintents.json @@ -0,0 +1,23 @@ +{ + "uniqueId": "info.guardianproject.trustedintents:trustedintents", + "funding": [ + + ], + "developers": [ + { + "name": "Guardian Project" + } + ], + "artifactVersion": "0.2", + "description": "TrustedIntents is a library for flexible trusted interactions between Android apps. It is modeled after Android's `signature` protection level for permissions. The key difference is that the framework allows the trusted signature to be set, rather than requiring to match the current app's signature.", + "scm": { + "connection": "scm:https://github.com/guardianproject/TrustedIntents.git", + "url": "scm:https://github.com/guardianproject/TrustedIntents", + "developerConnection": "scm:git@github.com:guardianproject/TrustedIntents.git" + }, + "name": "TrustedIntents", + "website": "https://guardianproject.info/code/trustedintents", + "licenses": [ + "3ca920d1875f7ad7ab04a2a331958577" + ] +} \ No newline at end of file diff --git a/app/config/licenses/3ca920d1875f7ad7ab04a2a331958577.json b/app/config/licenses/3ca920d1875f7ad7ab04a2a331958577.json new file mode 100644 index 00000000..2f0d7c2a --- /dev/null +++ b/app/config/licenses/3ca920d1875f7ad7ab04a2a331958577.json @@ -0,0 +1,5 @@ +{ + "hash": "3ca920d1875f7ad7ab04a2a331958577", + "url": "https://github.com/guardianproject/TrustedIntents/blob/master/LICENSE.txt", + "name": "LGPLv2.1" +} \ No newline at end of file diff --git a/app/lint.xml b/app/lint.xml index 4cdb0450..f9f30d6e 100644 --- a/app/lint.xml +++ b/app/lint.xml @@ -1,10 +1,15 @@ + + - + + + + diff --git a/app/schemas/com.beemdevelopment.aegis.database.AppDatabase/1.json b/app/schemas/com.beemdevelopment.aegis.database.AppDatabase/1.json new file mode 100644 index 00000000..811e430c --- /dev/null +++ b/app/schemas/com.beemdevelopment.aegis.database.AppDatabase/1.json @@ -0,0 +1,52 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "392278bdb797d013cb2ada67a3b1cc60", + "entities": [ + { + "tableName": "audit_logs", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `event_type` TEXT NOT NULL, `reference` TEXT, `timestamp` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "_eventType", + "columnName": "event_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "_reference", + "columnName": "reference", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "_timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '392278bdb797d013cb2ada67a3b1cc60')" + ] + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestRunner.java b/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestRunner.java index 44c06845..970f9ff0 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestRunner.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestRunner.java @@ -3,8 +3,8 @@ package com.beemdevelopment.aegis; import android.app.Application; import android.app.Instrumentation; import android.content.Context; -import android.preference.PreferenceManager; +import androidx.preference.PreferenceManager; import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnitRunner; diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java b/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java index 9f15019b..e0151395 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java @@ -61,13 +61,20 @@ import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.RunWith; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.List; +import java.util.Locale; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -183,7 +190,9 @@ public class BackupExportTest extends AegisTest { onView(withText(R.string.export_format_html)).inRoot(RootMatchers.isPlatformPopup()).perform(click()); onView(withId(android.R.id.button1)).perform(click()); onView(withId(R.id.checkbox_accept)).perform(click()); - doExport(); + File file = doExport(); + + checkHtmlExport(file); } @Test @@ -196,7 +205,9 @@ public class BackupExportTest extends AegisTest { onView(withText(R.string.export_format_html)).inRoot(RootMatchers.isPlatformPopup()).perform(click()); onView(withId(android.R.id.button1)).perform(click()); onView(withId(R.id.checkbox_accept)).perform(click()); - doExport(); + File file = doExport(); + + checkHtmlExport(file); } @Test @@ -380,6 +391,26 @@ public class BackupExportTest extends AegisTest { checkReadEntries(entries); } + private void checkHtmlExport(File file) { + try (InputStream inStream = new FileInputStream(file)) { + Reader inReader = new InputStreamReader(inStream, StandardCharsets.UTF_8); + XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); + XmlPullParser parser = factory.newPullParser(); + parser.setInput(inReader); + while (parser.getEventType() != XmlPullParser.START_TAG) { + parser.next(); + } + if (!parser.getName().toLowerCase(Locale.ROOT).equals("html")) { + throw new RuntimeException("not an html document!"); + } + while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { + parser.next(); + } + } catch (IOException | XmlPullParserException e) { + throw new RuntimeException("Unable to read html export file", e); + } + } + private void checkReadEntries(Collection entries) { List vectors = VaultEntries.get(); assertEquals(vectors.size(), entries.size()); diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java b/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java index 6c12809e..016eb5c6 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java @@ -7,6 +7,7 @@ import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; import static androidx.test.espresso.action.ViewActions.longClick; import static androidx.test.espresso.action.ViewActions.pressBack; +import static androidx.test.espresso.action.ViewActions.scrollTo; import static androidx.test.espresso.action.ViewActions.typeText; import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant; import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA; @@ -118,10 +119,11 @@ public class OverallTest extends AegisTest { onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 1, longClick())); onView(withId(R.id.action_edit)).perform(click()); onView(withId(R.id.text_name)).perform(clearText(), typeText("Bob"), closeSoftKeyboard()); - onView(withId(R.id.dropdown_group)).perform(click()); - onView(withText(R.string.new_group)).inRoot(RootMatchers.isPlatformPopup()).perform(click()); + onView(withId(R.id.text_group)).perform(click()); + onView(withId(R.id.addGroup)).inRoot(RootMatchers.isDialog()).perform(click()); onView(withId(R.id.text_input)).perform(typeText(_groupName), closeSoftKeyboard()); onView(withId(android.R.id.button1)).perform(click()); + onView(withText(R.string.save)).perform(click()); onView(isRoot()).perform(pressBack()); onView(withId(android.R.id.button1)).perform(click()); @@ -175,12 +177,10 @@ public class OverallTest extends AegisTest { } private void changeGroupFilter(String text) { - onView(withId(R.id.chip_group)).perform(click()); if (text == null) { - onView(withId(R.id.btnClear)).perform(click()); + onView(allOf(withText(R.string.no_group), isDescendantOfA(withId(R.id.groupChipGroup)))).perform(click()); } else { - onView(withText(text)).perform(click()); - onView(isRoot()).perform(pressBack()); + onView(allOf(withText(text), isDescendantOfA(withId(R.id.groupChipGroup)))).perform(click()); } } @@ -188,7 +188,7 @@ public class OverallTest extends AegisTest { onView(withId(R.id.fab)).perform(click()); onView(withId(R.id.fab_enter)).perform(click()); - onView(withId(R.id.accordian_header)).perform(click()); + onView(withId(R.id.accordian_header)).perform(scrollTo(), click()); onView(withId(R.id.text_name)).perform(typeText(entry.getName()), closeSoftKeyboard()); onView(withId(R.id.text_issuer)).perform(typeText(entry.getIssuer()), closeSoftKeyboard()); @@ -208,7 +208,7 @@ public class OverallTest extends AegisTest { throw new RuntimeException(String.format("Unexpected entry type: %s", entry.getInfo().getClass().getSimpleName())); } - onView(withId(R.id.dropdown_type)).perform(click()); + onView(withId(R.id.dropdown_type)).perform(scrollTo(), click()); onView(withText(otpType)).inRoot(RootMatchers.isPlatformPopup()).perform(click()); } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d3ea78bb..09337184 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_outline_filter_list_24.xml b/app/src/main/res/drawable/ic_outline_filter_list_24.xml deleted file mode 100644 index ac6b9761..00000000 --- a/app/src/main/res/drawable/ic_outline_filter_list_24.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_outline_group_24.xml b/app/src/main/res/drawable/ic_outline_group_24.xml new file mode 100644 index 00000000..5c60ea3e --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_group_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_tag_24.xml b/app/src/main/res/drawable/ic_tag_24.xml new file mode 100644 index 00000000..66360540 --- /dev/null +++ b/app/src/main/res/drawable/ic_tag_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/progress_horizontal.xml b/app/src/main/res/drawable/progress_horizontal.xml index bb5fdac4..f6b62766 100644 --- a/app/src/main/res/drawable/progress_horizontal.xml +++ b/app/src/main/res/drawable/progress_horizontal.xml @@ -1,9 +1,14 @@ - + - + + - + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_background.xml b/app/src/main/res/drawable/rounded_background.xml deleted file mode 100644 index 682c748a..00000000 --- a/app/src/main/res/drawable/rounded_background.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 8a6c3b51..d4b17d0b 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -7,6 +7,7 @@ android:fitsSystemWindows="true" tools:context="com.beemdevelopment.aegis.ui.AboutActivity"> @@ -16,6 +17,7 @@ android:layout_height="?attr/actionBarSize" /> diff --git a/app/src/main/res/layout/activity_auth.xml b/app/src/main/res/layout/activity_auth.xml index b11f3b17..45e4ae12 100644 --- a/app/src/main/res/layout/activity_auth.xml +++ b/app/src/main/res/layout/activity_auth.xml @@ -5,6 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" + android:fitsSystemWindows="true" tools:context="com.beemdevelopment.aegis.ui.AuthActivity"> @@ -37,12 +38,13 @@ android:layout_width="match_parent" android:layout_height="250dp"> - + android:layout_centerVertical="true" + app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Aegis.ImageView.Circle" /> + android:inputType="textCapSentences"/> + android:inputType="textCapSentences"/> + + + + - + + + android:inputType="text|textMultiLine|textCapSentences"/> + android:inputType="textPassword|textMultiLine"/> - + android:orientation="vertical" + android:visibility="gone" + android:alpha="0" + android:layout_marginHorizontal="10dp"> - + + + - - - - - - - - - - - - - + + android:inputType="none"/> - + + android:inputType="none" /> - + + - + - - + + + - - - - - - - + + + + + android:src="@drawable/ic_counter_black_24" + app:tint="?attr/colorOnSurface" + android:layout_marginStart="5dp" + android:layout_marginEnd="15dp" + android:layout_gravity="center_vertical"/> + + + + + + + - - - + + diff --git a/app/src/main/res/layout/activity_groups.xml b/app/src/main/res/layout/activity_groups.xml index 611f4ad7..c9226446 100644 --- a/app/src/main/res/layout/activity_groups.xml +++ b/app/src/main/res/layout/activity_groups.xml @@ -8,6 +8,7 @@ tools:context="com.beemdevelopment.aegis.ui.GroupManagerActivity"> diff --git a/app/src/main/res/layout/activity_import_entries.xml b/app/src/main/res/layout/activity_import_entries.xml index da5eeef0..deba9ac1 100644 --- a/app/src/main/res/layout/activity_import_entries.xml +++ b/app/src/main/res/layout/activity_import_entries.xml @@ -9,6 +9,7 @@ tools:context="com.beemdevelopment.aegis.ui.ImportEntriesActivity"> @@ -22,7 +23,6 @@ android:id="@+id/list_entries" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingBottom="60dp" android:clipToPadding="false" android:scrollbars="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index ccc10366..b2ca2d00 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,6 +1,5 @@ - + + + + + + + + + + - - - - + android:orientation="vertical" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> @@ -48,6 +65,6 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" - android:src="@drawable/ic_outline_add_24" /> + android:src="@drawable/ic_outline_add_24" /> diff --git a/app/src/main/res/layout/activity_preferences.xml b/app/src/main/res/layout/activity_preferences.xml index 7bc815f2..3dc74edf 100644 --- a/app/src/main/res/layout/activity_preferences.xml +++ b/app/src/main/res/layout/activity_preferences.xml @@ -6,6 +6,7 @@ android:orientation="vertical" android:fitsSystemWindows="true"> diff --git a/app/src/main/res/layout/activity_scanner.xml b/app/src/main/res/layout/activity_scanner.xml index 64814633..29b4ed7e 100644 --- a/app/src/main/res/layout/activity_scanner.xml +++ b/app/src/main/res/layout/activity_scanner.xml @@ -9,7 +9,7 @@ tools:context="com.beemdevelopment.aegis.ui.ScannerActivity"> @@ -22,62 +22,56 @@ - - - - + android:layout_height="match_parent" + android:layout_marginTop="?attr/actionBarSize" + android:paddingHorizontal="30dp"> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + + app:layout_constraintTop_toBottomOf="@+id/ivQrCode" + tools:text="Issuer" /> + app:layout_constraintTop_toBottomOf="@+id/tvIssuer" + tools:text="Accountname" />