-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Conversation
I fixed the broken travis build, let me know if you want something changed. |
There was a problem hiding this 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() { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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"}; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems unnecessary
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
app/ui/build.gradle
Outdated
@@ -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}" |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ;)
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.
53cfb91
to
72c3ac5
Compare
…duce duplicated code
Okay, I addressed the feedback and rebased the PR. |
looks good to me! will test tomorrow, should be good to merge if it checks out. thanks for your work :) |
I fixed two issues:
|
Looks good. Let's merge this now so people can test, we can fix other problems in follow-up PRs. Thanks 👍 |
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. |
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. |
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.