From b5060e6f47c0d90969d1b022c2ccffc55134577f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedger=20M=C3=BCffke?= Date: Fri, 22 Nov 2019 15:49:30 +0100 Subject: [PATCH] use androidx preferences, fix translation errors, prevent zip path traversal attack --- FileManager/build.gradle | 7 +- .../test/ActivityResultTestRule.java | 7 +- .../filemanager/test/BaseTestFileManager.java | 21 +- .../test/DirectoryScannerIdlingResource.java | 2 +- .../test/TestActivityTestRule.java | 8 +- .../test/TestFileManagerActivity.java | 48 ++--- .../TestFileManagerActivityWithIntents.java | 8 +- .../TestIntentFilterActivityForPickFile.java | 8 +- .../test/TestPickFilePathHistory.java | 17 +- .../filemanager/test/TestPickFileResult.java | 17 +- .../filemanager/test/TestSaveAsActivity.java | 21 +- .../test/TestViewFolderIntent.java | 14 +- FileManager/src/main/AndroidManifest.xml | 10 +- .../DistributionLibraryFragmentActivity.java | 54 ----- .../filemanager/FileManagerActivity.java | 39 ++-- .../filemanager/IntentFilterActivity.java | 25 +-- .../filemanager/PreferenceActivity.java | 187 ++++-------------- .../filemanager/PreferenceFragment.java | 175 ++++++++++++++++ .../filemanager/ThumbnailLoader.java | 12 +- .../bookmarks/BookmarkListActivity.java | 4 +- .../bookmarks/BookmarkListFragment.java | 8 +- .../BookmarkListActionHandler.java | 7 +- .../filemanager/files/DirectoryScanner.java | 12 +- .../filemanager/files/FileHolder.java | 3 +- .../filemanager/lists/FileListFragment.java | 20 +- .../lists/PickFileListFragment.java | 10 +- .../lists/SimpleFileListFragment.java | 24 +-- .../filemanager/search/SearchCore.java | 3 +- .../search/SearchSuggestionsProvider.java | 3 +- .../search/SearchableActivity.java | 6 +- .../filemanager/util/ExtractManager.java | 13 +- .../filemanager/util/MenuUtils.java | 17 +- .../filemanager/util/MimeTypes.java | 3 +- .../openintents/filemanager/util/UIUtils.java | 7 +- .../view/LegacyActionContainer.java | 4 +- .../filemanager/view/PathButtonLayout.java | 2 + .../openintents/filemanager/view/PickBar.java | 5 +- .../main/res/layout/activity_filemanager.xml | 32 +++ .../src/main/res/layout/dialog_details.xml | 1 - .../src/main/res/layout/dialog_text_input.xml | 3 +- FileManager/src/main/res/layout/filelist.xml | 1 + .../src/main/res/raw/recent_changes.txt | 11 ++ .../src/main/res/values-be/strings.xml | 7 +- .../src/main/res/values-bs/strings.xml | 5 +- .../src/main/res/values-hi/strings.xml | 4 +- .../src/main/res/values-iw/strings.xml | 7 +- .../src/main/res/values-ja/strings.xml | 6 +- .../src/main/res/values-ko/strings.xml | 14 +- .../src/main/res/values-lo/strings.xml | 14 +- .../src/main/res/values-lv/strings.xml | 5 +- .../src/main/res/values-pa/strings.xml | 4 +- .../src/main/res/values-pt-rBR/strings.xml | 2 +- .../src/main/res/values-pt/strings.xml | 2 +- .../src/main/res/values-sd/strings.xml | 4 +- .../src/main/res/values-sl/strings.xml | 7 +- .../src/main/res/values-uk/strings.xml | 7 +- .../src/main/res/values-v11/styles.xml | 6 - .../src/main/res/values-zh-rCN/strings.xml | 11 +- .../src/main/res/values-zh-rTW/strings.xml | 14 +- FileManager/src/main/res/values/themes.xml | 10 + FileManager/src/main/res/xml/file_paths.xml | 3 + FileManagerDemo/AndroidManifest.xml | 1 + FileManagerDemo/build.gradle | 3 +- .../openintents/filemanager/demo/Demo.java | 4 +- build.gradle | 9 +- 65 files changed, 534 insertions(+), 494 deletions(-) delete mode 100644 FileManager/src/main/java/org/openintents/filemanager/DistributionLibraryFragmentActivity.java create mode 100644 FileManager/src/main/java/org/openintents/filemanager/PreferenceFragment.java create mode 100644 FileManager/src/main/res/layout/activity_filemanager.xml delete mode 100644 FileManager/src/main/res/values-v11/styles.xml create mode 100644 FileManager/src/main/res/xml/file_paths.xml diff --git a/FileManager/build.gradle b/FileManager/build.gradle index a230f3d5..a93f9865 100644 --- a/FileManager/build.gradle +++ b/FileManager/build.gradle @@ -1,9 +1,13 @@ apply plugin: 'com.android.application' dependencies { - implementation 'com.github.openintents:distribution:3.0.2' + implementation 'com.github.openintents:distribution:3.2.0' implementation 'androidx.appcompat:appcompat:1.1.0' + implementation "androidx.preference:preference:1.1.0" + implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' + implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta3" + androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' @@ -15,7 +19,6 @@ dependencies { android { compileSdkVersion compile_sdk_version - buildToolsVersion build_tools_version defaultConfig { applicationId "org.openintents.filemanager" diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/ActivityResultTestRule.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/ActivityResultTestRule.java index e17c0439..a372b7fd 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/ActivityResultTestRule.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/ActivityResultTestRule.java @@ -1,21 +1,22 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.os.Build; + import androidx.annotation.NonNull; import androidx.test.rule.ActivityTestRule; import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; import org.hamcrest.TypeSafeMatcher; import java.lang.reflect.Field; import static android.app.Instrumentation.ActivityResult; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; public class ActivityResultTestRule extends ActivityTestRule { diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/BaseTestFileManager.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/BaseTestFileManager.java index bd5b1956..35ba499a 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/BaseTestFileManager.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/BaseTestFileManager.java @@ -1,13 +1,17 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; -import androidx.test.espresso.ViewAssertion; -import androidx.test.espresso.matcher.BoundedMatcher; import android.view.View; import android.widget.Adapter; import android.widget.AdapterView; +import androidx.test.espresso.Espresso; +import androidx.test.espresso.ViewAssertion; +import androidx.test.espresso.action.ViewActions; +import androidx.test.espresso.matcher.BoundedMatcher; + import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.Matchers; import org.hamcrest.TypeSafeMatcher; import org.openintents.filemanager.bookmarks.BookmarkListAdapter; import org.openintents.filemanager.files.FileHolder; @@ -16,14 +20,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; - -import static androidx.test.espresso.Espresso.onData; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.longClick; -import static androidx.test.espresso.action.ViewActions.pressBack; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; +import java.nio.charset.StandardCharsets; public class BaseTestFileManager { public static final String TEST_DIRECTORY = "oi-filemanager-tests"; @@ -49,7 +46,7 @@ protected static void cleanDirectory(File file) { protected static void createFile(String path, String content) throws IOException { File file = new File(path); - OutputStreamWriter wr = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); + OutputStreamWriter wr = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); wr.write(content); wr.close(); } diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/DirectoryScannerIdlingResource.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/DirectoryScannerIdlingResource.java index 680a0ceb..8e53c837 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/DirectoryScannerIdlingResource.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/DirectoryScannerIdlingResource.java @@ -1,4 +1,4 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import androidx.test.espresso.IdlingResource; diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestActivityTestRule.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestActivityTestRule.java index 57329b49..227035bf 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestActivityTestRule.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestActivityTestRule.java @@ -14,22 +14,22 @@ * limitations under the License. */ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.app.Activity; import android.app.Instrumentation; import android.content.Intent; +import android.util.Log; + import androidx.annotation.Nullable; import androidx.test.InstrumentationRegistry; import androidx.test.annotation.Beta; +import androidx.test.espresso.intent.Checks; import androidx.test.rule.UiThreadTestRule; -import android.util.Log; import org.junit.runner.Description; import org.junit.runners.model.Statement; -import static androidx.test.internal.util.Checks.checkNotNull; - /** * This rule provides functional testing of a single activity. The activity under test will be * launched before each test annotated with diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivity.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivity.java index f8ac180a..1a4e3985 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivity.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivity.java @@ -1,33 +1,38 @@ /* - * This is an example test project created in Eclipse to test NotePad which is a sample + * This is an example test project created in Eclipse to test NotePad which is a sample * project located in AndroidSDK/samples/android-11/NotePad * Just click on File --> New --> Project --> Android Project --> Create Project from existing source and * select NotePad. - * + * * Then you can run these test cases either on the emulator or on device. You right click * the test project and select Run As --> Run As Android JUnit Test - * + * * @author Renas Reda, renas.reda@jayway.com - * + * */ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.content.Context; import android.content.SharedPreferences; import android.os.Environment; import android.preference.PreferenceManager; -import androidx.test.InstrumentationRegistry; -import androidx.test.espresso.Espresso; -import androidx.test.rule.ActivityTestRule; -import androidx.test.runner.AndroidJUnit4; import android.text.format.Formatter; import android.view.KeyEvent; import android.view.View; import android.widget.ListView; +import androidx.test.InstrumentationRegistry; +import androidx.test.espresso.Espresso; +import androidx.test.espresso.action.ViewActions; +import androidx.test.espresso.assertion.ViewAssertions; +import androidx.test.espresso.matcher.ViewMatchers; +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.Matchers; import org.hamcrest.TypeSafeMatcher; import org.junit.After; import org.junit.Before; @@ -46,27 +51,8 @@ import java.io.IOException; import java.util.Random; -import static androidx.test.espresso.Espresso.onData; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; -import static androidx.test.espresso.Espresso.openContextualActionModeOverflowMenu; -import static androidx.test.espresso.Espresso.pressBack; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.longClick; -import static androidx.test.espresso.action.ViewActions.pressKey; -import static androidx.test.espresso.action.ViewActions.replaceText; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.assertThat; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; - @RunWith(AndroidJUnit4.class) -public class TestFileManagerActivity extends BaseTestFileManager { +public class TestFileManagerActivity extends org.openintents.filemanager.test.BaseTestFileManager { private static String filenameIsInRightDirectory; @Rule @@ -379,9 +365,9 @@ private void setAscending(boolean enabled) { @Test public void testBrowseToOnPressEnter() throws IOException { - /* + /* * We start at the SD card. - */ + */ Espresso.onView(ViewMatchers.withText(Environment.getExternalStorageDirectory().getParentFile().getName())).perform(ViewActions.longClick()); Espresso.onView(ViewMatchers.withId(R.id.path_bar_path_edit_text)).perform(ViewActions.click()); // Let the editText have focus to be able to send the enter key. Espresso.onView(ViewMatchers.withId(R.id.path_bar_path_edit_text)).perform(ViewActions.replaceText(sdcardPath + TEST_DIRECTORY)); diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivityWithIntents.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivityWithIntents.java index 5a2b7ca7..9ce269bb 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivityWithIntents.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestFileManagerActivityWithIntents.java @@ -1,8 +1,11 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.content.Intent; import android.net.Uri; import android.os.Environment; + +import androidx.test.espresso.assertion.ViewAssertions; +import androidx.test.espresso.matcher.ViewMatchers; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; @@ -14,9 +17,6 @@ import java.io.IOException; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; - @RunWith(AndroidJUnit4.class) public class TestFileManagerActivityWithIntents extends BaseTestFileManager { diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestIntentFilterActivityForPickFile.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestIntentFilterActivityForPickFile.java index e7e1a9ca..005fe71c 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestIntentFilterActivityForPickFile.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestIntentFilterActivityForPickFile.java @@ -1,8 +1,11 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.content.Intent; import android.net.Uri; import android.os.Environment; + +import androidx.test.espresso.assertion.ViewAssertions; +import androidx.test.espresso.matcher.ViewMatchers; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; @@ -15,9 +18,6 @@ import java.io.IOException; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; - @RunWith(AndroidJUnit4.class) public class TestIntentFilterActivityForPickFile extends BaseTestFileManager { diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFilePathHistory.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFilePathHistory.java index 530abbdf..b4db4c52 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFilePathHistory.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFilePathHistory.java @@ -1,17 +1,22 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.content.Intent; import android.net.Uri; import android.os.Environment; +import android.view.View; + import androidx.test.InstrumentationRegistry; import androidx.test.espresso.Espresso; +import androidx.test.espresso.action.ViewActions; +import androidx.test.espresso.assertion.ViewAssertions; import androidx.test.espresso.matcher.BoundedMatcher; +import androidx.test.espresso.matcher.ViewMatchers; import androidx.test.rule.UiThreadTestRule; import androidx.test.runner.AndroidJUnit4; -import android.view.View; import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -24,14 +29,6 @@ import java.io.File; import java.io.IOException; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.Matchers.endsWith; - @RunWith(AndroidJUnit4.class) public class TestPickFilePathHistory extends BaseTestFileManager { diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFileResult.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFileResult.java index 6dd175de..406e3bcb 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFileResult.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestPickFileResult.java @@ -1,11 +1,17 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Environment; + +import androidx.test.espresso.Espresso; +import androidx.test.espresso.action.ViewActions; +import androidx.test.espresso.intent.matcher.IntentMatchers; +import androidx.test.espresso.matcher.ViewMatchers; import androidx.test.runner.AndroidJUnit4; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -15,13 +21,8 @@ import java.io.IOException; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.intent.matcher.IntentMatchers.hasData; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.junit.Assert.assertThat; -import static androidTest.java.org.openintents.filemanager.test.ActivityResultTestRule.hasResultCode; -import static androidTest.java.org.openintents.filemanager.test.ActivityResultTestRule.hasResultData; +import static org.openintents.filemanager.test.ActivityResultTestRule.hasResultCode; +import static org.openintents.filemanager.test.ActivityResultTestRule.hasResultData; @RunWith(AndroidJUnit4.class) public class TestPickFileResult extends BaseTestFileManager { diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestSaveAsActivity.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestSaveAsActivity.java index f4204039..69ff4fb8 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestSaveAsActivity.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestSaveAsActivity.java @@ -1,19 +1,25 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; import android.os.Environment; import android.os.SystemClock; +import android.view.KeyEvent; +import android.view.View; + import androidx.test.InstrumentationRegistry; +import androidx.test.espresso.Espresso; import androidx.test.espresso.InjectEventSecurityException; import androidx.test.espresso.UiController; import androidx.test.espresso.ViewAction; +import androidx.test.espresso.action.ViewActions; +import androidx.test.espresso.matcher.ViewMatchers; import androidx.test.rule.ActivityTestRule; -import android.view.KeyEvent; -import android.view.View; import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -23,15 +29,6 @@ import java.io.File; import java.io.IOException; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.actionWithAssertions; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.replaceText; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withHint; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - public class TestSaveAsActivity extends BaseTestFileManager { @Rule diff --git a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestViewFolderIntent.java b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestViewFolderIntent.java index 9b129dd1..300f58b5 100644 --- a/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestViewFolderIntent.java +++ b/FileManager/src/androidTest/java/org/openintents/filemanager/test/TestViewFolderIntent.java @@ -1,13 +1,17 @@ -package androidTest.java.org.openintents.filemanager.test; +package org.openintents.filemanager.test; import android.content.Intent; import android.net.Uri; import android.os.Environment; import android.provider.DocumentsContract; -import androidx.test.espresso.intent.rule.IntentsTestRule; -import androidx.test.runner.AndroidJUnit4; import android.view.View; +import androidx.test.espresso.Espresso; +import androidx.test.espresso.assertion.ViewAssertions; +import androidx.test.espresso.intent.rule.IntentsTestRule; +import androidx.test.espresso.matcher.ViewMatchers; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; @@ -17,10 +21,6 @@ import org.openintents.filemanager.FileManagerActivity; import org.openintents.filemanager.view.PathBar; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.withId; - @RunWith(AndroidJUnit4.class) public class TestViewFolderIntent { diff --git a/FileManager/src/main/AndroidManifest.xml b/FileManager/src/main/AndroidManifest.xml index 9aabfaad..2db4803f 100644 --- a/FileManager/src/main/AndroidManifest.xml +++ b/FileManager/src/main/AndroidManifest.xml @@ -61,6 +61,7 @@ @@ -90,12 +92,12 @@ - + - + @@ -111,6 +113,7 @@ @@ -172,6 +175,9 @@ android:exported="true" android:grantUriPermissions="true" android:permission="android.permission.READ_EXTERNAL_STORAGE"> + diff --git a/FileManager/src/main/java/org/openintents/filemanager/DistributionLibraryFragmentActivity.java b/FileManager/src/main/java/org/openintents/filemanager/DistributionLibraryFragmentActivity.java deleted file mode 100644 index 7b9a1da5..00000000 --- a/FileManager/src/main/java/org/openintents/filemanager/DistributionLibraryFragmentActivity.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.openintents.filemanager; - -import android.app.Dialog; -import android.os.Bundle; -import androidx.fragment.app.FragmentActivity; -import android.view.Menu; -import android.view.MenuItem; - -import org.openintents.distribution.DistributionLibrary; - -public class DistributionLibraryFragmentActivity extends FragmentActivity { - - static final int MENU_DISTRIBUTION_START = Menu.FIRST; - - static final int DIALOG_DISTRIBUTION_START = 1; - - protected DistributionLibrary mDistribution; - - /** - * Called when the activity is first created. - */ - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mDistribution = new DistributionLibrary(this, MENU_DISTRIBUTION_START, DIALOG_DISTRIBUTION_START); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - mDistribution.onCreateOptionsMenu(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (mDistribution.onOptionsItemSelected(item)) { - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - protected Dialog onCreateDialog(int id) { - return mDistribution.onCreateDialog(id); - } - - @Override - protected void onPrepareDialog(int id, Dialog dialog) { - super.onPrepareDialog(id, dialog); - mDistribution.onPrepareDialog(id, dialog); - } -} diff --git a/FileManager/src/main/java/org/openintents/filemanager/FileManagerActivity.java b/FileManager/src/main/java/org/openintents/filemanager/FileManagerActivity.java index 4ba7187a..b61efc38 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/FileManagerActivity.java +++ b/FileManager/src/main/java/org/openintents/filemanager/FileManagerActivity.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2008 OpenIntents.org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,28 +20,30 @@ import android.content.ComponentName; import android.content.Intent; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.os.Environment; -import androidx.annotation.VisibleForTesting; +import android.preference.PreferenceManager; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.Toast; +import androidx.annotation.VisibleForTesting; +import androidx.appcompat.widget.Toolbar; + +import org.openintents.distribution.DistributionLibrary; +import org.openintents.distribution.DistributionLibraryActivity; import org.openintents.filemanager.bookmarks.BookmarkListActivity; -import org.openintents.filemanager.compatibility.HomeIconHelper; import org.openintents.filemanager.files.FileHolder; import org.openintents.filemanager.lists.SimpleFileListFragment; import org.openintents.filemanager.util.FileUtils; -import org.openintents.filemanager.util.UIUtils; import org.openintents.intents.FileManagerIntents; import org.openintents.util.MenuIntentOptionsWithIcons; import java.io.File; -public class FileManagerActivity extends DistributionLibraryFragmentActivity { +public class FileManagerActivity extends DistributionLibraryActivity { @VisibleForTesting public static final String FRAGMENT_TAG = "ListFragment"; @@ -80,12 +82,18 @@ private File resolveIntentData() { */ @Override public void onCreate(Bundle icicle) { - UIUtils.setThemeFor(this); - super.onCreate(icicle); + // update theme from preferences + if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("usedarktheme", true)) { + this.setTheme(R.style.Theme_Dark_NoActionBar); + } else { + this.setTheme(R.style.Theme_Light_DarkTitle_NoActionBar); + } + + setContentView(R.layout.activity_filemanager); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); - mDistribution.setFirst(MENU_DISTRIBUTION_START, - DIALOG_DISTRIBUTION_START); // Check whether EULA has been accepted // or information about new version can be presented. @@ -93,9 +101,8 @@ public void onCreate(Bundle icicle) { return; } - // Enable home button. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) - HomeIconHelper.activity_actionbar_setHomeButtonEnabled(this); + getSupportActionBar().setHomeButtonEnabled(true); + // Search when the user types. setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); @@ -126,7 +133,7 @@ public void onCreate(Bundle icicle) { } } mFragment.setArguments(args); - getSupportFragmentManager().beginTransaction().add(android.R.id.content, mFragment, FRAGMENT_TAG).commit(); + getSupportFragmentManager().beginTransaction().add(R.id.container_file_list, mFragment, FRAGMENT_TAG).commit(); } else { // If we didn't rotate and data wasn't null. if (icicle == null && data != null) @@ -144,10 +151,12 @@ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = new MenuInflater(this); inflater.inflate(R.menu.main, menu); + mDistribution.onCreateOptionsMenu(menu); + if (FileManagerApplication.hideDonateMenu(this)) { menu.findItem(R.id.menu_donate).setVisible(false); + menu.getItem(DistributionLibrary.OFFSET_SUPPORT).setVisible(false); } - mDistribution.onCreateOptionsMenu(menu); return true; } diff --git a/FileManager/src/main/java/org/openintents/filemanager/IntentFilterActivity.java b/FileManager/src/main/java/org/openintents/filemanager/IntentFilterActivity.java index 7387d2b4..74bb5fca 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/IntentFilterActivity.java +++ b/FileManager/src/main/java/org/openintents/filemanager/IntentFilterActivity.java @@ -1,13 +1,12 @@ package org.openintents.filemanager; import android.content.Intent; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; -import androidx.fragment.app.FragmentActivity; import android.view.KeyEvent; +import androidx.fragment.app.FragmentActivity; + import org.openintents.filemanager.lists.FileListFragment; import org.openintents.filemanager.lists.MultiselectListFragment; import org.openintents.filemanager.lists.PickFileListFragment; @@ -36,12 +35,12 @@ protected void onCreate(Bundle savedInstance) { if (!extras.containsKey(FileManagerIntents.EXTRA_DIR_PATH)) { // Set a default path so that we launch a proper list. File defaultFile = new File( - PreferenceActivity.getDefaultPickFilePath(this)); + PreferenceFragment.getDefaultPickFilePath(this)); if (!defaultFile.exists()) { - PreferenceActivity.setDefaultPickFilePath(this, Environment + PreferenceFragment.setDefaultPickFilePath(this, Environment .getExternalStorageDirectory().getAbsolutePath()); defaultFile = new File( - PreferenceActivity.getDefaultPickFilePath(this)); + PreferenceFragment.getDefaultPickFilePath(this)); } extras.putString(FileManagerIntents.EXTRA_DIR_PATH, defaultFile.getAbsolutePath()); @@ -132,7 +131,7 @@ else if (FileManagerIntents.ACTION_PICK_DIRECTORY.equals(intent.getAction()) @Override public boolean onKeyUp(int keyCode, KeyEvent event) { // Only check fragment back-ability if we're on the filepicker fragment. - if (mFragment instanceof PickFileListFragment && VERSION.SDK_INT > VERSION_CODES.DONUT) { + if (mFragment instanceof PickFileListFragment) { if (keyCode == KeyEvent.KEYCODE_BACK && ((PickFileListFragment) mFragment).pressBack()) return true; @@ -140,16 +139,4 @@ public boolean onKeyUp(int keyCode, KeyEvent event) { return super.onKeyUp(keyCode, event); } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - // Only check fragment back-ability if we're on the filepicker fragment. - if (mFragment instanceof PickFileListFragment && VERSION.SDK_INT <= VERSION_CODES.DONUT) { - if (keyCode == KeyEvent.KEYCODE_BACK - && ((PickFileListFragment) mFragment).pressBack()) - return true; - } - - return super.onKeyDown(keyCode, event); - } } diff --git a/FileManager/src/main/java/org/openintents/filemanager/PreferenceActivity.java b/FileManager/src/main/java/org/openintents/filemanager/PreferenceActivity.java index 9828b060..1614438e 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/PreferenceActivity.java +++ b/FileManager/src/main/java/org/openintents/filemanager/PreferenceActivity.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2008 OpenIntents.org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,169 +16,50 @@ package org.openintents.filemanager; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.os.Build; +import android.content.Intent; import android.os.Bundle; -import android.os.Environment; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceManager; -import androidx.annotation.VisibleForTesting; import android.view.MenuItem; -import android.widget.Toast; -import org.openintents.filemanager.compatibility.HomeIconHelper; -import org.openintents.filemanager.search.SearchableActivity; -import org.openintents.filemanager.util.UIUtils; - -public class PreferenceActivity extends android.preference.PreferenceActivity - implements OnSharedPreferenceChangeListener { - - public static final String PREFS_MEDIASCAN = "mediascan"; - /** - * @since 2011-09-30 - */ - public static final String PREFS_SHOWALLWARNING = "showallwarning"; - - - public static final String PREFS_DISPLAYHIDDENFILES = "displayhiddenfiles"; - - public static final String PREFS_SORTBY = "sortby"; - - public static final String PREFS_ASCENDING = "ascending"; - - public static final String PREFS_DEFAULTPICKFILEPATH = "defaultpickfilepath"; - public static final String PREFS_USEBESTMATCH = "usebestmatch"; - - public static boolean getMediaScanFromPreference(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(PREFS_MEDIASCAN, false); - } - - /** - * @since 2011-09-30 - */ - public static void setShowAllWarning(Context context, boolean enabled) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean(PREFS_SHOWALLWARNING, enabled); - editor.commit(); - } - - /** - * @since 2011-09-30 - */ - public static boolean getShowAllWarning(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(PREFS_SHOWALLWARNING, true); - } - - @VisibleForTesting - public static void setDisplayHiddenFiles(Context context, boolean enabled) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean(PREFS_DISPLAYHIDDENFILES, enabled); - editor.commit(); - } - - public static boolean getDisplayHiddenFiles(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(PREFS_DISPLAYHIDDENFILES, true); - } - - public static void setDefaultPickFilePath(Context context, String path) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); - SharedPreferences.Editor editor = settings.edit(); - editor.putString(PREFS_DEFAULTPICKFILEPATH, path); - editor.commit(); - } - - static String getDefaultPickFilePath(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getString(PREFS_DEFAULTPICKFILEPATH, Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ? Environment.getExternalStorageDirectory().getAbsolutePath() : "/"); - } - - public static int getSortBy(Context context) { - /* entryValues must be a string-array while we need integers */ - return Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context) - .getString(PREFS_SORTBY, "1")); - } - - public static boolean getAscending(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(PREFS_ASCENDING, true); - } +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.NavUtils; +import androidx.core.app.TaskStackBuilder; +public class PreferenceActivity extends AppCompatActivity { @Override - protected void onCreate(Bundle icicle) { - UIUtils.setThemeFor(this); - - super.onCreate(icicle); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - HomeIconHelper.activity_actionbar_setDisplayHomeAsUpEnabled(this); - } - - UIUtils.setThemeFor(this); - - addPreferencesFromResource(R.xml.preferences); - - /* Register the onSharedPreferenceChanged listener to update the SortBy ListPreference summary */ - getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); - /* Set the onSharedPreferenceChanged listener summary to its initial value */ - changeListPreferenceSummaryToCurrentValue((ListPreference) findPreference("sortby")); - - // Initialize search history reset confirmation dialog. - findPreference("clear_search_button").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - new AlertDialog.Builder(PreferenceActivity.this) - .setTitle(R.string.preference_search_title) - .setMessage(R.string.preference_search_dialog_message) - .setIcon(android.R.drawable.ic_dialog_alert) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - SearchableActivity.clearSearchRecents(PreferenceActivity.this); - Toast.makeText(PreferenceActivity.this, R.string.search_history_cleared, Toast.LENGTH_SHORT).show(); - } - }) - .setNegativeButton(android.R.string.cancel, null).show(); - - return true; - } - }); - - findPreference("usedarktheme").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - //TODO show dialog about restarting app - return true; - } - }); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getSupportActionBar().setHomeButtonEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportFragmentManager() + .beginTransaction() + .replace(android.R.id.content, new PreferenceFragment()) + .commit(); } + @Nullable @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - HomeIconHelper.showHome(this); - break; - } - return super.onOptionsItemSelected(item); + public Intent getParentActivityIntent() { + return new Intent(this, FileManagerActivity.class); } @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (key.equals("sortby")) { - changeListPreferenceSummaryToCurrentValue((ListPreference) findPreference(key)); - } - } + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + Intent upIntent = NavUtils.getParentActivityIntent(this); + if (NavUtils.shouldUpRecreateTask(this, upIntent)) { + // create new task + TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent) + .startActivities(); + } else { + // Stay in same task + NavUtils.navigateUpTo(this, upIntent); + } + return true; - private void changeListPreferenceSummaryToCurrentValue(ListPreference listPref) { - listPref.setSummary(listPref.getEntry()); + } else { + return super.onOptionsItemSelected(item); + } } } diff --git a/FileManager/src/main/java/org/openintents/filemanager/PreferenceFragment.java b/FileManager/src/main/java/org/openintents/filemanager/PreferenceFragment.java new file mode 100644 index 00000000..98f7acda --- /dev/null +++ b/FileManager/src/main/java/org/openintents/filemanager/PreferenceFragment.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2008 OpenIntents.org + * + * 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 org.openintents.filemanager; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.os.Environment; +import android.view.MenuItem; +import android.widget.Toast; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; + +import org.openintents.filemanager.compatibility.HomeIconHelper; +import org.openintents.filemanager.search.SearchableActivity; + +public class PreferenceFragment extends PreferenceFragmentCompat + implements OnSharedPreferenceChangeListener { + + public static final String PREFS_MEDIASCAN = "mediascan"; + /** + * @since 2011-09-30 + */ + public static final String PREFS_SHOWALLWARNING = "showallwarning"; + + + public static final String PREFS_DISPLAYHIDDENFILES = "displayhiddenfiles"; + + public static final String PREFS_SORTBY = "sortby"; + + public static final String PREFS_ASCENDING = "ascending"; + + public static final String PREFS_DEFAULTPICKFILEPATH = "defaultpickfilepath"; + public static final String PREFS_USEBESTMATCH = "usebestmatch"; + + public static boolean getMediaScanFromPreference(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(PREFS_MEDIASCAN, false); + } + + /** + * @since 2011-09-30 + */ + public static void setShowAllWarning(Context context, boolean enabled) { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = settings.edit(); + editor.putBoolean(PREFS_SHOWALLWARNING, enabled); + editor.apply(); + } + + /** + * @since 2011-09-30 + */ + public static boolean getShowAllWarning(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(PREFS_SHOWALLWARNING, true); + } + + @VisibleForTesting + public static void setDisplayHiddenFiles(Context context, boolean enabled) { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = settings.edit(); + editor.putBoolean(PREFS_DISPLAYHIDDENFILES, enabled); + editor.apply(); + } + + public static boolean getDisplayHiddenFiles(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(PREFS_DISPLAYHIDDENFILES, true); + } + + public static void setDefaultPickFilePath(Context context, String path) { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = settings.edit(); + editor.putString(PREFS_DEFAULTPICKFILEPATH, path); + editor.apply(); + } + + static String getDefaultPickFilePath(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getString(PREFS_DEFAULTPICKFILEPATH, Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ? Environment.getExternalStorageDirectory().getAbsolutePath() : "/"); + } + + public static int getSortBy(Context context) { + /* entryValues must be a string-array while we need integers */ + return Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context) + .getString(PREFS_SORTBY, "1")); + } + + public static boolean getAscending(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(PREFS_ASCENDING, true); + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.preferences, rootKey); + + /* Register the onSharedPreferenceChanged listener to update the SortBy ListPreference summary */ + getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + /* Set the onSharedPreferenceChanged listener summary to its initial value */ + changeListPreferenceSummaryToCurrentValue((ListPreference) findPreference("sortby")); + + // Initialize search history reset confirmation dialog. + findPreference("clear_search_button").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + new AlertDialog.Builder(PreferenceFragment.this.getContext()) + .setTitle(R.string.preference_search_title) + .setMessage(R.string.preference_search_dialog_message) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + SearchableActivity.clearSearchRecents(PreferenceFragment.this.getContext()); + Toast.makeText(PreferenceFragment.this.getContext(), R.string.search_history_cleared, Toast.LENGTH_SHORT).show(); + } + }) + .setNegativeButton(android.R.string.cancel, null).show(); + + return true; + } + }); + + findPreference("usedarktheme").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + //TODO show dialog about restarting app + return true; + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + HomeIconHelper.showHome(this.getActivity()); + break; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals("sortby")) { + changeListPreferenceSummaryToCurrentValue((ListPreference) findPreference(key)); + } + } + + private void changeListPreferenceSummaryToCurrentValue(ListPreference listPref) { + listPref.setSummary(listPref.getEntry()); + } +} diff --git a/FileManager/src/main/java/org/openintents/filemanager/ThumbnailLoader.java b/FileManager/src/main/java/org/openintents/filemanager/ThumbnailLoader.java index b2c8127d..8b010f36 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/ThumbnailLoader.java +++ b/FileManager/src/main/java/org/openintents/filemanager/ThumbnailLoader.java @@ -14,13 +14,13 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Build; import android.os.Handler; -import android.preference.PreferenceManager; import android.util.Log; import android.util.TypedValue; import android.widget.ImageView; +import androidx.preference.PreferenceManager; + import org.openintents.filemanager.files.FileHolder; import org.openintents.filemanager.util.FileUtils; import org.openintents.filemanager.util.ImageUtils; @@ -102,7 +102,7 @@ protected boolean removeEldestEntry(LinkedHashMap.Entry eldest) } }; - mUseBestMatch = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PreferenceActivity.PREFS_USEBESTMATCH, true); + mUseBestMatch = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PreferenceFragment.PREFS_USEBESTMATCH, true); } public static void setThumbnailHeight(int height) { @@ -315,10 +315,8 @@ private Drawable getDrawableForMimetype(FileHolder holder, Context context) { // Bug in SDK versions >= 8. See here: // http://code.google.com/p/android/issues/detail?id=9151 - if (Build.VERSION.SDK_INT >= 8) { - aInfo.sourceDir = path; - aInfo.publicSourceDir = path; - } + aInfo.sourceDir = path; + aInfo.publicSourceDir = path; return aInfo.loadIcon(pm); } diff --git a/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListActivity.java b/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListActivity.java index a0c00e79..daf46eaa 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListActivity.java +++ b/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListActivity.java @@ -18,9 +18,7 @@ protected void onCreate(Bundle savedInstanceState) { UIUtils.setThemeFor(this); super.onCreate(savedInstanceState); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { - HomeIconHelper.activity_actionbar_setDisplayHomeAsUpEnabled(this); - } + HomeIconHelper.activity_actionbar_setDisplayHomeAsUpEnabled(this); if (getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG) == null) { getSupportFragmentManager().beginTransaction() diff --git a/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListFragment.java b/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListFragment.java index 460c3d20..030d42aa 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListFragment.java +++ b/FileManager/src/main/java/org/openintents/filemanager/bookmarks/BookmarkListFragment.java @@ -53,12 +53,8 @@ public void onScroll(AbsListView view, int firstVisibleItem, setEmptyText(getString(R.string.bookmark_empty)); // Handle item selection. - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - registerForContextMenu(getListView()); - } else { - getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); - BookmarkMultiChoiceModeHelper.listView_setMultiChoiceModeListener(getListView(), getActivity()); - } + getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); + BookmarkMultiChoiceModeHelper.listView_setMultiChoiceModeListener(getListView(), getActivity()); } @Override diff --git a/FileManager/src/main/java/org/openintents/filemanager/compatibility/BookmarkListActionHandler.java b/FileManager/src/main/java/org/openintents/filemanager/compatibility/BookmarkListActionHandler.java index 36f9c52c..90210b9c 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/compatibility/BookmarkListActionHandler.java +++ b/FileManager/src/main/java/org/openintents/filemanager/compatibility/BookmarkListActionHandler.java @@ -19,20 +19,17 @@ private BookmarkListActionHandler() { * * @param item The MenuItem selected. * @param list The list to act upon. - * @param pos The selected item's position. */ public static void handleItemSelection(MenuItem item, ListView list) { // Single selection - if (VERSION.SDK_INT < VERSION_CODES.HONEYCOMB - || ListViewMethodHelper.listView_getCheckedItemCount(list) == 1) { + if (ListViewMethodHelper.listView_getCheckedItemCount(list) == 1) { // Get id of selected bookmark. long id = -1; if (item.getMenuInfo() instanceof AdapterContextMenuInfo) id = list.getAdapter().getItemId(((AdapterContextMenuInfo) item.getMenuInfo()).position); - if (VERSION.SDK_INT > VERSION_CODES.HONEYCOMB) - id = ListViewMethodHelper.listView_getCheckedItemIds(list)[0]; + id = ListViewMethodHelper.listView_getCheckedItemIds(list)[0]; // Handle selection switch (item.getItemId()) { diff --git a/FileManager/src/main/java/org/openintents/filemanager/files/DirectoryScanner.java b/FileManager/src/main/java/org/openintents/filemanager/files/DirectoryScanner.java index d01810ee..b5b42652 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/files/DirectoryScanner.java +++ b/FileManager/src/main/java/org/openintents/filemanager/files/DirectoryScanner.java @@ -9,6 +9,7 @@ import android.util.Log; import org.openintents.filemanager.PreferenceActivity; +import org.openintents.filemanager.PreferenceFragment; import org.openintents.filemanager.R; import org.openintents.filemanager.util.FileUtils; import org.openintents.filemanager.util.MimeTypes; @@ -18,6 +19,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; public class DirectoryScanner extends Thread { /** @@ -77,7 +79,7 @@ private void init() { progress = 0; files = currentDirectory.listFiles(); noMedia = false; - displayHidden = PreferenceActivity.getDisplayHiddenFiles(context); + displayHidden = PreferenceFragment.getDisplayHiddenFiles(context); sdIcon = context.getResources().getDrawable(R.drawable.ic_launcher_sdcard); folderIcon = context.getResources().getDrawable(R.drawable.ic_launcher_folder); genericFileIcon = context.getResources().getDrawable(R.drawable.ic_launcher_file); @@ -168,8 +170,8 @@ public void run() { } Log.v(TAG, "Sorting results..."); - int sortBy = PreferenceActivity.getSortBy(context); - boolean ascending = PreferenceActivity.getAscending(context); + int sortBy = PreferenceFragment.getSortBy(context); + boolean ascending = PreferenceFragment.getAscending(context); // Sort lists if (!cancelled) { @@ -293,13 +295,15 @@ public int compare(FileHolder f1, FileHolder f2) { } class NameComparator extends FileHolderComparator { + Locale locale = Locale.getDefault(); + public NameComparator(boolean asc) { super(asc); } @Override protected int comp(FileHolder f1, FileHolder f2) { - return f1.getName().toLowerCase().compareTo(f2.getName().toLowerCase()); + return f1.getName().toLowerCase(locale).compareTo(f2.getName().toLowerCase(locale)); } } diff --git a/FileManager/src/main/java/org/openintents/filemanager/files/FileHolder.java b/FileManager/src/main/java/org/openintents/filemanager/files/FileHolder.java index ac35ec8e..9a12e843 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/files/FileHolder.java +++ b/FileManager/src/main/java/org/openintents/filemanager/files/FileHolder.java @@ -12,6 +12,7 @@ import java.io.File; import java.text.DateFormat; import java.util.Date; +import java.util.Locale; public class FileHolder implements Parcelable, Comparable { public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -148,7 +149,7 @@ public int compareTo(FileHolder another) { * Parse the extension from the filename of the mFile member. */ private String parseExtension() { - return FileUtils.getExtension(mFile.getName()).toLowerCase(); + return FileUtils.getExtension(mFile.getName()).toLowerCase(Locale.ROOT); } @Override diff --git a/FileManager/src/main/java/org/openintents/filemanager/lists/FileListFragment.java b/FileManager/src/main/java/org/openintents/filemanager/lists/FileListFragment.java index e435a039..3dab6228 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/lists/FileListFragment.java +++ b/FileManager/src/main/java/org/openintents/filemanager/lists/FileListFragment.java @@ -1,5 +1,6 @@ package org.openintents.filemanager.lists; +import android.app.Activity; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle; @@ -15,6 +16,11 @@ import android.widget.Toast; import android.widget.ViewFlipper; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.fragment.app.ListFragment; +import androidx.test.espresso.IdlingResource; + import org.openintents.filemanager.FileHolderListAdapter; import org.openintents.filemanager.FileManagerApplication; import org.openintents.filemanager.R; @@ -28,11 +34,6 @@ import java.io.File; import java.util.ArrayList; -import androidx.annotation.LayoutRes; -import androidx.annotation.NonNull; -import androidx.fragment.app.ListFragment; -import androidx.test.espresso.IdlingResource; - import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static androidx.core.content.ContextCompat.checkSelfPermission; @@ -128,10 +129,10 @@ public void onScroll(AbsListView view, int firstVisibleItem, getListView().requestFocusFromTouch(); // Init flipper - mFlipper = (ViewFlipper) view.findViewById(R.id.flipper); + mFlipper = view.findViewById(R.id.flipper); mClipboardInfo = view.findViewById(R.id.clipboard_info); - mClipboardContent = (TextView) view.findViewById(R.id.clipboard_content); - mClipboardAction = (TextView) view.findViewById(R.id.clipboard_action); + mClipboardContent = view.findViewById(R.id.clipboard_content); + mClipboardAction = view.findViewById(R.id.clipboard_action); mClipboardAction.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -219,7 +220,8 @@ public void refresh() { } private boolean hasPermissions() { - return getActivity() != null && checkSelfPermission(getActivity(), WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED; + Activity activity = getActivity(); + return activity != null && checkSelfPermission(activity, WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED; } private void requestPermissions() { diff --git a/FileManager/src/main/java/org/openintents/filemanager/lists/PickFileListFragment.java b/FileManager/src/main/java/org/openintents/filemanager/lists/PickFileListFragment.java index 20925ac0..76e23312 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/lists/PickFileListFragment.java +++ b/FileManager/src/main/java/org/openintents/filemanager/lists/PickFileListFragment.java @@ -13,7 +13,7 @@ import android.widget.ViewFlipper; import org.openintents.filemanager.FileManagerProvider; -import org.openintents.filemanager.PreferenceActivity; +import org.openintents.filemanager.PreferenceFragment; import org.openintents.filemanager.R; import org.openintents.filemanager.files.FileHolder; import org.openintents.filemanager.view.PickBar; @@ -41,13 +41,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - ViewFlipper modeSelector = (ViewFlipper) view.findViewById(R.id.modeSelector); + ViewFlipper modeSelector = view.findViewById(R.id.modeSelector); // Folder init if (getArguments().getBoolean(FileManagerIntents.EXTRA_DIRECTORIES_ONLY)) { modeSelector.setDisplayedChild(0); - Button button = (Button) view.findViewById(R.id.button); + Button button = view.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -62,7 +62,7 @@ public void onClick(View v) { else { modeSelector.setDisplayedChild(1); - mPickBar = (PickBar) view.findViewById(R.id.pickBar); + mPickBar = view.findViewById(R.id.pickBar); mPickBar.setButtonText(getArguments().getString(FileManagerIntents.EXTRA_BUTTON_TEXT)); mPickBar.setText(getFilename()); @@ -105,7 +105,7 @@ private void pickFileOrFolder(File selection, boolean getContentInitiated) { Intent intent = new Intent(); intent.putExtras(getArguments()); - PreferenceActivity.setDefaultPickFilePath(getActivity(), selection.getParent() != null ? selection.getParent() : "/"); + PreferenceFragment.setDefaultPickFilePath(getActivity(), selection.getParent() != null ? selection.getParent() : "/"); if (getContentInitiated) intent.setData(Uri.parse(FileManagerProvider.FILE_PROVIDER_PREFIX + selection)); diff --git a/FileManager/src/main/java/org/openintents/filemanager/lists/SimpleFileListFragment.java b/FileManager/src/main/java/org/openintents/filemanager/lists/SimpleFileListFragment.java index 04536031..b0f5172f 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/lists/SimpleFileListFragment.java +++ b/FileManager/src/main/java/org/openintents/filemanager/lists/SimpleFileListFragment.java @@ -2,8 +2,6 @@ import android.content.Context; import android.content.Intent; -import android.os.Build; -import android.os.Build.VERSION; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -20,7 +18,7 @@ import android.widget.Toast; import org.openintents.filemanager.FileManagerApplication; -import org.openintents.filemanager.PreferenceActivity; +import org.openintents.filemanager.PreferenceFragment; import org.openintents.filemanager.R; import org.openintents.filemanager.compatibility.FileMultiChoiceModeHelper; import org.openintents.filemanager.dialogs.CreateDirectoryDialog; @@ -61,8 +59,8 @@ public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // Pathbar init. - mPathBar = (PathBar) view.findViewById(R.id.pathbar); - mMessageView = (TextView) view.findViewById(R.id.message); + mPathBar = view.findViewById(R.id.pathbar); + mMessageView = view.findViewById(R.id.message); mMessageView.setText(getString(R.string.error_generic) + "no access"); // Handle mPath differently if we restore state or just initially create the view. if (savedInstanceState == null) @@ -92,15 +90,11 @@ public void directoryChanged(File newCurrentDir) { */ void initContextualActions() { if (mActionsEnabled) { - if (VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - registerForContextMenu(getListView()); - } else { - FileMultiChoiceModeHelper multiChoiceModeHelper = new FileMultiChoiceModeHelper(mSingleSelectionMenu, mMultiSelectionMenu); - multiChoiceModeHelper.setListView(getListView()); - multiChoiceModeHelper.setPathBar(mPathBar); - multiChoiceModeHelper.setContext(this); - getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); - } + FileMultiChoiceModeHelper multiChoiceModeHelper = new FileMultiChoiceModeHelper(mSingleSelectionMenu, mMultiSelectionMenu); + multiChoiceModeHelper.setListView(getListView()); + multiChoiceModeHelper.setPathBar(mPathBar); + multiChoiceModeHelper.setContext(this); + getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); setHasOptionsMenu(true); } } @@ -200,7 +194,7 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { @Override public void onPrepareOptionsMenu(Menu menu) { // We only know about ".nomedia" once scanning is finished. - boolean showMediaScanMenuItem = PreferenceActivity.getMediaScanFromPreference(getActivity()); + boolean showMediaScanMenuItem = PreferenceFragment.getMediaScanFromPreference(getActivity()); if (!mScanner.isRunning() && showMediaScanMenuItem) { menu.findItem(R.id.menu_media_scan_include).setVisible(mScanner.getNoMedia()); menu.findItem(R.id.menu_media_scan_exclude).setVisible(!mScanner.getNoMedia()); diff --git a/FileManager/src/main/java/org/openintents/filemanager/search/SearchCore.java b/FileManager/src/main/java/org/openintents/filemanager/search/SearchCore.java index 6f8d841b..c6d660a5 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/search/SearchCore.java +++ b/FileManager/src/main/java/org/openintents/filemanager/search/SearchCore.java @@ -10,6 +10,7 @@ import java.io.File; import java.io.FilenameFilter; +import java.util.Locale; /** * Provides the search core, used by every search subsystem that provides results. @@ -33,7 +34,7 @@ public class SearchCore { private FilenameFilter filter = new FilenameFilter() { @Override public boolean accept(File dir, String filename) { - return mQuery == null ? false : filename.toLowerCase().contains(mQuery.toLowerCase()); + return mQuery != null && filename.toLowerCase(Locale.getDefault()).contains(mQuery.toLowerCase(Locale.getDefault())); } }; diff --git a/FileManager/src/main/java/org/openintents/filemanager/search/SearchSuggestionsProvider.java b/FileManager/src/main/java/org/openintents/filemanager/search/SearchSuggestionsProvider.java index 2cf4d3aa..64efe489 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/search/SearchSuggestionsProvider.java +++ b/FileManager/src/main/java/org/openintents/filemanager/search/SearchSuggestionsProvider.java @@ -11,6 +11,7 @@ import android.provider.BaseColumns; import java.util.ArrayList; +import java.util.Locale; import androidx.annotation.NonNull; @@ -74,7 +75,7 @@ public boolean onCreate() { */ public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - searcher.setQuery(uri.getLastPathSegment().toLowerCase()); + searcher.setQuery(uri.getLastPathSegment().toLowerCase(Locale.ROOT)); searcher.dropPreviousResults(); diff --git a/FileManager/src/main/java/org/openintents/filemanager/search/SearchableActivity.java b/FileManager/src/main/java/org/openintents/filemanager/search/SearchableActivity.java index 4d3fc72d..69c6a066 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/search/SearchableActivity.java +++ b/FileManager/src/main/java/org/openintents/filemanager/search/SearchableActivity.java @@ -12,12 +12,12 @@ import android.os.Build; import android.os.Bundle; import android.provider.SearchRecentSuggestions; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.widget.ListView; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.openintents.filemanager.FileManagerActivity; import org.openintents.filemanager.R; import org.openintents.filemanager.compatibility.HomeIconHelper; @@ -51,9 +51,7 @@ protected void onCreate(Bundle savedInstanceState) { // Presentation settings requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); super.onCreate(savedInstanceState); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - HomeIconHelper.activity_actionbar_setDisplayHomeAsUpEnabled(this); - } + HomeIconHelper.activity_actionbar_setDisplayHomeAsUpEnabled(this); lbm = LocalBroadcastManager.getInstance(getApplicationContext()); diff --git a/FileManager/src/main/java/org/openintents/filemanager/util/ExtractManager.java b/FileManager/src/main/java/org/openintents/filemanager/util/ExtractManager.java index e0899567..e0d0fb1b 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/util/ExtractManager.java +++ b/FileManager/src/main/java/org/openintents/filemanager/util/ExtractManager.java @@ -42,7 +42,7 @@ public ExtractManager setOnExtractFinishedListener(OnExtractFinishedListener lis } public interface OnExtractFinishedListener { - public abstract void extractFinished(); + void extractFinished(); } private class ExtractTask extends AsyncTask { @@ -101,8 +101,15 @@ private void unzipEntry(ZipFile zipfile, ZipEntry entry, return; } File outputFile = new File(outputDir, entry.getName()); - if (!outputFile.getParentFile().exists()) { - createDir(outputFile.getParentFile()); + + String canonicalPath = outputFile.getCanonicalPath(); + if (!canonicalPath.startsWith(outputDir)) { + throw new IOException("Zip Path Traversal Attack detected for " + canonicalPath); + } + + File parentFile = outputFile.getParentFile(); + if (parentFile != null && !parentFile.exists()) { + createDir(parentFile); } BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry)); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); diff --git a/FileManager/src/main/java/org/openintents/filemanager/util/MenuUtils.java b/FileManager/src/main/java/org/openintents/filemanager/util/MenuUtils.java index 921ee018..d39a35be 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/util/MenuUtils.java +++ b/FileManager/src/main/java/org/openintents/filemanager/util/MenuUtils.java @@ -15,7 +15,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; -import androidx.fragment.app.DialogFragment; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; @@ -25,10 +24,12 @@ import android.widget.CheckBox; import android.widget.Toast; +import androidx.fragment.app.DialogFragment; + import org.openintents.filemanager.FileManagerActivity; import org.openintents.filemanager.FileManagerApplication; import org.openintents.filemanager.FileManagerProvider; -import org.openintents.filemanager.PreferenceActivity; +import org.openintents.filemanager.PreferenceFragment; import org.openintents.filemanager.R; import org.openintents.filemanager.bookmarks.BookmarksProvider; import org.openintents.filemanager.dialogs.DetailsDialog; @@ -281,7 +282,7 @@ public void extractFinished() { return true; case R.id.menu_more: - if (!PreferenceActivity.getShowAllWarning(context)) { + if (!PreferenceFragment.getShowAllWarning(context)) { showMoreCommandsDialog(fItem, context); return true; } @@ -350,9 +351,9 @@ private static void sendFile(FileHolder fHolder, Context context) { private static void showWarningDialog(final FileHolder holder, final Context context) { LayoutInflater li = LayoutInflater.from(context); View warningView = li.inflate(R.layout.dialog_warning, null); - final CheckBox showWarningAgain = (CheckBox) warningView.findViewById(R.id.showagaincheckbox); + final CheckBox showWarningAgain = warningView.findViewById(R.id.showagaincheckbox); - showWarningAgain.setChecked(PreferenceActivity.getShowAllWarning(context)); + showWarningAgain.setChecked(PreferenceFragment.getShowAllWarning(context)); new AlertDialog.Builder(context).setView(warningView).setTitle(context.getString(R.string.title_warning_some_may_not_work)) .setMessage(context.getString(R.string.warning_some_may_not_work)) @@ -360,7 +361,7 @@ private static void showWarningDialog(final FileHolder holder, final Context con android.R.string.ok, new OnClickListener() { public void onClick(DialogInterface dialog, int which) { - PreferenceActivity.setShowAllWarning(context, showWarningAgain.isChecked()); + PreferenceFragment.setShowAllWarning(context, showWarningAgain.isChecked()); showMoreCommandsDialog(holder, context); } @@ -391,8 +392,8 @@ private static void showMoreCommandsDialog(FileHolder holder, final Context cont final List items = new ArrayList<>(); /* Some of the options don't go to the list hence we have to remove them * to keep the lri correspond with the menu items. In the addition, we have - * to remove them after the first iteration, otherwise the iteration breaks. - */ + * to remove them after the first iteration, otherwise the iteration breaks. + */ List toRemove = new ArrayList<>(); for (int i = 0; i < N; i++) { final ResolveInfo ri = lri.get(i); diff --git a/FileManager/src/main/java/org/openintents/filemanager/util/MimeTypes.java b/FileManager/src/main/java/org/openintents/filemanager/util/MimeTypes.java index b0335bc7..827a7be5 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/util/MimeTypes.java +++ b/FileManager/src/main/java/org/openintents/filemanager/util/MimeTypes.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.util.HashMap; +import java.util.Locale; import java.util.Map; public class MimeTypes { @@ -69,7 +70,7 @@ public void put(String extension, String type, int icon) { public void put(String extension, String type) { // Convert extensions to lower case letters for easier comparison - extension = extension.toLowerCase(); + extension = extension.toLowerCase(Locale.ROOT); mExtensionsToTypes.put(extension, type); } diff --git a/FileManager/src/main/java/org/openintents/filemanager/util/UIUtils.java b/FileManager/src/main/java/org/openintents/filemanager/util/UIUtils.java index 6a848609..50310c71 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/util/UIUtils.java +++ b/FileManager/src/main/java/org/openintents/filemanager/util/UIUtils.java @@ -1,14 +1,15 @@ package org.openintents.filemanager.util; import android.app.Activity; -import android.preference.PreferenceManager; import org.openintents.filemanager.R; +import static androidx.preference.PreferenceManager.getDefaultSharedPreferences; + public abstract class UIUtils { public static void setThemeFor(Activity act) { - if (PreferenceManager.getDefaultSharedPreferences(act).getBoolean("usedarktheme", true)) { + if (getDefaultSharedPreferences(act).getBoolean("usedarktheme", true)) { act.setTheme(R.style.Theme_Dark); } else { act.setTheme(R.style.Theme_Light_DarkTitle); @@ -16,6 +17,6 @@ public static void setThemeFor(Activity act) { } public static boolean shouldDialogInverseBackground(Activity act) { - return !PreferenceManager.getDefaultSharedPreferences(act).getBoolean("usedarktheme", true); + return !getDefaultSharedPreferences(act).getBoolean("usedarktheme", true); } } diff --git a/FileManager/src/main/java/org/openintents/filemanager/view/LegacyActionContainer.java b/FileManager/src/main/java/org/openintents/filemanager/view/LegacyActionContainer.java index 2d76aa28..eaccffa0 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/view/LegacyActionContainer.java +++ b/FileManager/src/main/java/org/openintents/filemanager/view/LegacyActionContainer.java @@ -72,7 +72,7 @@ public boolean onLongClick(View v) { ((MenuItem) v.getTag()).getTitle(), Toast.LENGTH_SHORT); // Position the toast near the item but not on it so that the user can see it appearing. - t.setGravity(Gravity.TOP | Gravity.LEFT, v.getLeft() - 50, + t.setGravity(Gravity.TOP | Gravity.START, v.getLeft() - 50, v.getBottom() + 40); t.show(); return true; @@ -97,6 +97,6 @@ public void setOnActionSelectedListener(OnActionSelectedListener listener) { } public interface OnActionSelectedListener { - public void actionSelected(MenuItem item); + void actionSelected(MenuItem item); } } \ No newline at end of file diff --git a/FileManager/src/main/java/org/openintents/filemanager/view/PathButtonLayout.java b/FileManager/src/main/java/org/openintents/filemanager/view/PathButtonLayout.java index 39314285..3199a47a 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/view/PathButtonLayout.java +++ b/FileManager/src/main/java/org/openintents/filemanager/view/PathButtonLayout.java @@ -1,5 +1,6 @@ package org.openintents.filemanager.view; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Environment; import android.util.AttributeSet; @@ -43,6 +44,7 @@ public static Map getPathDrawables() { return mPathDrawables; } + @SuppressLint("SdCardPath") private void init() { this.setOrientation(LinearLayout.HORIZONTAL); this.setOnLongClickListener(this); diff --git a/FileManager/src/main/java/org/openintents/filemanager/view/PickBar.java b/FileManager/src/main/java/org/openintents/filemanager/view/PickBar.java index 363bd8cf..6bdbc9b2 100644 --- a/FileManager/src/main/java/org/openintents/filemanager/view/PickBar.java +++ b/FileManager/src/main/java/org/openintents/filemanager/view/PickBar.java @@ -33,10 +33,7 @@ public PickBar(Context context, AttributeSet attrs) { private void init() { // Apply borderless style when applicable. - if (VERSION.SDK_INT >= 11) - mButton = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); - else - mButton = new Button(getContext()); + mButton = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); { mButton.setText(R.string.pick_button_default); mButton.setId(R.id.pickbar_button); diff --git a/FileManager/src/main/res/layout/activity_filemanager.xml b/FileManager/src/main/res/layout/activity_filemanager.xml new file mode 100644 index 00000000..20b3d84b --- /dev/null +++ b/FileManager/src/main/res/layout/activity_filemanager.xml @@ -0,0 +1,32 @@ + + + + + + + + \ No newline at end of file diff --git a/FileManager/src/main/res/layout/dialog_details.xml b/FileManager/src/main/res/layout/dialog_details.xml index 8dbf428b..6b217310 100644 --- a/FileManager/src/main/res/layout/dialog_details.xml +++ b/FileManager/src/main/res/layout/dialog_details.xml @@ -4,7 +4,6 @@ android:layout_height="wrap_content"> + android:selectAllOnFocus="true" + android:importantForAutofill="no" /> \ No newline at end of file diff --git a/FileManager/src/main/res/layout/filelist.xml b/FileManager/src/main/res/layout/filelist.xml index 14174c34..6c8622d5 100644 --- a/FileManager/src/main/res/layout/filelist.xml +++ b/FileManager/src/main/res/layout/filelist.xml @@ -101,6 +101,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:clickable="true" + android:focusable="true" android:gravity="center" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/navbar_details"/> diff --git a/FileManager/src/main/res/raw/recent_changes.txt b/FileManager/src/main/res/raw/recent_changes.txt index 2c374b0a..923d6009 100644 --- a/FileManager/src/main/res/raw/recent_changes.txt +++ b/FileManager/src/main/res/raw/recent_changes.txt @@ -1,3 +1,14 @@ +---------------- +release: 2.3.0 + +- minor bug fixes +- better support for newer Android versions + +---------------- +release: 2.2.8 + +- improve handling of deleted files + ---------------- release: 2.2.7 diff --git a/FileManager/src/main/res/values-be/strings.xml b/FileManager/src/main/res/values-be/strings.xml index 193e8050..eb90b773 100644 --- a/FileManager/src/main/res/values-be/strings.xml +++ b/FileManager/src/main/res/values-be/strings.xml @@ -1,5 +1,4 @@ - - - क्या आप वास्तव में% d फ़ाइलें हटाना चाहते हैं? + क्या आप वास्तव में %1$d फ़ाइलें हटाना चाहते हैं? एकाधिक फ़ाइलों का चयन करें File picker diff --git a/FileManager/src/main/res/values-iw/strings.xml b/FileManager/src/main/res/values-iw/strings.xml index 2c1bf2ae..01f3a566 100644 --- a/FileManager/src/main/res/values-iw/strings.xml +++ b/FileManager/src/main/res/values-iw/strings.xml @@ -1,5 +1,4 @@ - - - + Do you really want to delete %d files? ਕਇ ਫਾਇਲ ਚੁਨੇ File picker @@ -82,7 +82,7 @@ ਨਹੀ - + ਕਾਪੀ %s ਕਾਪੀ %1$d ਓਫ %2$s diff --git a/FileManager/src/main/res/values-pt-rBR/strings.xml b/FileManager/src/main/res/values-pt-rBR/strings.xml index 0a2c0553..6dfdcd8b 100644 --- a/FileManager/src/main/res/values-pt-rBR/strings.xml +++ b/FileManager/src/main/res/values-pt-rBR/strings.xml @@ -68,7 +68,7 @@ Tem certeza de que deseja deletar %d arquivos? - Selecione varios arquivos + Selecione vários arquivos Seletor de arquivos diff --git a/FileManager/src/main/res/values-pt/strings.xml b/FileManager/src/main/res/values-pt/strings.xml index 1760cf24..1e020dfa 100644 --- a/FileManager/src/main/res/values-pt/strings.xml +++ b/FileManager/src/main/res/values-pt/strings.xml @@ -65,7 +65,7 @@ Mostrar aviso novamente - Quer mesmo eliminar %s ficheiros? + Quer mesmo eliminar %d ficheiros? Selecionar vários ficheiros Seletor de ficheiros diff --git a/FileManager/src/main/res/values-sd/strings.xml b/FileManager/src/main/res/values-sd/strings.xml index 55be02a9..583d6a48 100644 --- a/FileManager/src/main/res/values-sd/strings.xml +++ b/FileManager/src/main/res/values-sd/strings.xml @@ -61,13 +61,13 @@ नयो फ़ोल्डर ठायो फ़ोल्डर यो नाम |हे फ़ोल्डर खाली आ - शा ताहाँ सहिय्में में%sखे मितायण ता चाह्यो ? + शा ताहाँ सहिय्में में %s खे मितायण ता चाह्यो ? चेतावनी कोई कोई विकल्प कम न कंदवा चेतवानी वारी सां दिखार्यो - \?शा तहां खे सहिया में% d फईल्यूं मिटायनी तव + \?शा तहां खे सहिया में %d फईल्यूं मिटायनी तव हिक्क खान वधीक फईलोयूं चुन्द्यो File picker diff --git a/FileManager/src/main/res/values-sl/strings.xml b/FileManager/src/main/res/values-sl/strings.xml index 85d4d669..cbe99e8f 100644 --- a/FileManager/src/main/res/values-sl/strings.xml +++ b/FileManager/src/main/res/values-sl/strings.xml @@ -1,5 +1,4 @@ - -