Skip to content

Commit

Permalink
Merge pull request #126 from anggrayudi/release/1.5.5
Browse files Browse the repository at this point in the history
Release/1.5.5
  • Loading branch information
anggrayudi authored Jun 27, 2023
2 parents 4d165e6 + efbd0a5 commit 64ca9da
Show file tree
Hide file tree
Showing 21 changed files with 123 additions and 76 deletions.
11 changes: 1 addition & 10 deletions .github/scripts/copy_env_variables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,9 @@ fi

mkdir "$HOME/.android"
keytool -genkey -v -keystore "$HOME/.android/debug.keystore" -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "C=US, O=Android, CN=Android Debug"
echo "$RELEASE_KEYSTORE_BASE64" | base64 --decode >"sample/keystore.jks"

if [ -n "$RELEASE_KEYSTORE_ALIAS" ]; then
{
printf "\nkeyAlias=%s" "$RELEASE_KEYSTORE_ALIAS"
printf "\nkeyPassword=%s" "$RELEASE_KEYSTORE_PASSWORD"
printf "\nstorePassword=%s" "$RELEASE_KEYSTORE_PASSWORD"
} >>local.properties
else
{
{
printf "\nkeyAlias=androiddebugkey"
printf "\nkeyPassword=android"
printf "\nstorePassword=android"
} >>local.properties
fi
4 changes: 2 additions & 2 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Setup JDK 11
- name: Setup JDK 17
uses: actions/setup-java@v1
with:
java-version: 11
java-version: 17

- name: Copy environment variables
env:
Expand Down
9 changes: 6 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ buildscript {

addRepos(repositories)

ext.kotlin_version = '1.7.20'
ext.kotlin_version = '1.8.22'

dependencies {
classpath 'com.android.tools:r8:3.3.75'
classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.android.tools.build:gradle:8.0.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.22.0'
classpath 'org.jetbrains.dokka:dokka-gradle-plugin:1.7.20'
Expand Down Expand Up @@ -57,6 +56,10 @@ subprojects {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

buildFeatures {
buildConfig true
}
}
configurations.all {
resolutionStrategy {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ kotlin.code.style=official
# For publishing:
GROUP=com.anggrayudi
POM_ARTIFACT_ID=storage
VERSION_NAME=1.5.4-SNAPSHOT
VERSION_NAME=1.5.5-SNAPSHOT
RELEASE_SIGNING_ENABLED=true
SONATYPE_AUTOMATIC_RELEASE=true
SONATYPE_HOST=DEFAULT
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
18 changes: 6 additions & 12 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,14 @@ android {
storeFile debugKeystore
}
release {
if (properties['keyAlias'] != null) {
keyAlias properties['keyAlias']
keyPassword properties['keyPassword']
storePassword properties['storePassword']
storeFile file('keystore.jks')
} else {
keyAlias 'androiddebugkey'
keyPassword 'android'
storePassword 'android'
storeFile debugKeystore
}
keyAlias 'androiddebugkey'
keyPassword 'android'
storePassword 'android'
storeFile debugKeystore
}
}

namespace 'com.anggrayudi.storage.sample'
defaultConfig {
applicationId "com.anggrayudi.storage.sample"
multiDexEnabled true
Expand All @@ -48,7 +42,7 @@ android {
}
}

lintOptions {
lint {
abortOnError false
}

Expand Down
5 changes: 2 additions & 3 deletions sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.anggrayudi.storage.sample">
xmlns:tools="http://schemas.android.com/tools">

<!-- Add this permission if your app requires full disk access -->
<uses-permission
Expand All @@ -16,7 +15,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup">
tools:ignore="AllowBackup,LockedOrientationActivity">
<activity
android:name=".activity.MainActivity"
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private void setupSimpleStorage(Bundle savedState) {
String absolutePath = DocumentFileUtils.getAbsolutePath(root, getBaseContext());
Toast.makeText(
getBaseContext(),
getString(R.string.ss_selecting_root_path_success_without_open_folder_picker, absolutePath),
getString(com.anggrayudi.storage.R.string.ss_selecting_root_path_success_without_open_folder_picker, absolutePath),
Toast.LENGTH_SHORT
).show();
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class MainActivity : AppCompatActivity() {
storageHelper.onStorageAccessGranted = { _, root ->
Toast.makeText(
this,
getString(R.string.ss_selecting_root_path_success_without_open_folder_picker, root.getAbsolutePath(this)),
getString(com.anggrayudi.storage.R.string.ss_selecting_root_path_success_without_open_folder_picker, root.getAbsolutePath(this)),
Toast.LENGTH_SHORT
).show()
}
Expand Down
17 changes: 9 additions & 8 deletions storage/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
namespace 'com.anggrayudi.storage'
resourcePrefix 'ss_'

defaultConfig {
consumerProguardFiles "consumer-rules.pro"
}
Expand All @@ -13,15 +16,13 @@ android {
}
}

lintOptions {
lint {
abortOnError false
}

buildFeatures {
viewBinding = true
}

resourcePrefix 'ss_'
}

dependencies {
Expand All @@ -33,17 +34,17 @@ dependencies {
api deps.coroutines.core
api deps.coroutines.android
api 'com.afollestad.material-dialogs:files:3.3.0'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"

testImplementation deps.junit
testImplementation deps.mockk
testImplementation deps.robolectric

// TODO: Replace with MockK after feature "mock java.io.File" has been fixed: https://github.com/mockk/mockk/issues/603
testImplementation "org.mockito:mockito-core:3.3.3"
testImplementation "org.mockito:mockito-inline:3.3.3"
testImplementation "org.mockito:mockito-core:3.10.0"
testImplementation "org.mockito:mockito-inline:3.10.0"
testImplementation "org.mockito:mockito-all:1.10.19"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
testImplementation "org.powermock:powermock-api-mockito2:2.0.5"
testImplementation "org.powermock:powermock-module-junit4:2.0.5"
testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
testImplementation "org.powermock:powermock-module-junit4:2.0.9"
}
6 changes: 3 additions & 3 deletions storage/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.anggrayudi.storage">
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
Expand Down
34 changes: 17 additions & 17 deletions storage/src/main/java/com/anggrayudi/storage/SimpleStorage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,8 @@ class SimpleStorage private constructor(private val wrapper: ComponentWrapper) {
private const val KEY_LAST_VISITED_FOLDER = BuildConfig.LIBRARY_PACKAGE_NAME + ".lastVisitedFolder"
private const val TAG = "SimpleStorage"

const val KITKAT_SD_CARD_PATH = "/storage/sdcard"
const val KITKAT_SD_CARD_ID = "sdcard"
const val KITKAT_SD_CARD_PATH = "/storage/$KITKAT_SD_CARD_ID"

@JvmStatic
@Suppress("DEPRECATION")
Expand Down Expand Up @@ -618,8 +619,9 @@ class SimpleStorage private constructor(private val wrapper: ComponentWrapper) {
@JvmStatic
@JvmOverloads
fun hasStorageAccess(context: Context, fullPath: String, requiresWriteAccess: Boolean = true): Boolean {
return (requiresWriteAccess && hasStoragePermission(context) || !requiresWriteAccess && hasStorageReadPermission(context))
&& DocumentFileCompat.getAccessibleRootDocumentFile(context, fullPath, requiresWriteAccess) != null
return DocumentFileCompat.getAccessibleRootDocumentFile(context, fullPath, requiresWriteAccess) != null
&& (Build.VERSION.SDK_INT > Build.VERSION_CODES.P
|| requiresWriteAccess && hasStoragePermission(context) || !requiresWriteAccess && hasStorageReadPermission(context))
}

/**
Expand All @@ -632,20 +634,18 @@ class SimpleStorage private constructor(private val wrapper: ComponentWrapper) {
* Read [Count Your SAF Uri Persisted Permissions!](https://commonsware.com/blog/2020/06/13/count-your-saf-uri-permission-grants.html)
*/
@JvmStatic
fun cleanupRedundantUriPermissions(context: Context) {
thread {
val resolver = context.contentResolver
// e.g. content://com.android.externalstorage.documents/tree/primary%3AMusic
val persistedUris = resolver.persistedUriPermissions
.filter { it.isReadPermission && it.isWritePermission && it.uri.isExternalStorageDocument }
.map { it.uri }
val writeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
val uniqueUriParents = DocumentFileCompat.findUniqueParents(context, persistedUris.mapNotNull { it.path?.substringAfter("/tree/") })
persistedUris.forEach {
if (DocumentFileCompat.buildAbsolutePath(context, it.path.orEmpty().substringAfter("/tree/")) !in uniqueUriParents) {
resolver.releasePersistableUriPermission(it, writeFlags)
Log.d(TAG, "Removed redundant URI permission => $it")
}
fun cleanupRedundantUriPermissions(context: Context) = thread {
val resolver = context.contentResolver
// e.g. content://com.android.externalstorage.documents/tree/primary%3AMusic
val persistedUris = resolver.persistedUriPermissions
.filter { it.isReadPermission && it.isWritePermission && it.uri.isExternalStorageDocument }
.map { it.uri }
val writeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
val uniqueUriParents = DocumentFileCompat.findUniqueParents(context, persistedUris.mapNotNull { it.path?.substringAfter("/tree/") })
persistedUris.forEach {
if (DocumentFileCompat.buildAbsolutePath(context, it.path.orEmpty().substringAfter("/tree/")) !in uniqueUriParents) {
resolver.releasePersistableUriPermission(it, writeFlags)
Log.d(TAG, "Removed redundant URI permission => $it")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat
import androidx.documentfile.provider.DocumentFile
import com.anggrayudi.storage.FileWrapper
import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.SimpleStorage.Companion.KITKAT_SD_CARD_ID
import com.anggrayudi.storage.SimpleStorage.Companion.KITKAT_SD_CARD_PATH
import com.anggrayudi.storage.extension.*
import com.anggrayudi.storage.file.StorageId.DATA
Expand Down Expand Up @@ -64,10 +65,10 @@ object DocumentFileCompat {
val SD_CARD_STORAGE_ID_REGEX = Regex("[A-Z0-9]{4}-[A-Z0-9]{4}")

@RestrictTo(RestrictTo.Scope.LIBRARY)
val SD_CARD_STORAGE_PATH_REGEX = Regex("[A-Z0-9]{4}-[A-Z0-9]{4}(.*?)")
val SD_CARD_STORAGE_PATH_REGEX = Regex("/storage/$SD_CARD_STORAGE_ID_REGEX(.*?)")

@RestrictTo(RestrictTo.Scope.LIBRARY)
fun getKitkatSdCardRootFile(basePath: String = "") = File(SimpleStorage.KITKAT_SD_CARD_PATH + "/$basePath".trimEnd('/'))
fun getKitkatSdCardRootFile(basePath: String = "") = File(KITKAT_SD_CARD_PATH + "/$basePath".trimEnd('/'))

@JvmStatic
fun isRootUri(uri: Uri): Boolean {
Expand All @@ -86,7 +87,10 @@ object DocumentFileCompat {
when {
fullPath.startsWith(SimpleStorage.externalStoragePath) -> PRIMARY
fullPath.startsWith(context.dataDirectory.path) -> DATA
else -> fullPath.substringAfter("/storage/", "").substringBefore('/')
fullPath.startsWith(KITKAT_SD_CARD_PATH) -> KITKAT_SD_CARD_ID
else -> if (fullPath.matches(SD_CARD_STORAGE_PATH_REGEX)) {
fullPath.substringAfter("/storage/", "").substringBefore('/')
} else ""
}
} else {
fullPath.substringBefore(':', "").substringAfterLast('/')
Expand All @@ -107,7 +111,10 @@ object DocumentFileCompat {
when {
fullPath.startsWith(externalStoragePath) -> fullPath.substringAfter(externalStoragePath)
fullPath.startsWith(dataDir) -> fullPath.substringAfter(dataDir)
else -> fullPath.substringAfter("/storage/", "").substringAfter('/', "")
fullPath.startsWith(KITKAT_SD_CARD_PATH) -> fullPath.substringAfter(KITKAT_SD_CARD_PATH)
else -> if (fullPath.matches(SD_CARD_STORAGE_PATH_REGEX)) {
fullPath.substringAfter("/storage/", "").substringAfter('/', "")
} else ""
}
} else {
fullPath.substringAfter(':', "")
Expand Down
6 changes: 5 additions & 1 deletion storage/src/main/java/com/anggrayudi/storage/file/FileExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.anggrayudi.storage.extension.trimFileSeparator
import com.anggrayudi.storage.file.DocumentFileCompat.removeForbiddenCharsFromFilename
import com.anggrayudi.storage.file.StorageId.DATA
import com.anggrayudi.storage.file.StorageId.HOME
import com.anggrayudi.storage.file.StorageId.KITKAT_SDCARD
import com.anggrayudi.storage.file.StorageId.PRIMARY
import java.io.File
import java.io.IOException
Expand All @@ -34,7 +35,10 @@ import java.io.IOException
fun File.getStorageId(context: Context) = when {
path.startsWith(SimpleStorage.externalStoragePath) -> PRIMARY
path.startsWith(context.dataDirectory.path) -> DATA
else -> path.substringAfter("/storage/", "").substringBefore('/')
path.startsWith(SimpleStorage.KITKAT_SD_CARD_PATH) -> KITKAT_SDCARD
else -> if (path.matches(DocumentFileCompat.SD_CARD_STORAGE_PATH_REGEX)) {
path.substringAfter("/storage/", "").substringBefore('/')
} else ""
}

val File.inPrimaryStorage: Boolean
Expand Down
27 changes: 20 additions & 7 deletions storage/src/main/java/com/anggrayudi/storage/file/FileFullPath.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import android.os.storage.StorageManager
import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.SimpleStorage.Companion.KITKAT_SD_CARD_PATH
import com.anggrayudi.storage.extension.fromTreeUri
import com.anggrayudi.storage.extension.trimFileSeparator
import com.anggrayudi.storage.file.StorageId.KITKAT_SDCARD
import java.io.File

/**
Expand Down Expand Up @@ -48,23 +50,34 @@ class FileFullPath {
when {
fullPath.startsWith(SimpleStorage.externalStoragePath) -> {
storageId = StorageId.PRIMARY
val externalPath = SimpleStorage.externalStoragePath
basePath = fullPath.substringAfter(externalPath, "").trimFileSeparator()
val rootPath = SimpleStorage.externalStoragePath
basePath = fullPath.substringAfter(rootPath, "").trimFileSeparator()
simplePath = "$storageId:$basePath"
absolutePath = "$externalPath/$basePath".trimEnd('/')
absolutePath = "$rootPath/$basePath".trimEnd('/')
}
fullPath.startsWith(context.dataDirectory.path) -> {
storageId = StorageId.DATA
val dataPath = context.dataDirectory.path
basePath = fullPath.substringAfter(dataPath, "").trimFileSeparator()
val rootPath = context.dataDirectory.path
basePath = fullPath.substringAfter(rootPath, "").trimFileSeparator()
simplePath = "$storageId:$basePath"
absolutePath = "$dataPath/$basePath".trimEnd('/')
absolutePath = "$rootPath/$basePath".trimEnd('/')
}
else -> {
fullPath.startsWith(KITKAT_SD_CARD_PATH) -> {
storageId = KITKAT_SDCARD
basePath = fullPath.substringAfter(KITKAT_SD_CARD_PATH, "").trimFileSeparator()
simplePath = "$storageId:$basePath"
absolutePath = "$KITKAT_SD_CARD_PATH/$basePath".trimEnd('/')
}
else -> if (fullPath.matches(DocumentFileCompat.SD_CARD_STORAGE_PATH_REGEX)) {
storageId = fullPath.substringAfter("/storage/", "").substringBefore('/')
basePath = fullPath.substringAfter("/storage/$storageId", "").trimFileSeparator()
simplePath = "$storageId:$basePath"
absolutePath = "/storage/$storageId/$basePath".trimEnd('/')
} else {
storageId = ""
basePath = ""
simplePath = ""
absolutePath = ""
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ class ActivityPermissionRequest private constructor(
}

private fun reportResult(reports: List<PermissionReport>) {
if (reports.isEmpty()) {
callback.onPermissionRequestInterrupted(permissions)
return
}
val blockedPermissions = reports.filter { it.deniedPermanently }
if (blockedPermissions.isEmpty()) {
callback.onPermissionsChecked(PermissionResult(reports), true)
Expand Down
Loading

0 comments on commit 64ca9da

Please sign in to comment.