ImportKeys: Extract duplicate code for permissions
This commit is contained in:
@@ -17,33 +17,28 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener;
|
|
||||||
import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState;
|
import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState;
|
||||||
|
import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||||
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
||||||
|
import org.sufficientlysecure.keychain.ui.util.PermissionsUtil;
|
||||||
import org.sufficientlysecure.keychain.util.FileHelper;
|
import org.sufficientlysecure.keychain.util.FileHelper;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
@@ -60,7 +55,6 @@ public class ImportKeysFileFragment extends Fragment {
|
|||||||
private Uri mCurrentUri;
|
private Uri mCurrentUri;
|
||||||
|
|
||||||
private static final int REQUEST_CODE_FILE = 0x00007003;
|
private static final int REQUEST_CODE_FILE = 0x00007003;
|
||||||
private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance of this fragment
|
* Creates new instance of this fragment
|
||||||
@@ -154,7 +148,7 @@ public class ImportKeysFileFragment extends Fragment {
|
|||||||
if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
|
if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
|
||||||
mCurrentUri = data.getData();
|
mCurrentUri = data.getData();
|
||||||
|
|
||||||
if (checkAndRequestReadPermission(mCurrentUri)) {
|
if (PermissionsUtil.checkAndRequestReadPermission(mActivity, mCurrentUri)) {
|
||||||
startImportingKeys();
|
startImportingKeys();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,53 +183,15 @@ public class ImportKeysFileFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris.
|
|
||||||
* <p>
|
|
||||||
* This method returns true on Android < 6, or if permission is already granted. It
|
|
||||||
* requests the permission and returns false otherwise.
|
|
||||||
* <p>
|
|
||||||
* see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html
|
|
||||||
*/
|
|
||||||
private boolean checkAndRequestReadPermission(final Uri uri) {
|
|
||||||
if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Additional check due to https://commonsware.com/blog/2015/11/09/you-cannot-hold-nonexistent-permissions.html
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
||||||
== PackageManager.PERMISSION_GRANTED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPermissions(
|
|
||||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
|
||||||
REQUEST_PERMISSION_READ_EXTERNAL_STORAGE);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
public void onRequestPermissionsResult(int requestCode,
|
||||||
@NonNull String[] permissions,
|
@NonNull String[] permissions,
|
||||||
@NonNull int[] grantResults) {
|
@NonNull int[] grantResults) {
|
||||||
|
|
||||||
if (requestCode != REQUEST_PERMISSION_READ_EXTERNAL_STORAGE) {
|
if (PermissionsUtil.checkReadPermissionResult(mActivity, requestCode, grantResults)) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean permissionWasGranted = grantResults.length > 0
|
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED;
|
|
||||||
|
|
||||||
if (permissionWasGranted) {
|
|
||||||
startImportingKeys();
|
startImportingKeys();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(mActivity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show();
|
|
||||||
mActivity.setResult(Activity.RESULT_CANCELED);
|
mActivity.setResult(Activity.RESULT_CANCELED);
|
||||||
mActivity.finish();
|
mActivity.finish();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,20 +18,15 @@
|
|||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.databinding.DataBindingUtil;
|
import android.databinding.DataBindingUtil;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.support.v4.app.LoaderManager;
|
import android.support.v4.app.LoaderManager;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.support.v4.util.LongSparseArray;
|
import android.support.v4.util.LongSparseArray;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
@@ -39,7 +34,6 @@ import android.support.v7.widget.RecyclerView;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@@ -55,6 +49,7 @@ import org.sufficientlysecure.keychain.keyimport.processing.LoaderState;
|
|||||||
import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
|
import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
|
||||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
|
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
|
||||||
|
import org.sufficientlysecure.keychain.ui.util.PermissionsUtil;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
|
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
|
||||||
import org.sufficientlysecure.keychain.util.ParcelableProxy;
|
import org.sufficientlysecure.keychain.util.ParcelableProxy;
|
||||||
@@ -74,8 +69,6 @@ public class ImportKeysListFragment extends Fragment implements
|
|||||||
public static final String ARG_NON_INTERACTIVE = "non_interactive";
|
public static final String ARG_NON_INTERACTIVE = "non_interactive";
|
||||||
public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs";
|
public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs";
|
||||||
|
|
||||||
private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12;
|
|
||||||
|
|
||||||
private FragmentActivity mActivity;
|
private FragmentActivity mActivity;
|
||||||
|
|
||||||
private ImportKeysListFragmentBinding binding;
|
private ImportKeysListFragmentBinding binding;
|
||||||
@@ -222,61 +215,21 @@ public class ImportKeysListFragment extends Fragment implements
|
|||||||
mLoaderState = new CloudLoaderState(query, cloudSearchPrefs);
|
mLoaderState = new CloudLoaderState(query, cloudSearchPrefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataUri == null || checkAndRequestReadPermission(dataUri)) {
|
if (dataUri == null || PermissionsUtil.checkAndRequestReadPermission(mActivity, dataUri)) {
|
||||||
restartLoaders();
|
restartLoaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris.
|
|
||||||
* <p/>
|
|
||||||
* This method returns true on Android < 6, or if permission is already granted. It
|
|
||||||
* requests the permission and returns false otherwise.
|
|
||||||
* <p/>
|
|
||||||
* see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html
|
|
||||||
*/
|
|
||||||
private boolean checkAndRequestReadPermission(final Uri uri) {
|
|
||||||
if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Additional check due to https://commonsware.com/blog/2015/11/09/you-cannot-hold-nonexistent-permissions.html
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
||||||
== PackageManager.PERMISSION_GRANTED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPermissions(
|
|
||||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
|
||||||
REQUEST_PERMISSION_READ_EXTERNAL_STORAGE);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
public void onRequestPermissionsResult(int requestCode,
|
||||||
@NonNull String[] permissions,
|
@NonNull String[] permissions,
|
||||||
@NonNull int[] grantResults) {
|
@NonNull int[] grantResults) {
|
||||||
|
|
||||||
if (requestCode != REQUEST_PERMISSION_READ_EXTERNAL_STORAGE) {
|
if (PermissionsUtil.checkReadPermissionResult(mActivity, requestCode, grantResults)) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean permissionWasGranted = grantResults.length > 0
|
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED;
|
|
||||||
|
|
||||||
if (permissionWasGranted) {
|
|
||||||
// permission granted -> load key
|
|
||||||
restartLoaders();
|
restartLoaders();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(mActivity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show();
|
|
||||||
mActivity.setResult(Activity.RESULT_CANCELED);
|
mActivity.setResult(Activity.RESULT_CANCELED);
|
||||||
mActivity.finish();
|
mActivity.finish();
|
||||||
}
|
}
|
||||||
@@ -292,7 +245,8 @@ public class ImportKeysListFragment extends Fragment implements
|
|||||||
if (mLoaderState instanceof BytesLoaderState) {
|
if (mLoaderState instanceof BytesLoaderState) {
|
||||||
BytesLoaderState ls = (BytesLoaderState) mLoaderState;
|
BytesLoaderState ls = (BytesLoaderState) mLoaderState;
|
||||||
|
|
||||||
if (ls.mDataUri != null && !checkAndRequestReadPermission(ls.mDataUri)) {
|
if (ls.mDataUri != null &&
|
||||||
|
!PermissionsUtil.checkAndRequestReadPermission(mActivity, ls.mDataUri)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package org.sufficientlysecure.keychain.ui.util;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Andrea on 19/06/2016.
|
||||||
|
*/
|
||||||
|
public class PermissionsUtil {
|
||||||
|
|
||||||
|
private static final int PERMISSION_READ_EXTERNAL_STORAGE = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris.
|
||||||
|
* <p/>
|
||||||
|
* This method returns true on Android < 6, or if permission is already granted. It
|
||||||
|
* requests the permission and returns false otherwise.
|
||||||
|
* <p/>
|
||||||
|
* see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html
|
||||||
|
*/
|
||||||
|
public static boolean checkAndRequestReadPermission(Activity activity, Uri uri) {
|
||||||
|
if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional check due to https://commonsware.com/blog/2015/11/09/you-cannot-hold-nonexistent-permissions.html
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
== PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
activity.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
||||||
|
PERMISSION_READ_EXTERNAL_STORAGE);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkReadPermissionResult(Activity activity,
|
||||||
|
int requestCode,
|
||||||
|
int[] grantResults) {
|
||||||
|
|
||||||
|
if (requestCode != PERMISSION_READ_EXTERNAL_STORAGE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean permissionWasGranted = grantResults.length > 0
|
||||||
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED;
|
||||||
|
|
||||||
|
if (permissionWasGranted) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Toast.makeText(activity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user