Loading core/res/res/values/config.xml +1 −8 Original line number Diff line number Diff line Loading @@ -636,19 +636,12 @@ of new location providers at run-time. The new package does not have to be explicitly listed here, however it must have a signature that matches the signature of at least one package on this list. Platforms should overlay additional packages in config_overlay_locationProviderPackageNames, instead of overlaying this config, if they only want to append packages and not replace the entire array. --> <string-array name="config_locationProviderPackageNames" translatable="false"> <!-- The standard AOSP fused location provider --> <item>com.android.location.fused</item> </string-array> <!-- Pacakge name(s) supplied by overlay, and appended to config_locationProviderPackageNames. --> <string-array name="config_overlay_locationProviderPackageNames" translatable="false" /> <!-- Boolean indicating if current platform supports bluetooth SCO for off call use cases --> <bool name="config_bluetooth_sco_off_call">true</bool> Loading core/res/res/values/symbols.xml +0 −1 Original line number Diff line number Diff line Loading @@ -1475,7 +1475,6 @@ <java-symbol type="array" name="radioAttributes" /> <java-symbol type="array" name="config_oemUsbModeOverride" /> <java-symbol type="array" name="config_locationProviderPackageNames" /> <java-symbol type="array" name="config_overlay_locationProviderPackageNames" /> <java-symbol type="bool" name="config_animateScreenLights" /> <java-symbol type="bool" name="config_automatic_brightness_available" /> <java-symbol type="bool" name="config_sf_limitedAlpha" /> Loading packages/FusedLocation/AndroidManifest.xml +3 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.location.fused" coreApp="true"> coreApp="true" android:sharedUserId="android.uid.system"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> Loading @@ -39,7 +40,7 @@ <intent-filter> <action android:name="com.android.location.service.FusedLocationProvider" /> </intent-filter> <meta-data android:name="version" android:value="1" /> <meta-data android:name="serviceVersion" android:value="0" /> </service> </application> </manifest> services/java/com/android/server/LocationManagerService.java +77 −7 Original line number Diff line number Diff line Loading @@ -23,8 +23,11 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.content.res.Resources; import android.database.ContentObserver; import android.location.Address; Loading Loading @@ -249,6 +252,74 @@ public class LocationManagerService extends ILocationManager.Stub implements Run updateProvidersLocked(); } private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) { PackageManager pm = mContext.getPackageManager(); String systemPackageName = mContext.getPackageName(); ArrayList<HashSet<Signature>> sigSets = ServiceWatcher.getSignatureSets(mContext, pkgs); List<ResolveInfo> rInfos = pm.queryIntentServicesAsUser( new Intent(FUSED_LOCATION_SERVICE_ACTION), PackageManager.GET_META_DATA, mCurrentUserId); for (ResolveInfo rInfo : rInfos) { String packageName = rInfo.serviceInfo.packageName; // Check that the signature is in the list of supported sigs. If it's not in // this list the standard provider binding logic won't bind to it. try { PackageInfo pInfo; pInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); if (!ServiceWatcher.isSignatureMatch(pInfo.signatures, sigSets)) { Log.w(TAG, packageName + " resolves service " + FUSED_LOCATION_SERVICE_ACTION + ", but has wrong signature, ignoring"); continue; } } catch (NameNotFoundException e) { Log.e(TAG, "missing package: " + packageName); continue; } // Get the version info if (rInfo.serviceInfo.metaData == null) { Log.w(TAG, "Found fused provider without metadata: " + packageName); continue; } int version = rInfo.serviceInfo.metaData.getInt( ServiceWatcher.EXTRA_SERVICE_VERSION, -1); if (version == 0) { // This should be the fallback fused location provider. // Make sure it's in the system partition. if ((rInfo.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { if (D) Log.d(TAG, "Fallback candidate not in /system: " + packageName); continue; } // Check that the fallback is signed the same as the OS // as a proxy for coreApp="true" if (pm.checkSignatures(systemPackageName, packageName) != PackageManager.SIGNATURE_MATCH) { if (D) Log.d(TAG, "Fallback candidate not signed the same as system: " + packageName); continue; } // Found a valid fallback. if (D) Log.d(TAG, "Found fallback provider: " + packageName); return; } else { if (D) Log.d(TAG, "Fallback candidate not version 0: " + packageName); } } throw new IllegalStateException("Unable to find a fused location provider that is in the " + "system partition with version 0 and signed with the platform certificate. " + "Such a package is needed to provide a default fused location provider in the " + "event that no other fused location provider has been installed or is currently " + "available. For example, coreOnly boot mode when decrypting the data " + "partition. The fallback must also be marked coreApp=\"true\" in the manifest"); } private void loadProvidersLocked() { // create a passive location provider, which is always enabled PassiveProvider passiveProvider = new PassiveProvider(this); Loading Loading @@ -278,14 +349,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ Resources resources = mContext.getResources(); ArrayList<String> providerPackageNames = new ArrayList<String>(); String[] pkgs1 = resources.getStringArray( String[] pkgs = resources.getStringArray( com.android.internal.R.array.config_locationProviderPackageNames); String[] pkgs2 = resources.getStringArray( com.android.internal.R.array.config_overlay_locationProviderPackageNames); if (D) Log.d(TAG, "built-in location providers: " + Arrays.toString(pkgs1)); if (D) Log.d(TAG, "overlay location providers: " + Arrays.toString(pkgs2)); if (pkgs1 != null) providerPackageNames.addAll(Arrays.asList(pkgs1)); if (pkgs2 != null) providerPackageNames.addAll(Arrays.asList(pkgs2)); if (D) Log.d(TAG, "certificates for location providers pulled from: " + Arrays.toString(pkgs)); if (pkgs != null) providerPackageNames.addAll(Arrays.asList(pkgs)); ensureFallbackFusedProviderPresentLocked(providerPackageNames); // bind to network provider LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind( Loading services/java/com/android/server/ServiceWatcher.java +31 −20 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ import java.util.List; */ public class ServiceWatcher implements ServiceConnection { private static final boolean D = false; private static final String EXTRA_VERSION = "version"; public static final String EXTRA_SERVICE_VERSION = "serviceVersion"; private final String mTag; private final Context mContext; Loading @@ -58,9 +58,27 @@ public class ServiceWatcher implements ServiceConnection { // all fields below synchronized on mLock private IBinder mBinder; // connected service private String mPackageName; // current best package private int mVersion; // current best version private int mVersion = Integer.MIN_VALUE; // current best version private int mCurrentUserId; public static ArrayList<HashSet<Signature>> getSignatureSets(Context context, List<String> initialPackageNames) { PackageManager pm = context.getPackageManager(); ArrayList<HashSet<Signature>> sigSets = new ArrayList<HashSet<Signature>>(); for (int i = 0, size = initialPackageNames.size(); i < size; i++) { String pkg = initialPackageNames.get(i); try { HashSet<Signature> set = new HashSet<Signature>(); Signature[] sigs = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures; set.addAll(Arrays.asList(sigs)); sigSets.add(set); } catch (NameNotFoundException e) { Log.w("ServiceWatcher", pkg + " not found"); } } return sigSets; } public ServiceWatcher(Context context, String logTag, String action, List<String> initialPackageNames, Runnable newServiceWork, Handler handler, int userId) { mContext = context; Loading @@ -71,20 +89,7 @@ public class ServiceWatcher implements ServiceConnection { mHandler = handler; mCurrentUserId = userId; mSignatureSets = new ArrayList<HashSet<Signature>>(); for (int i=0; i < initialPackageNames.size(); i++) { String pkg = initialPackageNames.get(i); HashSet<Signature> set = new HashSet<Signature>(); try { Signature[] sigs = mPm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures; set.addAll(Arrays.asList(sigs)); mSignatureSets.add(set); } catch (NameNotFoundException e) { Log.w(logTag, pkg + " not found"); } } mSignatureSets = getSignatureSets(context, initialPackageNames); } public boolean start() { Loading Loading @@ -132,15 +137,16 @@ public class ServiceWatcher implements ServiceConnection { // check version int version = 0; if (rInfo.serviceInfo.metaData != null) { version = rInfo.serviceInfo.metaData.getInt(EXTRA_VERSION, 0); version = rInfo.serviceInfo.metaData.getInt(EXTRA_SERVICE_VERSION, 0); } if (version > mVersion) { bestVersion = version; bestPackage = packageName; } } if (D) Log.d(mTag, String.format("bindBestPackage %s found %d, %s", if (D) Log.d(mTag, String.format("bindBestPackage for %s : %s found %d, %s", mAction, (justCheckThisPackage == null ? "" : "(" + justCheckThisPackage + ") "), rInfos.size(), (bestPackage == null ? "no new best package" : "new best packge: " + bestPackage))); Loading Loading @@ -174,7 +180,8 @@ public class ServiceWatcher implements ServiceConnection { | Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_NOT_VISIBLE, mCurrentUserId); } private boolean isSignatureMatch(Signature[] signatures) { public static boolean isSignatureMatch(Signature[] signatures, List<HashSet<Signature>> sigSets) { if (signatures == null) return false; // build hashset of input to test against Loading @@ -184,7 +191,7 @@ public class ServiceWatcher implements ServiceConnection { } // test input against each of the signature sets for (HashSet<Signature> referenceSet : mSignatureSets) { for (HashSet<Signature> referenceSet : sigSets) { if (referenceSet.equals(inputSet)) { return true; } Loading @@ -192,6 +199,10 @@ public class ServiceWatcher implements ServiceConnection { return false; } private boolean isSignatureMatch(Signature[] signatures) { return isSignatureMatch(signatures, mSignatureSets); } private final PackageMonitor mPackageMonitor = new PackageMonitor() { /** * Called when package has been reinstalled Loading Loading
core/res/res/values/config.xml +1 −8 Original line number Diff line number Diff line Loading @@ -636,19 +636,12 @@ of new location providers at run-time. The new package does not have to be explicitly listed here, however it must have a signature that matches the signature of at least one package on this list. Platforms should overlay additional packages in config_overlay_locationProviderPackageNames, instead of overlaying this config, if they only want to append packages and not replace the entire array. --> <string-array name="config_locationProviderPackageNames" translatable="false"> <!-- The standard AOSP fused location provider --> <item>com.android.location.fused</item> </string-array> <!-- Pacakge name(s) supplied by overlay, and appended to config_locationProviderPackageNames. --> <string-array name="config_overlay_locationProviderPackageNames" translatable="false" /> <!-- Boolean indicating if current platform supports bluetooth SCO for off call use cases --> <bool name="config_bluetooth_sco_off_call">true</bool> Loading
core/res/res/values/symbols.xml +0 −1 Original line number Diff line number Diff line Loading @@ -1475,7 +1475,6 @@ <java-symbol type="array" name="radioAttributes" /> <java-symbol type="array" name="config_oemUsbModeOverride" /> <java-symbol type="array" name="config_locationProviderPackageNames" /> <java-symbol type="array" name="config_overlay_locationProviderPackageNames" /> <java-symbol type="bool" name="config_animateScreenLights" /> <java-symbol type="bool" name="config_automatic_brightness_available" /> <java-symbol type="bool" name="config_sf_limitedAlpha" /> Loading
packages/FusedLocation/AndroidManifest.xml +3 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.location.fused" coreApp="true"> coreApp="true" android:sharedUserId="android.uid.system"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> Loading @@ -39,7 +40,7 @@ <intent-filter> <action android:name="com.android.location.service.FusedLocationProvider" /> </intent-filter> <meta-data android:name="version" android:value="1" /> <meta-data android:name="serviceVersion" android:value="0" /> </service> </application> </manifest>
services/java/com/android/server/LocationManagerService.java +77 −7 Original line number Diff line number Diff line Loading @@ -23,8 +23,11 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.content.res.Resources; import android.database.ContentObserver; import android.location.Address; Loading Loading @@ -249,6 +252,74 @@ public class LocationManagerService extends ILocationManager.Stub implements Run updateProvidersLocked(); } private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) { PackageManager pm = mContext.getPackageManager(); String systemPackageName = mContext.getPackageName(); ArrayList<HashSet<Signature>> sigSets = ServiceWatcher.getSignatureSets(mContext, pkgs); List<ResolveInfo> rInfos = pm.queryIntentServicesAsUser( new Intent(FUSED_LOCATION_SERVICE_ACTION), PackageManager.GET_META_DATA, mCurrentUserId); for (ResolveInfo rInfo : rInfos) { String packageName = rInfo.serviceInfo.packageName; // Check that the signature is in the list of supported sigs. If it's not in // this list the standard provider binding logic won't bind to it. try { PackageInfo pInfo; pInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); if (!ServiceWatcher.isSignatureMatch(pInfo.signatures, sigSets)) { Log.w(TAG, packageName + " resolves service " + FUSED_LOCATION_SERVICE_ACTION + ", but has wrong signature, ignoring"); continue; } } catch (NameNotFoundException e) { Log.e(TAG, "missing package: " + packageName); continue; } // Get the version info if (rInfo.serviceInfo.metaData == null) { Log.w(TAG, "Found fused provider without metadata: " + packageName); continue; } int version = rInfo.serviceInfo.metaData.getInt( ServiceWatcher.EXTRA_SERVICE_VERSION, -1); if (version == 0) { // This should be the fallback fused location provider. // Make sure it's in the system partition. if ((rInfo.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { if (D) Log.d(TAG, "Fallback candidate not in /system: " + packageName); continue; } // Check that the fallback is signed the same as the OS // as a proxy for coreApp="true" if (pm.checkSignatures(systemPackageName, packageName) != PackageManager.SIGNATURE_MATCH) { if (D) Log.d(TAG, "Fallback candidate not signed the same as system: " + packageName); continue; } // Found a valid fallback. if (D) Log.d(TAG, "Found fallback provider: " + packageName); return; } else { if (D) Log.d(TAG, "Fallback candidate not version 0: " + packageName); } } throw new IllegalStateException("Unable to find a fused location provider that is in the " + "system partition with version 0 and signed with the platform certificate. " + "Such a package is needed to provide a default fused location provider in the " + "event that no other fused location provider has been installed or is currently " + "available. For example, coreOnly boot mode when decrypting the data " + "partition. The fallback must also be marked coreApp=\"true\" in the manifest"); } private void loadProvidersLocked() { // create a passive location provider, which is always enabled PassiveProvider passiveProvider = new PassiveProvider(this); Loading Loading @@ -278,14 +349,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ Resources resources = mContext.getResources(); ArrayList<String> providerPackageNames = new ArrayList<String>(); String[] pkgs1 = resources.getStringArray( String[] pkgs = resources.getStringArray( com.android.internal.R.array.config_locationProviderPackageNames); String[] pkgs2 = resources.getStringArray( com.android.internal.R.array.config_overlay_locationProviderPackageNames); if (D) Log.d(TAG, "built-in location providers: " + Arrays.toString(pkgs1)); if (D) Log.d(TAG, "overlay location providers: " + Arrays.toString(pkgs2)); if (pkgs1 != null) providerPackageNames.addAll(Arrays.asList(pkgs1)); if (pkgs2 != null) providerPackageNames.addAll(Arrays.asList(pkgs2)); if (D) Log.d(TAG, "certificates for location providers pulled from: " + Arrays.toString(pkgs)); if (pkgs != null) providerPackageNames.addAll(Arrays.asList(pkgs)); ensureFallbackFusedProviderPresentLocked(providerPackageNames); // bind to network provider LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind( Loading
services/java/com/android/server/ServiceWatcher.java +31 −20 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ import java.util.List; */ public class ServiceWatcher implements ServiceConnection { private static final boolean D = false; private static final String EXTRA_VERSION = "version"; public static final String EXTRA_SERVICE_VERSION = "serviceVersion"; private final String mTag; private final Context mContext; Loading @@ -58,9 +58,27 @@ public class ServiceWatcher implements ServiceConnection { // all fields below synchronized on mLock private IBinder mBinder; // connected service private String mPackageName; // current best package private int mVersion; // current best version private int mVersion = Integer.MIN_VALUE; // current best version private int mCurrentUserId; public static ArrayList<HashSet<Signature>> getSignatureSets(Context context, List<String> initialPackageNames) { PackageManager pm = context.getPackageManager(); ArrayList<HashSet<Signature>> sigSets = new ArrayList<HashSet<Signature>>(); for (int i = 0, size = initialPackageNames.size(); i < size; i++) { String pkg = initialPackageNames.get(i); try { HashSet<Signature> set = new HashSet<Signature>(); Signature[] sigs = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures; set.addAll(Arrays.asList(sigs)); sigSets.add(set); } catch (NameNotFoundException e) { Log.w("ServiceWatcher", pkg + " not found"); } } return sigSets; } public ServiceWatcher(Context context, String logTag, String action, List<String> initialPackageNames, Runnable newServiceWork, Handler handler, int userId) { mContext = context; Loading @@ -71,20 +89,7 @@ public class ServiceWatcher implements ServiceConnection { mHandler = handler; mCurrentUserId = userId; mSignatureSets = new ArrayList<HashSet<Signature>>(); for (int i=0; i < initialPackageNames.size(); i++) { String pkg = initialPackageNames.get(i); HashSet<Signature> set = new HashSet<Signature>(); try { Signature[] sigs = mPm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures; set.addAll(Arrays.asList(sigs)); mSignatureSets.add(set); } catch (NameNotFoundException e) { Log.w(logTag, pkg + " not found"); } } mSignatureSets = getSignatureSets(context, initialPackageNames); } public boolean start() { Loading Loading @@ -132,15 +137,16 @@ public class ServiceWatcher implements ServiceConnection { // check version int version = 0; if (rInfo.serviceInfo.metaData != null) { version = rInfo.serviceInfo.metaData.getInt(EXTRA_VERSION, 0); version = rInfo.serviceInfo.metaData.getInt(EXTRA_SERVICE_VERSION, 0); } if (version > mVersion) { bestVersion = version; bestPackage = packageName; } } if (D) Log.d(mTag, String.format("bindBestPackage %s found %d, %s", if (D) Log.d(mTag, String.format("bindBestPackage for %s : %s found %d, %s", mAction, (justCheckThisPackage == null ? "" : "(" + justCheckThisPackage + ") "), rInfos.size(), (bestPackage == null ? "no new best package" : "new best packge: " + bestPackage))); Loading Loading @@ -174,7 +180,8 @@ public class ServiceWatcher implements ServiceConnection { | Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_NOT_VISIBLE, mCurrentUserId); } private boolean isSignatureMatch(Signature[] signatures) { public static boolean isSignatureMatch(Signature[] signatures, List<HashSet<Signature>> sigSets) { if (signatures == null) return false; // build hashset of input to test against Loading @@ -184,7 +191,7 @@ public class ServiceWatcher implements ServiceConnection { } // test input against each of the signature sets for (HashSet<Signature> referenceSet : mSignatureSets) { for (HashSet<Signature> referenceSet : sigSets) { if (referenceSet.equals(inputSet)) { return true; } Loading @@ -192,6 +199,10 @@ public class ServiceWatcher implements ServiceConnection { return false; } private boolean isSignatureMatch(Signature[] signatures) { return isSignatureMatch(signatures, mSignatureSets); } private final PackageMonitor mPackageMonitor = new PackageMonitor() { /** * Called when package has been reinstalled Loading