Skip to content
This repository has been archived by the owner on Sep 6, 2019. It is now read-only.

Commit

Permalink
Fixed location restriction in AOSP mode
Browse files Browse the repository at this point in the history
Refs #2129
  • Loading branch information
M66B committed Feb 1, 2015
1 parent 3494196 commit 115d371
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 36 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Changelog

**Next release**

* ...
* Fixed location restriction in AOSP mode ([issue](/../../issues/2129))

[Open issues](https://github.com/M66B/XPrivacy/issues?state=open)

Expand Down
118 changes: 83 additions & 35 deletions src/biz/bokhorst/xprivacy/XLocationManager.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package biz.bokhorst.xprivacy;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -10,6 +13,7 @@
import android.location.Location;
import android.os.Binder;
import android.os.Bundle;
import android.os.IInterface;
import android.util.Log;
import android.location.GpsSatellite;
import android.location.GpsStatus;
Expand Down Expand Up @@ -176,24 +180,24 @@ protected void before(XParam param) throws Throwable {

case removeUpdates:
if (isRestricted(param, PrivacyManager.cLocation, "requestLocationUpdates"))
unproxyLocationListener(param, 0);
unproxyLocationListener(param, 0, true);
break;

case requestLocationUpdates:
if (param.args.length > 0 && param.args[0] instanceof String) {
if (isRestrictedExtra(param, (String) param.args[0]))
proxyLocationListener(param, 3, LocationListener.class);
proxyLocationListener(param, 3, LocationListener.class, true);
} else {
if (isRestricted(param))
proxyLocationListener(param, 3, LocationListener.class);
proxyLocationListener(param, 3, LocationListener.class, true);
}
break;

case Srv_removeUpdates:
if (isRestricted(param, PrivacyManager.cLocation, "Srv_requestLocationUpdates"))
if (param.args.length > 1)
if (param.args[0] != null) // ILocationListener
unproxyLocationListener(param, 0);
unproxyLocationListener(param, 0, false);
else if (param.args[1] != null) // PendingIntent
param.setResult(null);
break;
Expand All @@ -202,18 +206,18 @@ else if (param.args[1] != null) // PendingIntent
if (isRestricted(param))
if (param.args.length > 2)
if (param.args[1] != null) // ILocationListener
proxyLocationListener(param, 1, Class.forName("android.location.ILocationListener"));
proxyLocationListener(param, 1, Class.forName("android.location.ILocationListener"), false);
else if (param.args[2] != null) // PendingIntent
param.setResult(null);
break;

case requestSingleUpdate:
if (param.args.length > 0 && param.args[0] instanceof String) {
if (isRestrictedExtra(param, (String) param.args[0]))
proxyLocationListener(param, 1, LocationListener.class);
proxyLocationListener(param, 1, LocationListener.class, true);
} else {
if (isRestricted(param))
proxyLocationListener(param, 1, LocationListener.class);
proxyLocationListener(param, 1, LocationListener.class, true);
}
break;

Expand Down Expand Up @@ -317,51 +321,79 @@ protected void after(XParam param) throws Throwable {
}
}

private void proxyLocationListener(XParam param, int arg, Class<?> interfaze) throws Throwable {
private void proxyLocationListener(XParam param, int arg, Class<?> interfaze, boolean client) throws Throwable {
if (param.args.length > arg)
if (param.args[arg] instanceof PendingIntent)
param.setResult(null);

else if (param.args[arg] != null && param.thisObject != null) {
Object key = param.args[arg];
synchronized (mMapProxy) {
// Reuse existing proxy
if (mMapProxy.containsKey(key)) {
Util.log(this, Log.INFO, "Reuse existing proxy uid=" + Binder.getCallingUid());
param.args[arg] = mMapProxy.get(key);
return;
if (client) {
Object key = param.args[arg];
synchronized (mMapProxy) {
// Reuse existing proxy
if (mMapProxy.containsKey(key)) {
Util.log(this, Log.INFO, "Reuse existing proxy uid=" + Binder.getCallingUid());
param.args[arg] = mMapProxy.get(key);
return;
}

// Already proxied
if (mMapProxy.containsValue(key)) {
Util.log(this, Log.INFO, "Already proxied uid=" + Binder.getCallingUid());
return;
}
}

// Already proxied
if (mMapProxy.containsValue(key)) {
Util.log(this, Log.INFO, "Already proxied uid=" + Binder.getCallingUid());
return;
}
}
// Create proxy
Util.log(this, Log.INFO, "Creating proxy uid=" + Binder.getCallingUid());
Object proxy = new ProxyLocationListener(Binder.getCallingUid(), (LocationListener) param.args[arg]);

// Create proxy
Util.log(this, Log.INFO, "Creating proxy uid=" + Binder.getCallingUid());
Object proxy = new ProxyLocationListener(Binder.getCallingUid(), (LocationListener) param.args[arg]);

// Use proxy
synchronized (mMapProxy) {
mMapProxy.put(key, proxy);
// Use proxy
synchronized (mMapProxy) {
mMapProxy.put(key, proxy);
}
param.args[arg] = proxy;
} else {
// Create proxy
ClassLoader cl = param.thisObject.getClass().getClassLoader();
InvocationHandler ih = new OnLocationChangedHandler(Binder.getCallingUid(), param.args[arg]);
Object proxy = Proxy.newProxyInstance(cl, new Class<?>[] { interfaze }, ih);

Object key = param.args[arg];
if (key instanceof IInterface)
key = ((IInterface) key).asBinder();

// Use proxy
synchronized (mMapProxy) {
mMapProxy.put(key, proxy);
}
param.args[arg] = proxy;
}
param.args[arg] = proxy;
}
}

private void unproxyLocationListener(XParam param, int arg) {
private void unproxyLocationListener(XParam param, int arg, boolean client) {
if (param.args.length > arg)
if (param.args[arg] instanceof PendingIntent)
param.setResult(null);

else if (param.args[arg] != null) {
Object key = param.args[arg];
synchronized (mMapProxy) {
if (mMapProxy.containsKey(key)) {
Util.log(this, Log.INFO, "Removing proxy uid=" + Binder.getCallingUid());
param.args[arg] = mMapProxy.get(key);
if (client) {
Object key = param.args[arg];
synchronized (mMapProxy) {
if (mMapProxy.containsKey(key)) {
Util.log(this, Log.INFO, "Removing proxy uid=" + Binder.getCallingUid());
param.args[arg] = mMapProxy.get(key);
}
}
} else {
Object key = param.args[arg];
if (key instanceof IInterface)
key = ((IInterface) key).asBinder();

synchronized (mMapProxy) {
if (mMapProxy.containsKey(key))
param.args[arg] = mMapProxy.get(key);
}
}
}
Expand Down Expand Up @@ -398,4 +430,20 @@ public void onStatusChanged(String provider, int status, Bundle extras) {
mListener.onStatusChanged(provider, status, extras);
}
}

private class OnLocationChangedHandler implements InvocationHandler {
private int mUid;
private Object mTarget;

public OnLocationChangedHandler(int uid, Object target) {
mUid = uid;
mTarget = target;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("onLocationChanged".equals(method.getName()))
args[0] = PrivacyManager.getDefacedLocation(mUid, (Location) args[0]);
return method.invoke(mTarget, args);
}
}
}

0 comments on commit 115d371

Please sign in to comment.