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 8, 2024
2 parents 53b8e5b + 9401dd2 commit 35aeefe
Show file tree
Hide file tree
Showing 201 changed files with 1,947 additions and 1,284 deletions.
2 changes: 1 addition & 1 deletion .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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: 'Dependency Review'
uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1

- 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@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4.3.0
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
with:
distribution: 'temurin'
java-version: '21'

- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7
uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
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@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7
uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
with:
category: "/language:${{matrix.language}}"
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,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@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4.3.0
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
with:
distribution: 'temurin'
java-version: '21'

- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1

- name: Get Flutter packages
run: scripts/pub_get_all.sh
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Upload app bundle
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1
with:
name: appbundle
path: outputs/app-play-release.aab
Expand All @@ -96,7 +96,7 @@ jobs:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1

- name: Get appbundle from artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
Expand Down
6 changes: 3 additions & 3 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
with:
persist-credentials: false

Expand All @@ -63,14 +63,14 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1
with:
name: SARIF file
path: results.sarif
retention-days: 5

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

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

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

### Added

- Map: OpenTopoMap raster layer
- Map: OSM Liberty vector layer (hosted by OSM Americana)
- Interoperability: receiving `geo:` URI generally opens map page at location
- Interoperability: receiving `geo:` URI when editing item location fills in coordinates
- Map basic app shortcut
- Enterprise: support for work profile switching from the drawer
- Settings: hidden path filters are merged with others and can be toggled

### Removed

- `Safe mode` basic app shortcut

### Fixed

- hanging when cataloguing some JPEG MPF images
- Apple HDR image detection

## <a id="v1.11.13"></a>[v1.11.13] - 2024-09-17

### Added
Expand Down Expand Up @@ -1126,6 +1147,7 @@ All notable changes to this project will be documented in this file.

- app launching on some devices
- corrupting motion photo exif editing (e.g. rotation)
- accessing files in `Download` directory when not using reference case

## [v1.4.9] - 2021-08-20

Expand Down
5 changes: 5 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ linter:
prefer_single_quotes: true
sort_child_properties_last: true
unawaited_futures: true

# `const` related, included
prefer_const_constructors: true
prefer_const_literals_to_create_immutables: true
prefer_const_declarations: true
28 changes: 3 additions & 25 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@ plugins {

def packageName = "deckers.thibault.aves"

// Flutter properties

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
def flutterVersionName = localProperties.getProperty('flutter.versionName')

// Keys

def keystoreProperties = new Properties()
Expand Down Expand Up @@ -53,22 +41,12 @@ android {
targetCompatibility JavaVersion.VERSION_21
}

lint {
checkAllWarnings true
warningsAsErrors true
disable 'InvalidPackage'
}

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

defaultConfig {
applicationId packageName
minSdk flutter.minSdkVersion
targetSdk 35
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
versionCode flutter.versionCode
versionName flutter.versionName
manifestPlaceholders = [googleApiKey: keystoreProperties["googleApiKey"] ?: "<NONE>"]
multiDexEnabled true
}
Expand Down Expand Up @@ -189,7 +167,7 @@ dependencies {

implementation "androidx.appcompat:appcompat:1.7.0"
implementation 'androidx.core:core-ktx:1.13.1'
implementation 'androidx.lifecycle:lifecycle-process:2.8.5'
implementation 'androidx.lifecycle:lifecycle-process:2.8.6'
implementation 'androidx.media:media:1.7.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
Expand Down
11 changes: 11 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROCESSING"
tools:ignore="SystemPermissionTypo" />
<!-- to switch between regular and work profiles -->
<uses-permission
android:name="android.permission.INTERACT_ACROSS_PROFILES"
tools:ignore="ProtectedPermissions" />
<!-- TODO TLAD still needed to fetch map tiles / reverse geocoding / else ? check in release mode -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- from Android 12 (API 31), users can optionally grant access to the media management special permission -->
Expand Down Expand Up @@ -179,6 +183,13 @@
<data android:scheme="content" />
<data android:scheme="file" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />

<data android:scheme="geo" />
</intent-filter>
<!--
<intent-filter>
<action android:name="android.intent.action.EDIT" />
Expand Down
60 changes: 36 additions & 24 deletions android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package deckers.thibault.aves

import android.annotation.SuppressLint
import android.app.KeyguardManager
import android.app.SearchManager
import android.appwidget.AppWidgetManager
import android.content.ClipData
Expand All @@ -23,6 +24,7 @@ import deckers.thibault.aves.channel.AvesByteSendingMethodCodec
import deckers.thibault.aves.channel.calls.AccessibilityHandler
import deckers.thibault.aves.channel.calls.AnalysisHandler
import deckers.thibault.aves.channel.calls.AppAdapterHandler
import deckers.thibault.aves.channel.calls.AppProfileHandler
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.channel.calls.DebugHandler
import deckers.thibault.aves.channel.calls.DeviceHandler
Expand Down Expand Up @@ -142,6 +144,7 @@ open class MainActivity : FlutterFragmentActivity() {
MethodChannel(messenger, MetadataEditHandler.CHANNEL).setMethodCallHandler(MetadataEditHandler(this))
MethodChannel(messenger, WallpaperHandler.CHANNEL).setMethodCallHandler(WallpaperHandler(this))
// - need Activity
MethodChannel(messenger, AppProfileHandler.CHANNEL).setMethodCallHandler(AppProfileHandler(this))
MethodChannel(messenger, WindowHandler.CHANNEL).setMethodCallHandler(ActivityWindowHandler(this))

// result streaming: dart -> platform ->->-> dart
Expand Down Expand Up @@ -293,14 +296,11 @@ open class MainActivity : FlutterFragmentActivity() {
open fun extractIntentData(intent: Intent?): FieldMap {
when (val action = intent?.action) {
Intent.ACTION_MAIN -> {
val fields = HashMap<String, Any?>()
if (intent.getBooleanExtra(EXTRA_KEY_SAFE_MODE, false)) {
fields[INTENT_DATA_KEY_SAFE_MODE] = true
}
fields[INTENT_DATA_KEY_PAGE] = intent.getStringExtra(EXTRA_KEY_PAGE)
fields[INTENT_DATA_KEY_FILTERS] = extractFiltersFromIntent(intent)
fields[INTENT_DATA_KEY_EXPLORER_PATH] = intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH)
return fields
return hashMapOf(
INTENT_DATA_KEY_PAGE to intent.getStringExtra(EXTRA_KEY_PAGE),
INTENT_DATA_KEY_FILTERS to extractFiltersFromIntent(intent),
INTENT_DATA_KEY_EXPLORER_PATH to intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH),
)
}

Intent.ACTION_VIEW,
Expand All @@ -310,6 +310,13 @@ open class MainActivity : FlutterFragmentActivity() {
"com.android.camera.action.REVIEW",
"com.android.camera.action.SPLIT_SCREEN_REVIEW" -> {
(intent.data ?: intent.getParcelableExtraCompat<Uri>(Intent.EXTRA_STREAM))?.let { uri ->
if (uri.scheme == "geo") {
return hashMapOf(
INTENT_DATA_KEY_ACTION to INTENT_ACTION_VIEW_GEO,
INTENT_DATA_KEY_URI to uri.toString(),
)
}

// MIME type is optional
val type = intent.type ?: intent.resolveType(this)
val fields = hashMapOf<String, Any?>(
Expand All @@ -318,7 +325,7 @@ open class MainActivity : FlutterFragmentActivity() {
INTENT_DATA_KEY_URI to uri.toString(),
)

val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as android.app.KeyguardManager
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val isLocked = keyguardManager.isKeyguardLocked
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(isLocked)
Expand Down Expand Up @@ -427,7 +434,7 @@ open class MainActivity : FlutterFragmentActivity() {
val pickedUris = call.argument<List<String>>("uris")
try {
if (!pickedUris.isNullOrEmpty()) {
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this, Uri.parse(uriString)) }
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, Uri.parse(uriString)) }
val intent = Intent().apply {
val firstUri = toUri(pickedUris.first())
if (pickedUris.size == 1) {
Expand All @@ -445,7 +452,8 @@ open class MainActivity : FlutterFragmentActivity() {
} else {
setResult(RESULT_CANCELED)
}
finish()
// move code triggering `Binder` call off the main thread
defaultScope.launch { finish() }
} catch (e: Exception) {
if (e is TransactionTooLargeException || e.cause is TransactionTooLargeException) {
result.error("submitPickedItems-large", "transaction too large with ${pickedUris?.size} URIs", e)
Expand Down Expand Up @@ -481,30 +489,30 @@ open class MainActivity : FlutterFragmentActivity() {
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_search else R.drawable.ic_shortcut_search))
.setIntent(
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
.putExtra(EXTRA_KEY_PAGE, "/search")
.putExtra(EXTRA_KEY_PAGE, SEARCH_PAGE_ROUTE_NAME)
)
.build()

val videos = ShortcutInfoCompat.Builder(this, "videos")
.setShortLabel(getString(R.string.videos_shortcut_short_label))
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_movie else R.drawable.ic_shortcut_movie))
val map = ShortcutInfoCompat.Builder(this, "map")
.setShortLabel(getString(R.string.map_shortcut_short_label))
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_map else R.drawable.ic_shortcut_map))
.setIntent(
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
.putExtra(EXTRA_KEY_PAGE, "/collection")
.putExtra("filters", arrayOf("{\"type\":\"mime\",\"mime\":\"video/*\"}"))
.putExtra(EXTRA_KEY_PAGE, MAP_PAGE_ROUTE_NAME)
)
.build()

val safeMode = ShortcutInfoCompat.Builder(this, "safeMode")
.setShortLabel(getString(R.string.safe_mode_shortcut_short_label))
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_safe_mode else R.drawable.ic_shortcut_safe_mode))
val videos = ShortcutInfoCompat.Builder(this, "videos")
.setShortLabel(getString(R.string.videos_shortcut_short_label))
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_movie else R.drawable.ic_shortcut_movie))
.setIntent(
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
.putExtra(EXTRA_KEY_SAFE_MODE, true)
.putExtra(EXTRA_KEY_PAGE, COLLECTION_PAGE_ROUTE_NAME)
.putExtra("filters", arrayOf("{\"type\":\"mime\",\"mime\":\"video/*\"}"))
)
.build()

val shortcutInfoList = listOf(videos, search, safeMode)
val shortcutInfoList = listOf(videos, search, map)
ShortcutManagerCompat.setDynamicShortcuts(this, shortcutInfoList)
Log.i(LOG_TAG, "set shortcuts: ${shortcutInfoList.joinToString(", ") { v -> v.id }}")
}
Expand Down Expand Up @@ -534,6 +542,7 @@ open class MainActivity : FlutterFragmentActivity() {
const val INTENT_ACTION_SEARCH = "search"
const val INTENT_ACTION_SET_WALLPAPER = "set_wallpaper"
const val INTENT_ACTION_VIEW = "view"
const val INTENT_ACTION_VIEW_GEO = "view_geo"
const val INTENT_ACTION_WIDGET_OPEN = "widget_open"
const val INTENT_ACTION_WIDGET_SETTINGS = "widget_settings"

Expand All @@ -545,7 +554,6 @@ open class MainActivity : FlutterFragmentActivity() {
const val INTENT_DATA_KEY_MIME_TYPE = "mimeType"
const val INTENT_DATA_KEY_PAGE = "page"
const val INTENT_DATA_KEY_QUERY = "query"
const val INTENT_DATA_KEY_SAFE_MODE = "safeMode"
const val INTENT_DATA_KEY_SECURE_URIS = "secureUris"
const val INTENT_DATA_KEY_URI = "uri"
const val INTENT_DATA_KEY_WIDGET_ID = "widgetId"
Expand All @@ -554,9 +562,13 @@ open class MainActivity : FlutterFragmentActivity() {
const val EXTRA_KEY_EXPLORER_PATH = "explorerPath"
const val EXTRA_KEY_FILTERS_ARRAY = "filters"
const val EXTRA_KEY_FILTERS_STRING = "filtersString"
const val EXTRA_KEY_SAFE_MODE = "safeMode"
const val EXTRA_KEY_WIDGET_ID = "widgetId"

// dart page routes
const val COLLECTION_PAGE_ROUTE_NAME = "/collection"
const val MAP_PAGE_ROUTE_NAME = "/map"
const val SEARCH_PAGE_ROUTE_NAME = "/search"

// request code to pending runnable
val pendingStorageAccessResultHandlers = ConcurrentHashMap<Int, PendingStorageAccessResultHandler>()

Expand Down
Loading

0 comments on commit 35aeefe

Please sign in to comment.