Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
deckerst committed Oct 30, 2024
2 parents 1c1be8b + be1e962 commit 530bd1a
Show file tree
Hide file tree
Showing 273 changed files with 3,829 additions and 1,602 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ jobs:
egress-policy: audit

- name: 'Checkout Repository'
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: 'Dependency Review'
uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
uses: actions/dependency-review-action@4081bf99e2866ebe428fc0477b69eb4fcda7220a # v4.4.0
10 changes: 5 additions & 5 deletions .github/workflows/quality-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Get Flutter packages
run: scripts/pub_get_all.sh
Expand Down Expand Up @@ -59,17 +59,17 @@ jobs:
# Building relies on the Android Gradle plugin,
# which requires a modern Java version (not the default one).
- name: Set up JDK for Android Gradle plugin
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
with:
distribution: 'temurin'
java-version: '21'

- name: Checkout repository
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
Expand All @@ -83,6 +83,6 @@ jobs:
./flutterw build apk --profile -t lib/main_play.dart --flavor play
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0
with:
category: "/language:${{matrix.language}}"
13 changes: 10 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ jobs:
name: GitHub release
runs-on: ubuntu-latest
permissions:
attestations: write
contents: write
id-token: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
Expand All @@ -23,13 +25,13 @@ jobs:
# Building relies on the Android Gradle plugin,
# which requires a modern Java version (not the default one).
- name: Set up JDK for Android Gradle plugin
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
with:
distribution: 'temurin'
java-version: '21'

- name: Checkout repository
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Get Flutter packages
run: scripts/pub_get_all.sh
Expand Down Expand Up @@ -72,6 +74,11 @@ jobs:
AVES_KEY_PASSWORD: ${{ secrets.AVES_KEY_PASSWORD }}
AVES_GOOGLE_API_KEY: ${{ secrets.AVES_GOOGLE_API_KEY }}

- name: Generate artifact attestation
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
with:
subject-path: 'outputs/*'

- name: Create GitHub release
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
with:
Expand All @@ -96,7 +103,7 @@ jobs:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Get appbundle from artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/scorecards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
egress-policy: audit

- name: "Checkout code"
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

Expand Down Expand Up @@ -71,6 +71,6 @@ jobs:

# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0
with:
sarif_file: results.sarif
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.

## <a id="unreleased"></a>[Unreleased]

## <a id="v1.11.17"></a>[v1.11.17] - 2024-10-30

### Added

- Map: create shortcut to custom region and filters
- Video: frame stepping forward/backward
- Video: custom playback buttons
- English (Shavian) translation (thanks Paranoid Android)

### Changed

- upgraded Flutter to stable v3.24.4

### Fixed

- crash when loading large collection
- Viewer: copying content URI item
- Albums: creating album with same name as existing empty directory
- Privacy: tagging while vaults are unlocked does not yield recent tags visible when vaults are locked

## <a id="v1.11.16"></a>[v1.11.16] - 2024-10-10

### Fixed
Expand Down
22 changes: 5 additions & 17 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id 'com.android.application'
id 'com.google.devtools.ksp'
Expand Down Expand Up @@ -30,16 +28,15 @@ if (keystorePropertiesFile.exists()) {
keystoreProperties["googleApiKey"] = System.getenv("AVES_GOOGLE_API_KEY") ?: "<NONE>"
}

kotlin {
jvmToolchain 17
}

android {
namespace 'deckers.thibault.aves'
compileSdk 35
// cf https://developer.android.com/studio/projects/install-ndk#default-ndk-per-agp
ndkVersion '26.1.10909125'

compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
ndkVersion '27.0.12077973'

defaultConfig {
applicationId packageName
Expand Down Expand Up @@ -133,15 +130,6 @@ android {
}
}

tasks.withType(KotlinCompile).configureEach {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

kotlin {
jvmToolchain(21)
}

flutter {
source '../..'
}
Expand Down
3 changes: 3 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@
<!--
Impeller is not supported by `media_kit` v1.1.10+1:
https://github.com/media-kit/media-kit/issues/707
Screenshot driver scenario is not supported by Impeller:
"Compressed screenshots not supported for Impeller"
-->
<meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
Expand Down
69 changes: 46 additions & 23 deletions android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import deckers.thibault.aves.channel.streams.MediaStoreStreamHandler
import deckers.thibault.aves.channel.streams.SettingsChangeStreamHandler
import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.anyCauseIs
import deckers.thibault.aves.utils.getParcelableExtraCompat
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
Expand Down Expand Up @@ -314,6 +315,7 @@ open class MainActivity : FlutterFragmentActivity() {
return hashMapOf(
INTENT_DATA_KEY_ACTION to INTENT_ACTION_VIEW_GEO,
INTENT_DATA_KEY_URI to uri.toString(),
INTENT_DATA_KEY_FILTERS to extractFiltersFromIntent(intent),
)
}

Expand Down Expand Up @@ -370,7 +372,8 @@ open class MainActivity : FlutterFragmentActivity() {
return hashMapOf(
INTENT_DATA_KEY_ACTION to INTENT_ACTION_PICK_ITEMS,
INTENT_DATA_KEY_MIME_TYPE to intent.type,
INTENT_DATA_KEY_ALLOW_MULTIPLE to (intent.extras?.getBoolean(Intent.EXTRA_ALLOW_MULTIPLE) ?: false),
INTENT_DATA_KEY_MIME_TYPES to intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES)?.toList(),
INTENT_DATA_KEY_ALLOW_MULTIPLE to intent.getBooleanExtra(Intent.EXTRA_ALLOW_MULTIPLE, false),
)
}

Expand Down Expand Up @@ -432,33 +435,50 @@ open class MainActivity : FlutterFragmentActivity() {

open fun submitPickedItems(call: MethodCall, result: MethodChannel.Result) {
val pickedUris = call.argument<List<String>>("uris")
try {
if (!pickedUris.isNullOrEmpty()) {
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, Uri.parse(uriString)) }
val intent = Intent().apply {
val firstUri = toUri(pickedUris.first())
if (pickedUris.size == 1) {
data = firstUri
} else {
clipData = ClipData.newUri(contentResolver, null, firstUri).apply {
pickedUris.drop(1).forEach {
addItem(ClipData.Item(toUri(it)))
}
}
if (pickedUris.isNullOrEmpty()) {
setResult(RESULT_CANCELED)
// move code triggering `Binder` call off the main thread
defaultScope.launch { finish() }
return
}

val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, Uri.parse(uriString)) }
val intent = Intent().apply {
val firstUri = toUri(pickedUris.first())
if (pickedUris.size == 1) {
data = firstUri
} else {
clipData = ClipData.newUri(contentResolver, null, firstUri).apply {
pickedUris.drop(1).forEach {
addItem(ClipData.Item(toUri(it)))
}
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
setResult(RESULT_OK, intent)
} else {
setResult(RESULT_CANCELED)
}
// move code triggering `Binder` call off the main thread
defaultScope.launch { finish() }
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
// move code triggering `Binder` call off the main thread
defaultScope.launch {
submitPickedItemsIntent(intent, result)
}
}

private fun submitPickedItemsIntent(intent: Intent, result: MethodChannel.Result) {
try {
setResult(RESULT_OK, intent)
finish()
} catch (e: Exception) {
if (e is TransactionTooLargeException || e.cause is TransactionTooLargeException) {
result.error("submitPickedItems-large", "transaction too large with ${pickedUris?.size} URIs", e)
setResult(RESULT_CANCELED)
if (e is SecurityException && intent.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION != 0) {
// in some environments, providing the write flag yields a `SecurityException`:
// "UID XXXX does not have permission to content://XXXX"
// so we retry without it
Log.i(LOG_TAG, "retry submitting picked items without FLAG_GRANT_WRITE_URI_PERMISSION")
intent.flags = intent.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION.inv()
submitPickedItemsIntent(intent, result)
} else if (e.anyCauseIs<TransactionTooLargeException>()) {
result.error("submitPickedItems-large", "transaction too large with ${intent.clipData?.itemCount} URIs", e)
} else {
result.error("submitPickedItems-exception", "failed to pick ${pickedUris?.size} URIs", e)
result.error("submitPickedItems-exception", "failed to pick ${intent.clipData?.itemCount} URIs", e)
}
}
}
Expand Down Expand Up @@ -552,6 +572,7 @@ open class MainActivity : FlutterFragmentActivity() {
const val INTENT_DATA_KEY_EXPLORER_PATH = "explorerPath"
const val INTENT_DATA_KEY_FILTERS = "filters"
const val INTENT_DATA_KEY_MIME_TYPE = "mimeType"
const val INTENT_DATA_KEY_MIME_TYPES = "mimeTypes"
const val INTENT_DATA_KEY_PAGE = "page"
const val INTENT_DATA_KEY_QUERY = "query"
const val INTENT_DATA_KEY_SECURE_URIS = "secureUris"
Expand All @@ -566,6 +587,8 @@ open class MainActivity : FlutterFragmentActivity() {

// dart page routes
const val COLLECTION_PAGE_ROUTE_NAME = "/collection"
const val ENTRY_VIEWER_PAGE_ROUTE_NAME = "/viewer"
const val EXPLORER_PAGE_ROUTE_NAME = "/explorer"
const val MAP_PAGE_ROUTE_NAME = "/map"
const val SEARCH_PAGE_ROUTE_NAME = "/search"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package deckers.thibault.aves.channel.calls

import android.app.ActivityManager
import android.content.Context
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
Expand Down Expand Up @@ -51,6 +52,17 @@ class AnalysisHandler(private val activity: FlutterFragmentActivity, private val
return
}

val activityManager: ActivityManager = activity.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningAppProcesses = activityManager.runningAppProcesses
if (runningAppProcesses != null) {
val importance = runningAppProcesses[0].importance
if (importance < ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
// the app is in the background
result.error("startAnalysis-background", "app is in the background (process importance=$importance)", null)
return
}
}

// can be null or empty
val allEntryIds = call.argument<List<Int>>("entryIds")

Expand Down
Loading

0 comments on commit 530bd1a

Please sign in to comment.