Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime permissions for contacts #3632

Merged
merged 9 commits into from
Nov 28, 2018
Merged

Conversation

GoneUp
Copy link
Contributor

@GoneUp GoneUp commented Sep 30, 2018

As the title says the pull request is basically a rebased commit of #3176
A thing to note is that the permission request will only show up when the targetsdk is upped >23, which cannot be changed until save attachment is based on SAF or gets a permission request. I think its still good to merge this to get closer to the goal of #2110.

@GoneUp
Copy link
Contributor Author

GoneUp commented Oct 8, 2018

I fixed the broken travis build, let me know if you want something changed.

Copy link
Contributor

@Valodim Valodim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good step towards runtime permissions, thanks! Left some comments inline

@@ -263,6 +267,14 @@ public Uri getPhotoUri(String address) {
}
}

private Boolean hasPerm() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why Boolean? This can't return null. The method is also not particularly readable, maybe introduce canRead and canWrite variables and then return canRead && canWrite

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method should also have a more descriptive name than "hasPerm", even if it's just privately used in this class

SORT_ORDER);

if (!hasPerm()) {
// return blank cursor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty ugly :( Perhaps create a new EmptyCursor class for it?


@Test
public void queryContactProviderWithoutPermission() throws Exception {
shadowApp.denyPermissions(Manifest.permission.READ_CONTACTS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -47,36 +50,39 @@
ContactsContract.Data.CONTACT_ID,
ContactsContract.CommonDataKinds.Nickname.NAME
};
static final String[] PROJECTION_CRYPTO_ADDRESSES = { "address", "uid_address" };
static final String[] PROJECTION_CRYPTO_STATUS = { "address", "uid_key_status", "autocrypt_key_status" };
static final String[] PROJECTION_CRYPTO_ADDRESSES = {"address", "uid_address"};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are a lot of unrelated formatting changes in this file. those make it harder to see what actually changed, please avoid this in the future. If the formatting is annoying in some place, it's best to fix it in a simple to review formatting-only PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that was just my old habit to use autoformat while coding.

if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {

Toast.makeText(this, R.string.contact_permission_thanks,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems unnecessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thanks message? I just left that in from the orignal pr, I will remove it.

switch (requestCode) {
case PERMISSIONS_REQUEST_READ_CONTACTS:
case PERMISSIONS_REQUEST_WRITE_CONTACTS: {
// If request is cancelled, the result arrays are empty.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's nicer to express this in code:

boolean permissionWasGranted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (permissionWasGranted) {

same amount of lines, but in a formal syntax :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but in this form it is extendable. I expect at least runtime permissions for storage to be here soon.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you meant the if statement, changed that.

@@ -39,6 +39,7 @@ dependencies {
implementation "net.jcip:jcip-annotations:1.0"
implementation "com.jakewharton.timber:timber:${versions.timber}"
implementation "org.apache.james:apache-mime4j-core:${versions.mime4j}"
implementation "org.apache.james:apache-mime4j-dom:${versions.mime4j}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really weird. Is it sufficient to put testImplementation here? Either way, please leave a comment describing why this is necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a strange error on the testbench without it, I wrote that in the commit message. One of the tests (RecipentLoaderTest) could not find a class that is in org.apache.james:apache-mime4j-dom. Normally I would expect it to pass since the dependency is present (https://github.com/k9mail/k-9/blob/012befd59e08c43caddec47d42f5a5d73ac3c2f1/mail/common/build.gradle#L15).

I will try to reduce it to a testImplementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nvm, works without a extra entry now. Clearing all caches works wonders sometimes ;)

GoneUp and others added 3 commits November 27, 2018 23:16
A thing to note is that the permission request will only show up when the targetsdk is upped >23.

Old commit message that explains the change:
--
The approach was to make it so that any K9Activity can easily request
whatever permission in the future.

The Contacts permission is now requested in two locations:

1.  When a list of Messages is displayed
2.  When a new message is first started to be composed.

The permission request is displayed ONCE per onCreate(). Any more than this
and it got really annoying.  A typical user who reads or writes emails
WILL see the request, trust me.  Once they see the message 2x, they
also have the option to block the requests from appearing.

If they DECLINE the request (or decline + DENY any further attempts),
the app should continues to work, albeit without incorporating contact data
(thumbnails, autocomplete, etc.). Contacts may still be added to the
Contacts app, as this uses an Intent and does not require any permission.

Once the Read Contacts permission is enabled, the app immediately begins
to use it.

To add other permissions in the future (such as External Storage access),
the request can be made in a similar way and the permission request result
handled appropriately by just adding it to K9Activity (or overriding in
a particular Activity).
…ilable. Without it DefaultAddressParser is not found in the RecipentLoaderTest even though the dependecy is declared in common. Looks like a gradle bug to me.
@GoneUp
Copy link
Contributor Author

GoneUp commented Nov 28, 2018

Okay, I addressed the feedback and rebased the PR.

@Valodim
Copy link
Contributor

Valodim commented Nov 28, 2018

looks good to me! will test tomorrow, should be good to merge if it checks out. thanks for your work :)

@cketti cketti changed the title Implements runtime permissions for contacts, rebase of #3176 Runtime permissions for contacts Nov 28, 2018
@cketti
Copy link
Member

cketti commented Nov 28, 2018

I fixed two issues:

  • The permission was requested every time the Activity was created, i.e. also after orientation changes. This is rather annoying if a dialog is displayed.
  • Permanently denying the permission would still display the "explanation toast" every time the Activity was created.

@Valodim
Copy link
Contributor

Valodim commented Nov 28, 2018

Looks good. Let's merge this now so people can test, we can fix other problems in follow-up PRs. Thanks 👍

@Valodim Valodim merged commit 0455157 into thunderbird:master Nov 28, 2018
@GoneUp
Copy link
Contributor Author

GoneUp commented Nov 28, 2018

Nice to see it merged. I will look at storage permission next.

@cketti
Copy link
Member

cketti commented Nov 28, 2018

Nice to see it merged. I will look at storage permission next.

Please note that we plan to mostly get rid of the need to request the storage permission. See #3752.

I believe the only situation where we really need the storage permission is when users decide to move their message database to "external" storage.

@GoneUp
Copy link
Contributor Author

GoneUp commented Nov 28, 2018

That makes it so much easier. I implemented saving attachments with SAF some time ago (see GoneUp@47f1dc0, or master...GoneUp:runtime_storage), but it became pretty messy with the compatibility behaviour. I will open a PR soon so we can discuss it there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants