Skip to content

Commit 3f840c8

Browse files
Victoria LeaseAndroid (Google) Code Review
authored andcommitted
Merge "fix crashing apps" into jb-mr1-dev
2 parents 477687c + da479c5 commit 3f840c8

File tree

1 file changed

+55
-44
lines changed

1 file changed

+55
-44
lines changed

services/java/com/android/server/LocationManagerService.java

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -609,20 +609,30 @@ private boolean isAllowedBySettingsLocked(String provider, int userId) {
609609
}
610610

611611
/**
612-
* Throw SecurityException if caller has neither COARSE or FINE.
613-
* Otherwise, return the best permission.
612+
* Returns the best permission available to the caller.
614613
*/
615-
private String checkPermission() {
614+
private String getBestCallingPermission() {
616615
if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) ==
617616
PackageManager.PERMISSION_GRANTED) {
618617
return ACCESS_FINE_LOCATION;
619618
} else if (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) ==
620619
PackageManager.PERMISSION_GRANTED) {
621620
return ACCESS_COARSE_LOCATION;
622621
}
622+
return null;
623+
}
623624

624-
throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" +
625-
" ACCESS_FINE_LOCATION permission");
625+
/**
626+
* Throw SecurityException if caller has neither COARSE or FINE.
627+
* Otherwise, return the best permission.
628+
*/
629+
private String checkPermission() {
630+
String perm = getBestCallingPermission();
631+
if (perm == null) {
632+
throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" +
633+
" ACCESS_FINE_LOCATION permission");
634+
}
635+
return perm;
626636
}
627637

628638
/**
@@ -635,19 +645,15 @@ private void checkGeofencePermission() {
635645
}
636646
}
637647

638-
private boolean isAllowedProviderSafe(String provider) {
648+
private String getMinimumPermissionForProvider(String provider) {
639649
if (LocationManager.GPS_PROVIDER.equals(provider) ||
640650
LocationManager.PASSIVE_PROVIDER.equals(provider)) {
641651
// gps and passive providers require FINE permission
642-
return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
643-
== PackageManager.PERMISSION_GRANTED;
652+
return ACCESS_FINE_LOCATION;
644653
} else if (LocationManager.NETWORK_PROVIDER.equals(provider) ||
645654
LocationManager.FUSED_PROVIDER.equals(provider)) {
646655
// network and fused providers are ok with COARSE or FINE
647-
return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
648-
== PackageManager.PERMISSION_GRANTED) ||
649-
(mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
650-
== PackageManager.PERMISSION_GRANTED);
656+
return ACCESS_COARSE_LOCATION;
651657
} else {
652658
// mock providers
653659
LocationProviderInterface lp = mMockProviders.get(provider);
@@ -656,20 +662,43 @@ private boolean isAllowedProviderSafe(String provider) {
656662
if (properties != null) {
657663
if (properties.mRequiresSatellite) {
658664
// provider requiring satellites require FINE permission
659-
return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
660-
== PackageManager.PERMISSION_GRANTED;
665+
return ACCESS_FINE_LOCATION;
661666
} else if (properties.mRequiresNetwork || properties.mRequiresCell) {
662667
// provider requiring network and or cell require COARSE or FINE
663-
return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
664-
== PackageManager.PERMISSION_GRANTED) ||
665-
(mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
666-
== PackageManager.PERMISSION_GRANTED);
668+
return ACCESS_COARSE_LOCATION;
667669
}
668670
}
669671
}
670672
}
671673

672-
return false;
674+
return null;
675+
}
676+
677+
private boolean isPermissionSufficient(String perm, String minPerm) {
678+
if (ACCESS_FINE_LOCATION.equals(minPerm)) {
679+
return ACCESS_FINE_LOCATION.equals(perm);
680+
} else if (ACCESS_COARSE_LOCATION.equals(minPerm)) {
681+
return ACCESS_FINE_LOCATION.equals(perm) ||
682+
ACCESS_COARSE_LOCATION.equals(perm);
683+
} else {
684+
return false;
685+
}
686+
}
687+
688+
private void checkPermissionForProvider(String perm, String provider) {
689+
String minPerm = getMinimumPermissionForProvider(provider);
690+
if (!isPermissionSufficient(perm, minPerm)) {
691+
if (ACCESS_FINE_LOCATION.equals(minPerm)) {
692+
throw new SecurityException("Location provider \"" + provider +
693+
"\" requires ACCESS_FINE_LOCATION permission.");
694+
} else if (ACCESS_COARSE_LOCATION.equals(minPerm)) {
695+
throw new SecurityException("Location provider \"" + provider +
696+
"\" requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.");
697+
} else {
698+
throw new SecurityException("Insufficient permission for location provider \"" +
699+
provider + "\".");
700+
}
701+
}
673702
}
674703

675704
/**
@@ -703,6 +732,7 @@ public List<String> getAllProviders() {
703732
@Override
704733
public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
705734
ArrayList<String> out;
735+
String perm = getBestCallingPermission();
706736
int callingUserId = UserHandle.getCallingUserId();
707737
long identity = Binder.clearCallingIdentity();
708738
try {
@@ -713,7 +743,7 @@ public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
713743
if (LocationManager.FUSED_PROVIDER.equals(name)) {
714744
continue;
715745
}
716-
if (isAllowedProviderSafe(name)) {
746+
if (isPermissionSufficient(perm, getMinimumPermissionForProvider(name))) {
717747
if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) {
718748
continue;
719749
}
@@ -980,26 +1010,12 @@ private Receiver getReceiver(PendingIntent intent, int pid, int uid, String pack
9801010
return receiver;
9811011
}
9821012

983-
private boolean isProviderAllowedByCoarsePermission(String provider) {
984-
if (LocationManager.FUSED_PROVIDER.equals(provider)) {
985-
return true;
986-
}
987-
if (LocationManager.PASSIVE_PROVIDER.equals(provider)) {
988-
return true;
989-
}
990-
if (LocationManager.NETWORK_PROVIDER.equals(provider)) {
991-
return true;
992-
}
993-
return false;
994-
}
995-
9961013
private String checkPermissionAndRequest(LocationRequest request) {
997-
String perm = checkPermission();
1014+
String perm = getBestCallingPermission();
1015+
String provider = request.getProvider();
1016+
checkPermissionForProvider(perm, provider);
9981017

9991018
if (ACCESS_COARSE_LOCATION.equals(perm)) {
1000-
if (!isProviderAllowedByCoarsePermission(request.getProvider())) {
1001-
throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
1002-
}
10031019
switch (request.getQuality()) {
10041020
case LocationRequest.ACCURACY_FINE:
10051021
request.setQuality(LocationRequest.ACCURACY_BLOCK);
@@ -1324,7 +1340,7 @@ public boolean sendNiResponse(int notifId, int userResponse) {
13241340
*/
13251341
@Override
13261342
public ProviderProperties getProviderProperties(String provider) {
1327-
checkPermission();
1343+
checkPermissionForProvider(getBestCallingPermission(), provider);
13281344

13291345
LocationProviderInterface p;
13301346
synchronized (mLock) {
@@ -1337,13 +1353,8 @@ public ProviderProperties getProviderProperties(String provider) {
13371353

13381354
@Override
13391355
public boolean isProviderEnabled(String provider) {
1340-
String perms = checkPermission();
1356+
checkPermissionForProvider(getBestCallingPermission(), provider);
13411357
if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;
1342-
if (ACCESS_COARSE_LOCATION.equals(perms) &&
1343-
!isProviderAllowedByCoarsePermission(provider)) {
1344-
throw new SecurityException("The \"" + provider +
1345-
"\" provider requires ACCESS_FINE_LOCATION permission");
1346-
}
13471358

13481359
long identity = Binder.clearCallingIdentity();
13491360
try {

0 commit comments

Comments
 (0)