From 025909374165743b0e27991db54a7630a9ccf43b Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 11 Jul 2014 20:16:06 +0200 Subject: [PATCH] Added restrictions for Google Maps API v2 Refs #1807 --- CHANGELOG.md | 1 + src/biz/bokhorst/xprivacy/Meta.java | 7 ++ src/biz/bokhorst/xprivacy/PrivacyManager.java | 2 + src/biz/bokhorst/xprivacy/XGoogleMap.java | 99 +++++++++++++++++++ src/biz/bokhorst/xprivacy/XPrivacy.java | 15 +++ 5 files changed, 124 insertions(+) create mode 100644 src/biz/bokhorst/xprivacy/XGoogleMap.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bdaf27ad..2b87d9f43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Changelog **Next release** * Updated some texts +* Added restrictions for [Google Maps API v2](http://developer.android.com/reference/com/google/android/gms/maps/GoogleMap.html) ([issue](/../../issues/1807)) [Open issues](https://github.com/M66B/XPrivacy/issues?state=open) diff --git a/src/biz/bokhorst/xprivacy/Meta.java b/src/biz/bokhorst/xprivacy/Meta.java index 3ebc23bbf..a586d0a37 100644 --- a/src/biz/bokhorst/xprivacy/Meta.java +++ b/src/biz/bokhorst/xprivacy/Meta.java @@ -172,6 +172,13 @@ public static List get() { mListHook.add(new Hook("location", "GMS.requestLocationUpdates", "ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION", 1, null, null)); mListHook.add(new Hook("location", "GMS.requestActivityUpdates", "com.google.android.gms.permission.ACTIVITY_RECOGNITION", 1, null, null)); + mListHook.add(new Hook("location", "MapV2.getMyLocation", "ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION", 1, "2.1.25", null)); + mListHook.add(new Hook("location", "MapV2.getPosition", "ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION", 1, "2.1.25", null)); + mListHook.add(new Hook("location", "MapV2.setLocationSource", "ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION", 1, "2.1.25", null)); + mListHook.add(new Hook("location", "MapV2.setOnMapClickListener", "ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION", 1, "2.1.25", null)); + mListHook.add(new Hook("location", "MapV2.setOnMapLongClickListener", "ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION", 1, "2.1.25", null)); + mListHook.add(new Hook("location", "MapV2.setOnMyLocationChangeListener", "ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION", 1, "2.1.25", null)); + mListHook.add(new Hook("media", "startRecording", "RECORD_AUDIO", 3, null, null).doNotify()); mListHook.add(new Hook("media", "setPreviewCallback", "CAMERA", 1, null, null).doNotify()); mListHook.add(new Hook("media", "setPreviewCallbackWithBuffer", "CAMERA", 8, null, null).doNotify()); diff --git a/src/biz/bokhorst/xprivacy/PrivacyManager.java b/src/biz/bokhorst/xprivacy/PrivacyManager.java index bf3588870..277237bd8 100644 --- a/src/biz/bokhorst/xprivacy/PrivacyManager.java +++ b/src/biz/bokhorst/xprivacy/PrivacyManager.java @@ -1070,6 +1070,8 @@ public static Location getDefacedLocation(int uid, Location location) { // 1 degree ~ 111111 m // 1 m ~ 0,000009 degrees + if (location == null) + location = new Location(cDeface); location.setLatitude(Float.parseFloat(sLat) + (Math.random() * 2.0 - 1.0) * location.getAccuracy() * 9e-6); location.setLongitude(Float.parseFloat(sLon) + (Math.random() * 2.0 - 1.0) * location.getAccuracy() * 9e-6); location.setAltitude(Float.parseFloat(sAlt) + (Math.random() * 2.0 - 1.0) * location.getAccuracy()); diff --git a/src/biz/bokhorst/xprivacy/XGoogleMap.java b/src/biz/bokhorst/xprivacy/XGoogleMap.java new file mode 100644 index 000000000..eb164ff01 --- /dev/null +++ b/src/biz/bokhorst/xprivacy/XGoogleMap.java @@ -0,0 +1,99 @@ +package biz.bokhorst.xprivacy; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import android.location.Location; +import android.os.Binder; +import android.util.Log; + +public class XGoogleMap extends XHook { + private Methods mMethod; + + private XGoogleMap(Methods method, String restrictionName) { + super(restrictionName, method.name(), String.format("MapV2.%s", method.name())); + mMethod = method; + } + + private XGoogleMap(Methods method, String restrictionName, int sdk) { + super(restrictionName, method.name(), String.format("MapV2.%s", method.name()), sdk); + mMethod = method; + } + + public String getClassName() { + if (mMethod == Methods.getPosition) + return "com.google.android.gms.maps.model.Marker"; + else + return "com.google.android.gms.maps.GoogleMap"; + } + + // @formatter:off + + // final Location getMyLocation() + // final void setLocationSource(LocationSource source) + // final void setOnMapClickListener(GoogleMap.OnMapClickListener listener) + // final void setOnMapLongClickListener(GoogleMap.OnMapLongClickListener listener) + // final void setOnMyLocationChangeListener(GoogleMap.OnMyLocationChangeListener listener) + // http://developer.android.com/reference/com/google/android/gms/maps/GoogleMap.html + + // public LatLng getPosition () + // http://developer.android.com/reference/com/google/android/gms/maps/model/Marker.html + // http://developer.android.com/reference/com/google/android/gms/maps/model/LatLng.html + + // @formatter:on + + private enum Methods { + getMyLocation, getPosition, setLocationSource, setOnMapClickListener, setOnMapLongClickListener, setOnMyLocationChangeListener + }; + + public static List getInstances() { + List listHook = new ArrayList(); + for (Methods method : Methods.values()) + listHook.add(new XGoogleMap(method, PrivacyManager.cLocation).optional()); + return listHook; + } + + @Override + protected void before(XParam param) throws Throwable { + if (mMethod == Methods.getMyLocation) { + // Do nothing + + } else if (mMethod == Methods.getPosition) { + // Do nothing + + } else if (mMethod == Methods.setLocationSource || mMethod == Methods.setOnMapClickListener + || mMethod == Methods.setOnMapLongClickListener || mMethod == Methods.setOnMyLocationChangeListener) { + if (isRestricted(param)) + param.setResult(null); + + } else + Util.log(this, Log.WARN, "Unknown method=" + param.method.getName()); + } + + @Override + protected void after(XParam param) throws Throwable { + if (mMethod == Methods.getMyLocation) { + if (param.getResult() != null) + if (isRestricted(param)) { + Location originalLocation = (Location) param.getResult(); + Location fakeLocation = PrivacyManager.getDefacedLocation(Binder.getCallingUid(), originalLocation); + param.setResult(fakeLocation); + } + + } else if (mMethod == Methods.getPosition) { + if (param.getResult() != null) + if (isRestricted(param)) { + Location fakeLocation = PrivacyManager.getDefacedLocation(Binder.getCallingUid(), null); + Field fLat = param.getResult().getClass().getField("latitude"); + Field fLon = param.getResult().getClass().getField("longitude"); + fLat.setAccessible(true); + fLon.setAccessible(true); + fLat.set(param.getResult(), fakeLocation.getLatitude()); + fLon.set(param.getResult(), fakeLocation.getLongitude()); + } + + } else + Util.log(this, Log.WARN, "Unknown method=" + param.method.getName()); + } +} diff --git a/src/biz/bokhorst/xprivacy/XPrivacy.java b/src/biz/bokhorst/xprivacy/XPrivacy.java index 14a36c978..2d512cbb1 100644 --- a/src/biz/bokhorst/xprivacy/XPrivacy.java +++ b/src/biz/bokhorst/xprivacy/XPrivacy.java @@ -136,6 +136,14 @@ public void classLoaded(Class clazz) { hookAll(XLocationClient.getInstances(), clazz.getClassLoader(), mSecret); } }); + + // Google Map + MS.hookClassLoad("com.google.android.gms.maps.GoogleMap", new MS.ClassLoadHook() { + @Override + public void classLoaded(Class clazz) { + hookAll(XGoogleMap.getInstances(), clazz.getClassLoader(), mSecret); + } + }); } // Common @@ -343,6 +351,13 @@ private static void handleLoadPackage(String packageName, ClassLoader classLoade hookAll(XLocationClient.getInstances(), classLoader, secret); } catch (Throwable ignored) { } + + // Google Map + try { + Class.forName("com.google.android.gms.maps.GoogleMap", false, classLoader); + hookAll(XGoogleMap.getInstances(), classLoader, secret); + } catch (Throwable ignored) { + } } public static void handleGetSystemService(String name, String className, String secret) {