aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Brabham <optedoblivion@cyngn.com>2015-04-15 15:33:25 -0700
committerMatt Garnes <matt@cyngn.com>2015-04-17 01:32:33 +0000
commit21d641ccee97ee011ea2587808c2cb78c435144a (patch)
treee200954857d618da62f6679f17149faa5e1d4c99
parent3274036619fc05be506226906bff0686c90cfd50 (diff)
downloadandroid_packages_apps_CMFileManager-21d641ccee97ee011ea2587808c2cb78c435144a.tar.gz
android_packages_apps_CMFileManager-21d641ccee97ee011ea2587808c2cb78c435144a.tar.bz2
android_packages_apps_CMFileManager-21d641ccee97ee011ea2587808c2cb78c435144a.zip
Implement a dialog that warns the user that we must expose the content of the file
by copying it out to an unsecure location in order to allow the external applications to read the files. Change-Id: I163ccd21678f413170e44cf3e8d341cd4747b1ac (cherry picked from commit 58928e7facbdd63d4320748b277e94417fe402bb)
-rw-r--r--AndroidManifest.xml8
-rw-r--r--res/values/strings.xml5
-rw-r--r--src/com/cyanogenmod/filemanager/FileManagerApplication.java4
-rw-r--r--src/com/cyanogenmod/filemanager/activities/NavigationActivity.java5
-rw-r--r--src/com/cyanogenmod/filemanager/activities/SearchActivity.java5
-rw-r--r--src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java5
-rw-r--r--src/com/cyanogenmod/filemanager/providers/secure/ISecureChoiceCompleteListener.java33
-rw-r--r--src/com/cyanogenmod/filemanager/providers/secure/SecureCacheCleanupService.java135
-rw-r--r--src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceClickListener.java97
-rw-r--r--src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceRefreshListener.java81
-rw-r--r--src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceSelectionListener.java88
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java5
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java68
-rw-r--r--src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java5
14 files changed, 537 insertions, 7 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ba672a04..c5c5d6bd 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -31,6 +31,7 @@
<uses-permission android:name="android.permission.ACCESS_SUPERUSER"/>
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.cyanogenmod.filemanager.permissions.READ_THEME"/>
@@ -217,6 +218,13 @@
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
+ <service android:name=".providers.secure.SecureCacheCleanupService">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="android.intent.action.QUICKBOOT_POWERON" />
+ <action android:name="com.cyanogenmod.filemanager.ACTION_START_CLEANUP"/>
+ </intent-filter>
+ </service>
</application>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0fe06ac5..b1601bc6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -815,6 +815,10 @@
<string name="secure_storage_unlock_validation_length">Password must have at least <xliff:g id="characters">%1$d</xliff:g> characters.</string>
<!-- Secure Storage unlock validation, equal -->
<string name="secure_storage_unlock_validation_equals">Passwords do not match.</string>
+ <!-- Secure storage open file warning -->
+ <string name="secure_storage_open_file_warning">This will copy the file out to a temporary
+ unencrypted location. This will be cleared after 1 hour.</string>
+
<!-- Print messages -->
<!-- Unsupported document format -->
@@ -838,4 +842,5 @@
<string name="welcome_msg">Welcome to the CyanogenMod file manager.\n\nThis app allows you to explore the file system and do operations that could break your device. To prevent damage, the app will start in a safe, low-privileged mode.\n\nYou can access the advanced, full-privileged mode via Settings. It\'s your responsibility to ensure that an operation doesn\'t break your system.\n\nThe CyanogenMod Team</string>
<string name="activity_not_found_exception">Couldn\'t find an app to open this file</string>
+
</resources>
diff --git a/src/com/cyanogenmod/filemanager/FileManagerApplication.java b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
index 3855c04f..20a7073d 100644
--- a/src/com/cyanogenmod/filemanager/FileManagerApplication.java
+++ b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
@@ -35,6 +35,7 @@ import com.cyanogenmod.filemanager.preferences.AccessMode;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
import com.cyanogenmod.filemanager.preferences.ObjectStringIdentifier;
import com.cyanogenmod.filemanager.preferences.Preferences;
+import com.cyanogenmod.filemanager.providers.secure.SecureCacheCleanupService;
import com.cyanogenmod.filemanager.service.MimeTypeIndexService;
import com.cyanogenmod.filemanager.ui.ThemeManager;
import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
@@ -183,6 +184,9 @@ public final class FileManagerApplication extends Application {
MimeTypeIndexService.indexFileRoot(this, externalStorage.getAbsolutePath());
MimeTypeIndexService.indexFileRoot(this, Environment.getRootDirectory().getAbsolutePath());
+ // Schedule in case not scheduled (i.e. never booted with this app on device
+ SecureCacheCleanupService.scheduleCleanup(getApplicationContext());
+
}
/**
diff --git a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
index 1f4946a3..454e8f08 100644
--- a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
@@ -1949,6 +1949,11 @@ public class NavigationActivity extends Activity
// Ignored
}
+ @Override
+ public void onCancel(){
+ // nop
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/com/cyanogenmod/filemanager/activities/SearchActivity.java b/src/com/cyanogenmod/filemanager/activities/SearchActivity.java
index 66218bc6..4aa8697a 100644
--- a/src/com/cyanogenmod/filemanager/activities/SearchActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/SearchActivity.java
@@ -1213,6 +1213,11 @@ public class SearchActivity extends Activity
}
}
+ @Override
+ public void onCancel() {
+ // nop
+ }
+
/**
* Method that returns to previous activity.
*
diff --git a/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java b/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java
index 817bdffd..da307c38 100644
--- a/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java
+++ b/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java
@@ -48,4 +48,9 @@ public interface OnRequestRefreshListener {
* @param o The object where to navigate to
*/
void onNavigateTo(Object o);
+
+ /**
+ * Invoked on action cancel
+ */
+ void onCancel();
}
diff --git a/src/com/cyanogenmod/filemanager/providers/secure/ISecureChoiceCompleteListener.java b/src/com/cyanogenmod/filemanager/providers/secure/ISecureChoiceCompleteListener.java
new file mode 100644
index 00000000..b0aea034
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/providers/secure/ISecureChoiceCompleteListener.java
@@ -0,0 +1,33 @@
+/*
+* Copyright (C) 2015 The CyanogenMod Project
+*
+* 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 com.cyanogenmod.filemanager.providers.secure;
+
+import java.io.File;
+
+/**
+ * ISecureChoiceCompleteListener
+ * <pre>
+ * This interface is to notify the caller
+ * in this case
+ * {@link com.cyanogenmod.filemanager.ui.policy.IntentsActionPolicy}
+ * that the operation is complete
+ * </pre>
+ */
+public interface ISecureChoiceCompleteListener {
+ public void onComplete(File cacheFile);
+ public void onCancelled();
+}
diff --git a/src/com/cyanogenmod/filemanager/providers/secure/SecureCacheCleanupService.java b/src/com/cyanogenmod/filemanager/providers/secure/SecureCacheCleanupService.java
new file mode 100644
index 00000000..6accb438
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/providers/secure/SecureCacheCleanupService.java
@@ -0,0 +1,135 @@
+/*
+* Copyright (C) 2015 The CyanogenMod Project
+*
+* 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 com.cyanogenmod.filemanager.providers.secure;
+
+import android.app.AlarmManager;
+import android.app.IntentService;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import com.cyanogenmod.filemanager.model.FileSystemObject;
+import com.cyanogenmod.filemanager.util.FileHelper;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * SecureCacheCleanupService
+ * <pre>
+ * Service that cleans up cache
+ * </pre>
+ *
+ * @see {@link android.app.IntentService}
+ */
+public class SecureCacheCleanupService extends IntentService {
+
+ // Constants
+ private static final String ACTION_START = "com.cyanogenmod.filemanager.ACTION_START_CLEANUP";
+ private static final String NAME = "cleanup-service";
+
+ /**
+ * Creates an IntentService. Invoked by your subclass's constructor.
+ */
+ public SecureCacheCleanupService() {
+ super(NAME);
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ scheduleCleanup(this);
+ } else if (ACTION_START.equals(action)) {
+ cleanupOperation();
+ }
+ }
+
+ private void cleanupOperation() {
+ File cacheDir = new File(getExternalCacheDir(), SecureChoiceClickListener.CACHE_DIR);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(System.currentTimeMillis());
+ calendar.add(Calendar.HOUR, -1);
+ Date cutoff = calendar.getTime();
+
+ if (!cacheDir.exists()) {
+ return;
+ }
+
+ // Get list of files
+ File[] files = cacheDir.listFiles();
+
+ if (files == null) {
+ return;
+ }
+
+ // Delete all, won't run if list is empty
+ for (File file : files) {
+ FileSystemObject fso = FileHelper.createFileSystemObject(file);
+ Date lastAccessDate = fso.getLastAccessedTime();
+ if (lastAccessDate.before(cutoff)) {
+ file.delete();
+ }
+ }
+
+ // Check again after deletion
+ files = cacheDir.listFiles();
+
+ // If no files, cancel alarm
+ if (files == null || files.length < 1) {
+ cancelAlarm(this);
+ }
+
+ }
+
+ /**
+ * Schedule a cleanup alarm
+ *
+ * @param context {@link android.content.Context}
+ *
+ * @throws IllegalArgumentException {@link java.lang.IllegalArgumentException}
+ */
+ public static void scheduleCleanup(Context context) throws IllegalArgumentException {
+ if (context == null) {
+ throw new IllegalArgumentException("'context' cannot be null!");
+ }
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent intent = new Intent(context, SecureCacheCleanupService.class);
+ intent.setAction(ACTION_START);
+ PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
+ alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, 1000,
+ AlarmManager.INTERVAL_HOUR, pendingIntent);
+ }
+
+ /**
+ * Cancel a cleanup alarm
+ *
+ * @param context {@link android.content.Context}
+ *
+ * @throws IllegalArgumentException {@link java.lang.IllegalArgumentException}
+ */
+ public static void cancelAlarm(Context context) throws IllegalArgumentException {
+ if (context == null) {
+ throw new IllegalArgumentException("'context' cannot be null!");
+ }
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent intent = new Intent(context, SecureCacheCleanupService.class);
+ intent.setAction(ACTION_START);
+ PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
+ alarmManager.cancel(pendingIntent);
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceClickListener.java b/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceClickListener.java
new file mode 100644
index 00000000..3e20b99b
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceClickListener.java
@@ -0,0 +1,97 @@
+/*
+* Copyright (C) 2015 The CyanogenMod Project
+*
+* 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 com.cyanogenmod.filemanager.providers.secure;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import com.cyanogenmod.filemanager.model.FileSystemObject;
+import com.cyanogenmod.filemanager.ui.policy.CopyMoveActionPolicy;
+import com.cyanogenmod.filemanager.ui.policy.CopyMoveActionPolicy.LinkedResource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * SecureChoiceClickListener
+ * <pre>
+ * This listens for the secure choice user selection
+ * </pre>
+ *
+ * @see {@link android.content.DialogInterface.OnClickListener}
+ */
+public class SecureChoiceClickListener implements DialogInterface.OnClickListener {
+
+ // Constants
+ /* package */ static final String CACHE_DIR = ".opened-files";
+
+ // Members
+ private Context mContext;
+ private FileSystemObject mFso;
+ private ISecureChoiceCompleteListener mListener;
+
+ /**
+ * Constructor
+ *
+ * @param context {@link android.content.Context}
+ * @param fso {@link com.cyanogenmod.filemanager.model.FileSystemObject}
+ *
+ * @throws IllegalArgumentException {@link java.lang.IllegalArgumentException}
+ */
+ public SecureChoiceClickListener(Context context, FileSystemObject fso,
+ ISecureChoiceCompleteListener listener) throws IllegalArgumentException {
+ if (context == null) {
+ throw new IllegalArgumentException("'context' cannot be null!");
+ }
+ if (fso == null) {
+ throw new IllegalArgumentException("'fso' cannot be null!");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("'listener' cannot be null!");
+ }
+ mContext = context;
+ mFso = fso;
+ mListener = listener;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ case AlertDialog.BUTTON_POSITIVE:
+ performUserFlow();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void performUserFlow() {
+ List<LinkedResource> selection = new ArrayList<LinkedResource>();
+ File hiddenCacheDirectory = new File(mContext.getExternalCacheDir(), CACHE_DIR);
+ // Check if the hidden directory exists
+ if (!hiddenCacheDirectory.exists()) {
+ hiddenCacheDirectory.mkdirs();
+ }
+ final File tmpFso = new File(hiddenCacheDirectory, mFso.getName());
+ selection.add(new LinkedResource(new File(mFso.getFullPath()), tmpFso));
+ CopyMoveActionPolicy.copyFileSystemObjects(mContext, selection,
+ new SecureChoiceSelectionListener(tmpFso),
+ new SecureChoiceRefreshListener(tmpFso, mListener));
+
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceRefreshListener.java b/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceRefreshListener.java
new file mode 100644
index 00000000..cf0e21c5
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceRefreshListener.java
@@ -0,0 +1,81 @@
+/*
+* Copyright (C) 2015 The CyanogenMod Project
+*
+* 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 com.cyanogenmod.filemanager.providers.secure;
+
+import com.cyanogenmod.filemanager.listeners.OnRequestRefreshListener;
+
+import java.io.File;
+
+/**
+ * SecureChoiceRefreshListener
+ * <pre>
+ * This is just a chained callback
+ * </pre>
+ *
+ * @see {@link com.cyanogenmod.filemanager.listeners.OnRequestRefreshListener}
+ */
+/* package */ class SecureChoiceRefreshListener implements OnRequestRefreshListener {
+
+ // Members
+ private File mCacheFile;
+ private ISecureChoiceCompleteListener mListener;
+
+ /**
+ * Constructor
+ *
+ * @param listener
+ * {@link com.cyanogenmod.filemanager.providers.secure.ISecureChoiceCompleteListener}
+ *
+ * @throws IllegalArgumentException {@link java.lang.IllegalArgumentException}
+ */
+ public SecureChoiceRefreshListener(File cacheFile, ISecureChoiceCompleteListener listener)
+ throws IllegalArgumentException {
+ if (cacheFile == null) {
+ throw new IllegalArgumentException("'cacheFile' cannot be null!");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("'listener' cannot be null!");
+ }
+ mCacheFile = cacheFile;
+ mListener = listener;
+ }
+
+ @Override
+ public void onRequestRefresh(Object o, boolean clearSelection) {
+ mListener.onComplete(mCacheFile);
+ }
+
+ @Override
+ public void onRequestBookmarksRefresh() {
+
+ }
+
+ @Override
+ public void onRequestRemove(Object o, boolean clearSelection) {
+
+ }
+
+ @Override
+ public void onNavigateTo(Object o) {
+
+ }
+
+ @Override
+ public void onCancel() {
+ mListener.onCancelled();
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceSelectionListener.java b/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceSelectionListener.java
new file mode 100644
index 00000000..7e8b2551
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/providers/secure/SecureChoiceSelectionListener.java
@@ -0,0 +1,88 @@
+/*
+* Copyright (C) 2015 The CyanogenMod Project
+*
+* 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 com.cyanogenmod.filemanager.providers.secure;
+
+import com.cyanogenmod.filemanager.listeners.OnSelectionListener;
+import com.cyanogenmod.filemanager.model.FileSystemObject;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * SecureChoiceSelectionListener
+ * <pre>
+ * This is something that the copy/move pipeline needs in order to
+ * pass a conditional check in {@link com.cyanogenmod.filemanager.ui.policy
+ * .CopyMoveActionPolicy}
+ * </pre>
+ *
+ * @see {@link com.cyanogenmod.filemanager.listeners.OnSelectionListener}
+ */
+/* package */ class SecureChoiceSelectionListener implements OnSelectionListener {
+
+ // Members
+ private File mFile;
+
+ /**
+ * Constructor
+ *
+ * @param fso {@link java.io.File}
+ * @throws IllegalArgumentException {@link java.lang.IllegalArgumentException}
+ */
+ public SecureChoiceSelectionListener(File fso) throws IllegalArgumentException {
+ if (fso == null) {
+ throw new IllegalArgumentException("'fso' cannot be null!");
+ }
+ mFile = fso;
+ }
+
+ @Override
+ public void onToggleSelection(FileSystemObject fso) {
+
+ }
+
+ @Override
+ public void onDeselectAll() {
+
+ }
+
+ @Override
+ public void onSelectAllVisibleItems() {
+
+ }
+
+ @Override
+ public void onDeselectAllVisibleItems() {
+
+ }
+
+ @Override
+ public List<FileSystemObject> onRequestSelectedFiles() {
+ return null;
+ }
+
+ @Override
+ public List<FileSystemObject> onRequestCurrentItems() {
+ return null;
+ }
+
+ @Override
+ public String onRequestCurrentDir() {
+ return mFile.getParent();
+ }
+
+}
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java
index c2dde32e..c8f61397 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java
@@ -19,12 +19,10 @@ package com.cyanogenmod.filemanager.ui.policy;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
import android.text.Html;
import android.text.Spanned;
import com.cyanogenmod.filemanager.R;
-import com.cyanogenmod.filemanager.console.CancelledOperationException;
import com.cyanogenmod.filemanager.console.Console;
import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
import com.cyanogenmod.filemanager.console.RelaunchableException;
@@ -356,6 +354,9 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
if (mDstConsole != null) {
mDstConsole.onCancel();
}
+ if (mOnRequestRefreshListener != null) {
+ mOnRequestRefreshListener.onCancel();
+ }
refreshUIAfterCompletion();
}
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java
index 5dcab233..aeeb4c9f 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java
@@ -17,7 +17,6 @@
package com.cyanogenmod.filemanager.ui.policy;
import android.content.ComponentName;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
@@ -30,7 +29,6 @@ import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
-
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.activities.ShortcutActivity;
import com.cyanogenmod.filemanager.console.secure.SecureConsole;
@@ -38,6 +36,9 @@ import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.RegularFile;
import com.cyanogenmod.filemanager.providers.SecureResourceProvider;
import com.cyanogenmod.filemanager.providers.SecureResourceProvider.AuthorizationResource;
+import com.cyanogenmod.filemanager.providers.secure.ISecureChoiceCompleteListener;
+import com.cyanogenmod.filemanager.providers.secure.SecureCacheCleanupService;
+import com.cyanogenmod.filemanager.providers.secure.SecureChoiceClickListener;
import com.cyanogenmod.filemanager.ui.dialogs.AssociationsDialog;
import com.cyanogenmod.filemanager.util.DialogHelper;
import com.cyanogenmod.filemanager.util.ExceptionUtil;
@@ -100,12 +101,69 @@ public final class IntentsActionPolicy extends ActionsPolicy {
*/
public static void openFileSystemObject(
final Context ctx, final FileSystemObject fso, final boolean choose,
- OnCancelListener onCancelListener, OnDismissListener onDismissListener) {
+ final OnCancelListener onCancelListener, final OnDismissListener onDismissListener) {
try {
// Create the intent to open the file
- Intent intent = new Intent();
+ final Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
+ // [NOTE][MSB]: Short circuit to pop up dialog informing user we need to copy out the
+ // file until we find a better solution.
+ if (fso.isSecure()) {
+ // [TODO][MSB]: Check visible cache for existing file but I need to split up
+ // resolveIntent function properly for this to be successful
+ DialogHelper.createTwoButtonsQuestionDialog(
+ ctx,
+ R.string.ok,
+ R.string.cancel,
+ R.string.warning_title,
+ ctx.getResources().getString(R.string.secure_storage_open_file_warning),
+ new SecureChoiceClickListener(ctx, fso,
+ new ISecureChoiceCompleteListener() {
+ private boolean isCancelled = false;
+ @Override
+ public void onComplete(File cacheFile) {
+ if (isCancelled) {
+ return;
+ }
+ // Schedule cleanup alarm
+ SecureCacheCleanupService.scheduleCleanup(ctx);
+
+ FileSystemObject cacheFso = FileHelper
+ .createFileSystemObject(cacheFile);
+ // Obtain the mime/type and passed it to intent
+ String mime = MimeTypeHelper.getMimeType(ctx, cacheFso);
+ if (mime != null) {
+ intent.setDataAndType(getUriFromFile(ctx, cacheFso),
+ mime);
+ } else {
+ intent.setData(getUriFromFile(ctx, cacheFso));
+ }
+ // Resolve the intent
+ resolveIntent(
+ ctx,
+ intent,
+ choose,
+ createInternalIntents(ctx, cacheFso),
+ 0,
+ R.string.associations_dialog_openwith_title,
+ R.string.associations_dialog_openwith_action,
+ true,
+ onCancelListener,
+ onDismissListener);
+ }
+
+ @Override
+ public void onCancelled() {
+ isCancelled = true;
+ Toast.makeText(ctx, R.string.cancelled_message, Toast
+ .LENGTH_SHORT).show();
+ }
+ }))
+ .show();
+ return;
+ }
+
// Obtain the mime/type and passed it to intent
String mime = MimeTypeHelper.getMimeType(ctx, fso);
if (mime != null) {
@@ -119,7 +177,7 @@ public final class IntentsActionPolicy extends ActionsPolicy {
ctx,
intent,
choose,
- createInternalIntents(ctx, fso),
+ createInternalIntents(ctx, fso),
0,
R.string.associations_dialog_openwith_title,
R.string.associations_dialog_openwith_action,
diff --git a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
index 099f0edb..4f02b5d4 100644
--- a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
+++ b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
@@ -1266,6 +1266,11 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
// Ignored
}
+ @Override
+ public void onCancel() {
+ // nop
+ }
+
/**
* {@inheritDoc}
*/