Skip to content

Commit fbadb69

Browse files
committed
Changes to support updating location providers.
This reverts commit 20de160. Bug: 7242814 Change-Id: I9ec49a14feb835b6683186fc6da4a74ae19fbae2
1 parent 0f2d014 commit fbadb69

File tree

5 files changed

+112
-38
lines changed

5 files changed

+112
-38
lines changed

core/res/res/values/config.xml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -636,19 +636,12 @@
636636
of new location providers at run-time. The new package does not
637637
have to be explicitly listed here, however it must have a signature
638638
that matches the signature of at least one package on this list.
639-
Platforms should overlay additional packages in
640-
config_overlay_locationProviderPackageNames, instead of overlaying
641-
this config, if they only want to append packages and not replace
642-
the entire array.
643639
-->
644640
<string-array name="config_locationProviderPackageNames" translatable="false">
641+
<!-- The standard AOSP fused location provider -->
645642
<item>com.android.location.fused</item>
646643
</string-array>
647644

648-
<!-- Pacakge name(s) supplied by overlay, and appended to
649-
config_locationProviderPackageNames. -->
650-
<string-array name="config_overlay_locationProviderPackageNames" translatable="false" />
651-
652645
<!-- Boolean indicating if current platform supports bluetooth SCO for off call
653646
use cases -->
654647
<bool name="config_bluetooth_sco_off_call">true</bool>

core/res/res/values/symbols.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,6 @@
14751475
<java-symbol type="array" name="radioAttributes" />
14761476
<java-symbol type="array" name="config_oemUsbModeOverride" />
14771477
<java-symbol type="array" name="config_locationProviderPackageNames" />
1478-
<java-symbol type="array" name="config_overlay_locationProviderPackageNames" />
14791478
<java-symbol type="bool" name="config_animateScreenLights" />
14801479
<java-symbol type="bool" name="config_automatic_brightness_available" />
14811480
<java-symbol type="bool" name="config_sf_limitedAlpha" />

packages/FusedLocation/AndroidManifest.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
-->
1919
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2020
package="com.android.location.fused"
21-
coreApp="true">
21+
coreApp="true"
22+
android:sharedUserId="android.uid.system">
2223

2324
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
2425
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
@@ -39,7 +40,7 @@
3940
<intent-filter>
4041
<action android:name="com.android.location.service.FusedLocationProvider" />
4142
</intent-filter>
42-
<meta-data android:name="version" android:value="1" />
43+
<meta-data android:name="serviceVersion" android:value="0" />
4344
</service>
4445
</application>
4546
</manifest>

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

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
import android.content.Intent;
2424
import android.content.IntentFilter;
2525
import android.content.pm.ApplicationInfo;
26+
import android.content.pm.PackageInfo;
2627
import android.content.pm.PackageManager;
2728
import android.content.pm.PackageManager.NameNotFoundException;
29+
import android.content.pm.ResolveInfo;
30+
import android.content.pm.Signature;
2831
import android.content.res.Resources;
2932
import android.database.ContentObserver;
3033
import android.location.Address;
@@ -246,6 +249,74 @@ public void onReceive(Context context, Intent intent) {
246249
updateProvidersLocked();
247250
}
248251

252+
private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) {
253+
PackageManager pm = mContext.getPackageManager();
254+
String systemPackageName = mContext.getPackageName();
255+
ArrayList<HashSet<Signature>> sigSets = ServiceWatcher.getSignatureSets(mContext, pkgs);
256+
257+
List<ResolveInfo> rInfos = pm.queryIntentServicesAsUser(
258+
new Intent(FUSED_LOCATION_SERVICE_ACTION),
259+
PackageManager.GET_META_DATA, mCurrentUserId);
260+
for (ResolveInfo rInfo : rInfos) {
261+
String packageName = rInfo.serviceInfo.packageName;
262+
263+
// Check that the signature is in the list of supported sigs. If it's not in
264+
// this list the standard provider binding logic won't bind to it.
265+
try {
266+
PackageInfo pInfo;
267+
pInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
268+
if (!ServiceWatcher.isSignatureMatch(pInfo.signatures, sigSets)) {
269+
Log.w(TAG, packageName + " resolves service " + FUSED_LOCATION_SERVICE_ACTION +
270+
", but has wrong signature, ignoring");
271+
continue;
272+
}
273+
} catch (NameNotFoundException e) {
274+
Log.e(TAG, "missing package: " + packageName);
275+
continue;
276+
}
277+
278+
// Get the version info
279+
if (rInfo.serviceInfo.metaData == null) {
280+
Log.w(TAG, "Found fused provider without metadata: " + packageName);
281+
continue;
282+
}
283+
284+
int version = rInfo.serviceInfo.metaData.getInt(
285+
ServiceWatcher.EXTRA_SERVICE_VERSION, -1);
286+
if (version == 0) {
287+
// This should be the fallback fused location provider.
288+
289+
// Make sure it's in the system partition.
290+
if ((rInfo.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
291+
if (D) Log.d(TAG, "Fallback candidate not in /system: " + packageName);
292+
continue;
293+
}
294+
295+
// Check that the fallback is signed the same as the OS
296+
// as a proxy for coreApp="true"
297+
if (pm.checkSignatures(systemPackageName, packageName)
298+
!= PackageManager.SIGNATURE_MATCH) {
299+
if (D) Log.d(TAG, "Fallback candidate not signed the same as system: "
300+
+ packageName);
301+
continue;
302+
}
303+
304+
// Found a valid fallback.
305+
if (D) Log.d(TAG, "Found fallback provider: " + packageName);
306+
return;
307+
} else {
308+
if (D) Log.d(TAG, "Fallback candidate not version 0: " + packageName);
309+
}
310+
}
311+
312+
throw new IllegalStateException("Unable to find a fused location provider that is in the "
313+
+ "system partition with version 0 and signed with the platform certificate. "
314+
+ "Such a package is needed to provide a default fused location provider in the "
315+
+ "event that no other fused location provider has been installed or is currently "
316+
+ "available. For example, coreOnly boot mode when decrypting the data "
317+
+ "partition. The fallback must also be marked coreApp=\"true\" in the manifest");
318+
}
319+
249320
private void loadProvidersLocked() {
250321
// create a passive location provider, which is always enabled
251322
PassiveProvider passiveProvider = new PassiveProvider(this);
@@ -275,14 +346,13 @@ Load package name(s) containing location provider support.
275346
*/
276347
Resources resources = mContext.getResources();
277348
ArrayList<String> providerPackageNames = new ArrayList<String>();
278-
String[] pkgs1 = resources.getStringArray(
349+
String[] pkgs = resources.getStringArray(
279350
com.android.internal.R.array.config_locationProviderPackageNames);
280-
String[] pkgs2 = resources.getStringArray(
281-
com.android.internal.R.array.config_overlay_locationProviderPackageNames);
282-
if (D) Log.d(TAG, "built-in location providers: " + Arrays.toString(pkgs1));
283-
if (D) Log.d(TAG, "overlay location providers: " + Arrays.toString(pkgs2));
284-
if (pkgs1 != null) providerPackageNames.addAll(Arrays.asList(pkgs1));
285-
if (pkgs2 != null) providerPackageNames.addAll(Arrays.asList(pkgs2));
351+
if (D) Log.d(TAG, "certificates for location providers pulled from: " +
352+
Arrays.toString(pkgs));
353+
if (pkgs != null) providerPackageNames.addAll(Arrays.asList(pkgs));
354+
355+
ensureFallbackFusedProviderPresentLocked(providerPackageNames);
286356

287357
// bind to network provider
288358
LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind(

services/java/com/android/server/ServiceWatcher.java

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
*/
4444
public class ServiceWatcher implements ServiceConnection {
4545
private static final boolean D = false;
46-
private static final String EXTRA_VERSION = "version";
46+
public static final String EXTRA_SERVICE_VERSION = "serviceVersion";
4747

4848
private final String mTag;
4949
private final Context mContext;
@@ -58,9 +58,27 @@ public class ServiceWatcher implements ServiceConnection {
5858
// all fields below synchronized on mLock
5959
private IBinder mBinder; // connected service
6060
private String mPackageName; // current best package
61-
private int mVersion; // current best version
61+
private int mVersion = Integer.MIN_VALUE; // current best version
6262
private int mCurrentUserId;
6363

64+
public static ArrayList<HashSet<Signature>> getSignatureSets(Context context,
65+
List<String> initialPackageNames) {
66+
PackageManager pm = context.getPackageManager();
67+
ArrayList<HashSet<Signature>> sigSets = new ArrayList<HashSet<Signature>>();
68+
for (int i = 0, size = initialPackageNames.size(); i < size; i++) {
69+
String pkg = initialPackageNames.get(i);
70+
try {
71+
HashSet<Signature> set = new HashSet<Signature>();
72+
Signature[] sigs = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures;
73+
set.addAll(Arrays.asList(sigs));
74+
sigSets.add(set);
75+
} catch (NameNotFoundException e) {
76+
Log.w("ServiceWatcher", pkg + " not found");
77+
}
78+
}
79+
return sigSets;
80+
}
81+
6482
public ServiceWatcher(Context context, String logTag, String action,
6583
List<String> initialPackageNames, Runnable newServiceWork, Handler handler, int userId) {
6684
mContext = context;
@@ -71,20 +89,7 @@ public ServiceWatcher(Context context, String logTag, String action,
7189
mHandler = handler;
7290
mCurrentUserId = userId;
7391

74-
mSignatureSets = new ArrayList<HashSet<Signature>>();
75-
for (int i=0; i < initialPackageNames.size(); i++) {
76-
String pkg = initialPackageNames.get(i);
77-
HashSet<Signature> set = new HashSet<Signature>();
78-
try {
79-
Signature[] sigs =
80-
mPm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures;
81-
set.addAll(Arrays.asList(sigs));
82-
mSignatureSets.add(set);
83-
} catch (NameNotFoundException e) {
84-
Log.w(logTag, pkg + " not found");
85-
}
86-
}
87-
92+
mSignatureSets = getSignatureSets(context, initialPackageNames);
8893
}
8994

9095
public boolean start() {
@@ -132,15 +137,16 @@ private boolean bindBestPackageLocked(String justCheckThisPackage) {
132137
// check version
133138
int version = 0;
134139
if (rInfo.serviceInfo.metaData != null) {
135-
version = rInfo.serviceInfo.metaData.getInt(EXTRA_VERSION, 0);
140+
version = rInfo.serviceInfo.metaData.getInt(EXTRA_SERVICE_VERSION, 0);
136141
}
142+
137143
if (version > mVersion) {
138144
bestVersion = version;
139145
bestPackage = packageName;
140146
}
141147
}
142148

143-
if (D) Log.d(mTag, String.format("bindBestPackage %s found %d, %s",
149+
if (D) Log.d(mTag, String.format("bindBestPackage for %s : %s found %d, %s", mAction,
144150
(justCheckThisPackage == null ? "" : "(" + justCheckThisPackage + ") "),
145151
rInfos.size(),
146152
(bestPackage == null ? "no new best package" : "new best packge: " + bestPackage)));
@@ -174,7 +180,8 @@ private void bindToPackageLocked(String packageName, int version) {
174180
| Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_NOT_VISIBLE, mCurrentUserId);
175181
}
176182

177-
private boolean isSignatureMatch(Signature[] signatures) {
183+
public static boolean isSignatureMatch(Signature[] signatures,
184+
List<HashSet<Signature>> sigSets) {
178185
if (signatures == null) return false;
179186

180187
// build hashset of input to test against
@@ -184,14 +191,18 @@ private boolean isSignatureMatch(Signature[] signatures) {
184191
}
185192

186193
// test input against each of the signature sets
187-
for (HashSet<Signature> referenceSet : mSignatureSets) {
194+
for (HashSet<Signature> referenceSet : sigSets) {
188195
if (referenceSet.equals(inputSet)) {
189196
return true;
190197
}
191198
}
192199
return false;
193200
}
194201

202+
private boolean isSignatureMatch(Signature[] signatures) {
203+
return isSignatureMatch(signatures, mSignatureSets);
204+
}
205+
195206
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
196207
/**
197208
* Called when package has been reinstalled

0 commit comments

Comments
 (0)