isolated permission request

This commit is contained in:
arrase 2016-11-21 22:43:08 +01:00
parent 8585466c96
commit 8c7b897cd8
3 changed files with 114 additions and 188 deletions

View File

@ -57,8 +57,6 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.RemoteException; import android.os.RemoteException;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.ActionBarDrawerToggle;
@ -92,7 +90,6 @@ import com.google.zxing.integration.android.IntentResult;
public class OrbotMainActivity extends AppCompatActivity public class OrbotMainActivity extends AppCompatActivity
implements OrbotConstants, OnLongClickListener, OnTouchListener { implements OrbotConstants, OnLongClickListener, OnTouchListener {
private GrantedPermissionsAction postPermissionsAction = null;
/* Useful UI bits */ /* Useful UI bits */
private TextView lblStatus = null; //the main text display widget private TextView lblStatus = null; //the main text display widget
@ -134,8 +131,6 @@ public class OrbotMainActivity extends AppCompatActivity
public final static String INTENT_ACTION_REQUEST_HIDDEN_SERVICE = "org.torproject.android.REQUEST_HS_PORT"; public final static String INTENT_ACTION_REQUEST_HIDDEN_SERVICE = "org.torproject.android.REQUEST_HS_PORT";
public final static String INTENT_ACTION_REQUEST_START_TOR = "org.torproject.android.START_TOR"; public final static String INTENT_ACTION_REQUEST_START_TOR = "org.torproject.android.START_TOR";
public final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
// for bridge loading from the assets default bridges.txt file // for bridge loading from the assets default bridges.txt file
class Bridge class Bridge
{ {
@ -525,19 +520,8 @@ public class OrbotMainActivity extends AppCompatActivity
} }
else if (item.getItemId() == R.id.menu_hidden_services) else if (item.getItemId() == R.id.menu_hidden_services)
{ {
if(usesRuntimePermissions() && !hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
postPermissionsAction = new GrantedPermissionsAction() {
@Override
public void run(Context context, boolean granted) {
startActivity(new Intent(context, HiddenServicesActivity.class));
}
};
checkPermissions();
} else {
startActivity(new Intent(this, HiddenServicesActivity.class)); startActivity(new Intent(this, HiddenServicesActivity.class));
} }
}
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -671,19 +655,23 @@ public class OrbotMainActivity extends AppCompatActivity
requestTorRereadConfig(); requestTorRereadConfig();
} }
/* TODO
if(doBackup) if(doBackup)
{ {
backupPath = hsutils.createOnionBackup(hsPort); backupPath = hsutils.createOnionBackup(hsPort);
} }
*/
onion.close(); onion.close();
} }
} }
Intent nResult = new Intent(); Intent nResult = new Intent();
nResult.putExtra("hs_host", hostname); nResult.putExtra("hs_host", hostname);
/* TODO
if(doBackup && backupPath != null) { if(doBackup && backupPath != null) {
nResult.putExtra("hs_backup_path", backupPath); nResult.putExtra("hs_backup_path", backupPath);
} }
*/
setResult(RESULT_OK, nResult); setResult(RESULT_OK, nResult);
finish(); finish();
} }
@ -713,26 +701,21 @@ public class OrbotMainActivity extends AppCompatActivity
if (action == null) if (action == null)
return; return;
if (action.equals(INTENT_ACTION_REQUEST_HIDDEN_SERVICE)) switch (action) {
{ case INTENT_ACTION_REQUEST_HIDDEN_SERVICE:
final int hiddenServicePort = intent.getIntExtra("hs_port", -1); final int hiddenServicePort = intent.getIntExtra("hs_port", -1);
final int hiddenServiceRemotePort = intent.getIntExtra("hs_onion_port", -1); final int hiddenServiceRemotePort = intent.getIntExtra("hs_onion_port", -1);
final String hiddenServiceName = intent.getStringExtra("hs_name"); final String hiddenServiceName = intent.getStringExtra("hs_name");
final Boolean createBackup = intent.getBooleanExtra("hs_backup",false); final Boolean createBackup = intent.getBooleanExtra("hs_backup", false);
final String keyZipPath = intent.getStringExtra("hs_key_zip_path"); final String keyZipPath = intent.getStringExtra("hs_key_zip_path");
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
switch (which){ switch (which) {
case DialogInterface.BUTTON_POSITIVE: case DialogInterface.BUTTON_POSITIVE:
if(createBackup && usesRuntimePermissions()
&& !hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
postPermissionsAction = new GrantedPermissionsAction() {
@Override
public void run(Context context, boolean granted) {
try { try {
enableHiddenServicePort ( enableHiddenServicePort(
hiddenServiceName, hiddenServicePort, hiddenServiceName, hiddenServicePort,
hiddenServiceRemotePort, createBackup, keyZipPath hiddenServiceRemotePort, createBackup, keyZipPath
); );
@ -743,30 +726,8 @@ public class OrbotMainActivity extends AppCompatActivity
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
}
};
checkPermissions();
} else {
try {
enableHiddenServicePort (
hiddenServiceName, hiddenServicePort,
hiddenServiceRemotePort, createBackup, keyZipPath
);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break; break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
finish();
break;
} }
} }
}; };
@ -777,9 +738,8 @@ public class OrbotMainActivity extends AppCompatActivity
.setNegativeButton("Deny", dialogClickListener).show(); .setNegativeButton("Deny", dialogClickListener).show();
return; //don't null the setIntent() as we need it later return; //don't null the setIntent() as we need it later
}
else if (action.equals(INTENT_ACTION_REQUEST_START_TOR)) case INTENT_ACTION_REQUEST_START_TOR:
{
autoStartFromIntent = true; autoStartFromIntent = true;
startTor(); startTor();
@ -800,13 +760,11 @@ public class OrbotMainActivity extends AppCompatActivity
finish(); finish();
}*/ }*/
} break;
else if (action.equals(Intent.ACTION_VIEW)) case Intent.ACTION_VIEW:
{
String urlString = intent.getDataString(); String urlString = intent.getDataString();
if (urlString != null) if (urlString != null) {
{
if (urlString.toLowerCase().startsWith("bridge://")) if (urlString.toLowerCase().startsWith("bridge://"))
@ -814,18 +772,18 @@ public class OrbotMainActivity extends AppCompatActivity
String newBridgeValue = urlString.substring(9); //remove the bridge protocol piece String newBridgeValue = urlString.substring(9); //remove the bridge protocol piece
newBridgeValue = URLDecoder.decode(newBridgeValue); //decode the value here newBridgeValue = URLDecoder.decode(newBridgeValue); //decode the value here
showAlert(getString(R.string.bridges_updated),getString(R.string.restart_orbot_to_use_this_bridge_) + newBridgeValue,false); showAlert(getString(R.string.bridges_updated), getString(R.string.restart_orbot_to_use_this_bridge_) + newBridgeValue, false);
setNewBridges(newBridgeValue); setNewBridges(newBridgeValue);
} }
} }
break;
} }
updateStatus(null); updateStatus(null);
setIntent(null); setIntent(null);
} }
private void setNewBridges (String newBridgeValue) private void setNewBridges (String newBridgeValue)
@ -905,10 +863,6 @@ public class OrbotMainActivity extends AppCompatActivity
} }
private void startIntent (String pkg, String action, Uri data) private void startIntent (String pkg, String action, Uri data)
{ {
Intent i; Intent i;
@ -1598,52 +1552,4 @@ public class OrbotMainActivity extends AppCompatActivity
setNewBridges(sbConfig.toString()); setNewBridges(sbConfig.toString());
} }
private boolean usesRuntimePermissions() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}
@SuppressLint("NewApi")
private boolean hasPermission(String permission) {
return (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
}
private void checkPermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale
(OrbotMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Snackbar.make(findViewById(android.R.id.content),
R.string.please_grant_permissions_for_external_storage,
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(OrbotMainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}).show();
} else {
ActivityCompat.requestPermissions(OrbotMainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}
@SuppressLint("NewApi")
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
boolean granted = (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED);
postPermissionsAction.run(this, granted);
break;
}
}
}
} }

View File

@ -1,12 +1,8 @@
package org.torproject.android.ui.hs; package org.torproject.android.ui.hs;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
@ -79,10 +75,6 @@ public class HiddenServicesActivity extends AppCompatActivity {
Bundle arguments = new Bundle(); Bundle arguments = new Bundle();
arguments.putString("port", port.getText().toString()); arguments.putString("port", port.getText().toString());
arguments.putString("onion", onion.getText().toString()); arguments.putString("onion", onion.getText().toString());
boolean has_write_permission = true;
if (usesRuntimePermissions())
has_write_permission = hasPermission();
arguments.putBoolean("has_write_permissions", has_write_permission);
HSActionsDialog dialog = new HSActionsDialog(); HSActionsDialog dialog = new HSActionsDialog();
dialog.setArguments(arguments); dialog.setArguments(arguments);
@ -91,15 +83,6 @@ public class HiddenServicesActivity extends AppCompatActivity {
}); });
} }
private boolean usesRuntimePermissions() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}
@SuppressLint("NewApi")
private boolean hasPermission() {
return (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
class HSObserver extends ContentObserver { class HSObserver extends ContentObserver {
HSObserver(Handler handler) { HSObserver(Handler handler) {
super(handler); super(handler);

View File

@ -1,14 +1,20 @@
package org.torproject.android.ui.hs.dialogs; package org.torproject.android.ui.hs.dialogs;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Dialog; import android.app.Dialog;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
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.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.view.View; import android.view.View;
@ -20,6 +26,7 @@ import org.torproject.android.hsutils.HiddenServiceUtils;
import org.torproject.android.ui.hs.providers.HSContentProvider; import org.torproject.android.ui.hs.providers.HSContentProvider;
public class HSActionsDialog extends DialogFragment { public class HSActionsDialog extends DialogFragment {
public final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
@NonNull @NonNull
@Override @Override
@ -37,8 +44,8 @@ public class HSActionsDialog extends DialogFragment {
public void onClick(View v) { public void onClick(View v) {
Context mContext = v.getContext(); Context mContext = v.getContext();
if (!arguments.getBoolean("has_write_permissions")) { if (usesRuntimePermissions() && !hasExternalWritePermission(mContext)) {
Toast.makeText(mContext, R.string.please_grant_permissions_for_external_storage, Toast.LENGTH_LONG).show(); requestPermissions();
return; return;
} }
@ -97,4 +104,34 @@ public class HSActionsDialog extends DialogFragment {
return actionDialog; return actionDialog;
} }
private boolean usesRuntimePermissions() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}
@SuppressLint("NewApi")
private boolean hasExternalWritePermission(Context context) {
return (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
private void requestPermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale
(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Snackbar.make(getActivity().findViewById(android.R.id.content),
R.string.please_grant_permissions_for_external_storage,
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}).show();
} else {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}
} }