Skip to content

Conversation

@ilgazer
Copy link
Contributor

@ilgazer ilgazer commented Jul 13, 2018

Title (required)

Fixes #1686 Implementation of in-app EXIF modification
Fixes #212 Remove from EXIF: copyright field (name)
Fixes #181 Remove from EXIF: geo info if too close to home
Fixes #70 Option to "anonymize" pictures

Description (required)

There are multiple issues about privacy concerns location and EXIF-related privacy concerns. These commits implement two different settings for removing certain EXIF rags from the picture and for reducing the accuracy or completely eliminating geolocation data from the picture.

The bulk of the anonymization logic is implemented in FileProcessor to prevent code reuse. The existing coordinate extraction logic in MultipleShareActivity is also replaced by a FileProcessor to further reduce code reuse.

Add method anonymizeCoord() that reduces the resolution of GPS coordinates. Think of each coordinate as a pixel. This function reduces the resolution of "the world" to one coordinate(pixel) for every x kilometres (x is the variable prefLocationAccuracy). This approach was chosen over changing the coordinates by a random amount because with that approach; if a user uploads sufficiently many pictures from the same location, statistical analysis can reveal the real location of the user.

The Android support library com.android.support:exifinterface was added as some required features are lacking from earlier Android versions.

As a minor detail, strings.xml was standardized to 4 spaces per tab. That's why there are so many removed lines.

Tests performed (required)

Tested on API 22 Genymotion Google Nexus 5 emulator, with build variant, BetaDebug and ProdDebug.

Screenshots showing what changed (optional)

image
image
image

ilgazer added 3 commits July 13, 2018 19:46
*Add method anonymizeCoord() that reduces the resolution of GPS coordinates. Think of each coordinate as a pixel. This function reduces the resolution of "the world" to one coordinate(pixel) for every x kilometers(x is the variable prefLocationAccuracy)
*Add method getAnonymizedDecimalCoords() that invokes anonymizeCoord() for latitude and longtitude and returns the coordinates with reduced accuracy in "lat|long" format.
*Add method redactEXIFData() that removes exif tags from image and returns the Uri referring to the new, anonymized image.
*Change behaviour of getPathOfMediaOrCopy() such that if anonymization is enabled, the function makes a copy of the file. The path to this copy is stored in variable fileOrCopyPath and the function always returns this path.
*Call FileProcessor.redactEXIFFields() and pass the uri returned by redactEXIFFields() to the Contribution object instead of the Uri of the unprocessed file.
*Move coordinate extraction logic from local function to FileProcessor to decrease code reuse.
@ilgazer
Copy link
Contributor Author

ilgazer commented Jul 13, 2018

Maybe the next step would be adding options for setting EXIF and location behaviour per image in a way that would also be a permanent solution to #1599 Update "automatically get current location" setting text to inform that files will be geotagged with it

@ilgazer
Copy link
Contributor Author

ilgazer commented Jul 14, 2018

I'm not sure why the conflicts remain as there seems to be nothing left that needs changing to allow a merge.

@neslihanturan
Copy link
Collaborator

Hi @ilgazer thanks for your PR but it is huge, which is something makes tester unhappy:/

  • Can you please revert strings.xml file commit, code quality improvements should be in a separate PR
  • Can you verify that all changes here are related with problem you solved? If so I will start to dig in.
  • preferences.xml is changed recently. It would be great if you can solve conflicts.
    Thanks in advance!

ilgazer added 6 commits July 25, 2018 09:51
*Call FileProcessor.redactEXIFFields() and pass the uri returned by redactEXIFFields() along with anonymized coordinates to the uploadController object instead of the Uri of the unprocessed file.
@ilgazer
Copy link
Contributor Author

ilgazer commented Jul 25, 2018 via email

@codecov-io
Copy link

codecov-io commented Jul 25, 2018

Codecov Report

Merging #1712 into master will increase coverage by 0.01%.
The diff coverage is 4.72%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #1712      +/-   ##
=========================================
+ Coverage    3.69%   3.71%   +0.01%     
=========================================
  Files         191     193       +2     
  Lines        9876    9988     +112     
  Branches      885     903      +18     
=========================================
+ Hits          365     371       +6     
- Misses       9484    9589     +105     
- Partials       27      28       +1
Impacted Files Coverage Δ
...java/fr/free/nrw/commons/upload/ShareActivity.java 0% <0%> (ø) ⬆️
...java/fr/free/nrw/commons/upload/FileProcessor.java 0% <0%> (ø) ⬆️
...free/nrw/commons/upload/MultipleShareActivity.java 0% <0%> (ø) ⬆️
app/src/main/java/fr/free/nrw/commons/Utils.java 25.97% <0%> (-1.43%) ⬇️
.../fr/free/nrw/commons/upload/FileMetadataUtils.java 0% <0%> (ø)
...references/LongTitleMultiSelectListPreference.java 66.66% <66.66%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8451e82...f10cd68. Read the comment docs.

ilgazer added 3 commits July 28, 2018 10:48
Create LongTitleMultiSelectListPreference to be used where MultiSelectListPreference was previously used.
@ilgazer ilgazer mentioned this pull request Aug 4, 2018
@neslihanturan
Copy link
Collaborator

@ilgazer , sorry for late testing, I was busy with other tasks in project. Currently I tried to remove Camera Model EXIF and uploaded a photo. But EXIF was still there, here is the photo I uploaded after selecting Remove EXIF tag checkbox: https://commons.m.wikimedia.org/wiki/File:Triangular_bungalow_on_seaside.jpg

Besides functional problem, I think removing something by selecting check boxes doesn't feel very natural from user interface point of view. I think, instead of Remove EXIF Tags item, we can have Manage EXIF Tags item, and behind, Dislplay author, Display Copyritght checkbox items. Selected means we will include that EXIF tag (so they will all be selected as default, user can deselect if they want), unelected means it will be hidden.

@ilgazer
Copy link
Contributor Author

ilgazer commented Sep 1, 2018 via email

@ilgazer
Copy link
Contributor Author

ilgazer commented Sep 4, 2018

Ok, so I implemented a new setting to remove XMP data, which is something similar to EXIF, but there are no good Android libraries to edit XMP data. Because of this, I only implemented deleting all XMP data by parsing the raw jpeg file and finding the XMP section. A future patch for better XMP support could be considered but that could easily turn into implementing a whole library, which is something I have inadequate time for.

I also changed to Manage Exif tags and the ticked items being kept, which means that if there are not new bugs, this PR should finally be ready to merge.

@neslihanturan
Copy link
Collaborator

Thanks @ilgazer , I am testing it now

@nicolas-raoul
Copy link
Member

I agree with @misaochan
Unlike @VojtechDostal I am sure Commons prefers 100 meters error to no coordinates at all, because the biggest problem on Commons is pictures with no geographical information at all. Actually, many pictures are actually more than 100 meters from the subject.

@VojtechDostal
Copy link
Collaborator

Then we should be more open about that and specify the precision used to fill in the template.

@misaochan
Copy link
Member

Maybe we should approve this PR without the Imprecise GPS feature and ask the commons community. After all, we can always retrieve the code from Git history if the Commons people don't object.

@ilgazer Sure, that sounds like a good plan, let's go with that. :) Let us discuss this further at #181 , and it would be great if we could ask in the Commons Village Pump as well. In the meantime, you could remove the GPS accuracy Setting and fix the other bugs, so we can re-test and merge this PR while discussion is ongoing? It is better to have more modular PRs anyway. ;)

@misaochan
Copy link
Member

misaochan commented Sep 10, 2018

Just to clarify, the remaining bugs (which I added in an edit later, so it might not be visible to those using email updates) are:

I have tested the PR on API 24 Nexus S emulator. My uploads work as usual, but:

  • Please set a default value (Do Nothing) in settings, otherwise it is unclear to the user what the default is. Also, display the current value chosen as subtext (similar to Recent Upload Limit). -> not needed if GPS accuracy is removed
  • Tapping the Set XMP Metadata option does nothing?
  • I chose "Do Nothing" in Location accuracy, and uploaded a picture. The picture in Commons has no geotag even though in my gallery view it has a location. https://commons.wikimedia.org/wiki/File:Yong_tau_fu.jpg Tested twice and this was still the case. -> not needed if GPS accuracy is removed
  • Actually, more generally, all of my EXIF is always stripped regardless of what my selection for the "Manage EXIF tags" setting is. @neslihanturan do your coords and EXIF data work with this PR?

@commons-app commons-app deleted a comment Sep 15, 2018
@ilgazer
Copy link
Contributor Author

ilgazer commented Sep 15, 2018

Please set a default value (Do Nothing) in settings,

Good catch! Fixed it.

Tapping the Set Keep XMP Metadata option does nothing?

Could your image have no XMP metadata? You can upload the picture here to see its XMP metadata: http://metapicz.com

Actually, more generally, all of my EXIF is always stripped regardless of what my selection for the "Manage EXIF tags" setting is. @neslihanturan do your coords and EXIF data work with this PR?

This seems incredibly odd. The only piece of code capable of doing that is the XMP removal code. Could you give a link to an image that is losing its EXIF data on upload?

@commons-app commons-app deleted a comment Sep 16, 2018
@misaochan
Copy link
Member

@ilgazer
Copy link
Contributor Author

ilgazer commented Sep 17, 2018

Could you upload its original form so that I can take a better look at it?

@misaochan
Copy link
Member

@ilgazer Shall I email you the picture? I don't think Commons will be happy with me uploading a duplicate, lol.

@ilgazer
Copy link
Contributor Author

ilgazer commented Sep 18, 2018 via email

@ilgazer
Copy link
Contributor Author

ilgazer commented Sep 18, 2018 via email

@neslihanturan
Copy link
Collaborator

Any updates with this PR @misaochan ? Does it work for you?

@misaochan
Copy link
Member

IIRC I emailed @ilgazer the image, but he hasn't gotten back to me about it?

@domdomegg domdomegg changed the title Implements of in-app EXIF and location anonymization [WIP] Implements of in-app EXIF and location anonymization Mar 17, 2019
@neslihanturan
Copy link
Collaborator

Well, I am not sure what to do with this PR, seems like it is sleeping for a while. It has conflicts and known issues. On the other hand, would be great to have this code after it is fixed. So my vote is keeping this open, someone else can take this up and fix since the code looks good overall.

@ilgazer
Copy link
Contributor Author

ilgazer commented Mar 18, 2019 via email

@VitalyVPinchuk
Copy link
Contributor

Hello!
Need some help.
I'm trying to merge changes from ilgazer:master to up-to-date master and having some troubles.
For example, FileProcessor class uses FileUtils.copy() method, which is no longer available.
Should I put copy() back into FileUtils class or is there a better solution?

@ilgazer
Copy link
Contributor Author

ilgazer commented Mar 24, 2019 via email

@VitalyVPinchuk
Copy link
Contributor

@ilgazer, I'm trying to use ExifInterface and it's not clear for me which one I should prefer:
(1) android.media.ExifInterface
(2) android.support.media.ExifInterface
(3) androidx.exifinterface.media.ExifInterface

By the way, it seems that only (1) returns image's latitude and longitude with getLatLong(float[]). Methods getLatLong() of both (2) and (3) return null despite the existence of image's location tag.
What am I doing wrong?

@VitalyVPinchuk
Copy link
Contributor

Please have a look at these two images. The smaller one was taken in emulator and the other one with my OP6. Both of them are shown as having geo tags in Google Photos app. But only OP6's image seems to have lat/long tags while reading with android.support.media.ExifInterface.getLatLong().
Why is it so?

IMG_20190329_144354
IMG_20190329_162205

@ilgazer
Copy link
Contributor Author

ilgazer commented Mar 29, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

7 participants