diff options
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} */ |