NetworkScorerAppManager.java revision 161977998feebf0a855ea56558464470877040cf
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright (C) 2014 The Android Open Source Project 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * you may not use this file except in compliance with the License. 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * You may obtain a copy of the License at 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * See the License for the specific language governing permissions and 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * limitations under the License 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package android.net; 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.Manifest; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.Manifest.permission; 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport android.annotation.Nullable; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.app.AppOpsManager; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.Context; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.Intent; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.pm.ActivityInfo; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.pm.PackageManager; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.pm.ResolveInfo; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.os.UserHandle; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.provider.Settings; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.text.TextUtils; 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.util.Log; 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import java.util.ArrayList; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import java.util.Collection; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import java.util.List; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Internal class for managing the primary network scorer application. 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * TODO: Rename this to something more generic. 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @hide 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public final class NetworkScorerAppManager { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static final String TAG = "NetworkScorerAppManager"; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static final Intent SCORE_INTENT = 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** This class cannot be instantiated. */ 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private NetworkScorerAppManager() {} 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static class NetworkScorerAppData { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** Package name of this scorer app. */ 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public final String mPackageName; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** Name of this scorer app for display. */ 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public final CharSequence mScorerName; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Optional class name of a configuration activity. Null if none is set. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @see NetworkScoreManager#ACTION_CUSTOM_ENABLE 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public final String mConfigurationActivityClassName; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public NetworkScorerAppData(String packageName, CharSequence scorerName, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Nullable String configurationActivityClassName) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mScorerName = scorerName; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mPackageName = packageName; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mConfigurationActivityClassName = configurationActivityClassName; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns the list of available scorer apps. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * <p>A network scorer is any application which: 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * <ul> 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * <li>Includes a receiver for {@link NetworkScoreManager#ACTION_SCORE_NETWORKS} guarded by the 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission. 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * </ul> 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return the list of scorers, or the empty list if there are no valid scorers. 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public static Collection<NetworkScorerAppData> getAllValidScorers(Context context) { 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) List<NetworkScorerAppData> scorers = new ArrayList<>(); 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) PackageManager pm = context.getPackageManager(); 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Only apps installed under the primary user of the device can be scorers. 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) List<ResolveInfo> receivers = 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pm.queryBroadcastReceivers(SCORE_INTENT, 0 /* flags */, UserHandle.USER_OWNER); 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (ResolveInfo receiver : receivers) { 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // This field is a misnomer, see android.content.pm.ResolveInfo#activityInfo 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) final ActivityInfo receiverInfo = receiver.activityInfo; 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (receiverInfo == null) { 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Should never happen with queryBroadcastReceivers, but invalid nonetheless. 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) continue; 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!permission.BROADCAST_NETWORK_PRIVILEGED.equals(receiverInfo.permission)) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Receiver doesn't require the BROADCAST_NETWORK_PRIVILEGED permission, which means 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // anyone could trigger network scoring and flood the framework with score requests. 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pm.checkPermission(permission.SCORE_NETWORKS, receiverInfo.packageName) != 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PackageManager.PERMISSION_GRANTED) { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Application doesn't hold the SCORE_NETWORKS permission, so the user never 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // approved it as a network scorer. 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Optionally, this package may specify a configuration activity. 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) String configurationActivityClassName = null; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Intent intent = new Intent(NetworkScoreManager.ACTION_CUSTOM_ENABLE); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) intent.setPackage(receiverInfo.packageName); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) List<ResolveInfo> configActivities = pm.queryIntentActivities(intent, 0 /* flags */); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!configActivities.isEmpty()) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ActivityInfo activityInfo = configActivities.get(0).activityInfo; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (activityInfo != null) { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) configurationActivityClassName = activityInfo.name; 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // NOTE: loadLabel will attempt to load the receiver's label and fall back to the app 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // label if none is present. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scorers.add(new NetworkScorerAppData(receiverInfo.packageName, 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) receiverInfo.loadLabel(pm), configurationActivityClassName)); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scorers; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Get the application to use for scoring networks. 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return the scorer app info or null if scoring is disabled (including if no scorer was ever 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * it was disabled or uninstalled). 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static NetworkScorerAppData getActiveScorer(Context context) { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) String scorerPackage = Settings.Global.getString(context.getContentResolver(), 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Settings.Global.NETWORK_SCORER_APP); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getScorer(context, scorerPackage); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Set the specified package as the default scorer application. 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * <p>The caller must have permission to write to {@link android.provider.Settings.Global}. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param context the context of the calling application 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param packageName the packageName of the new scorer to use. If null, scoring will be 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * disabled. Otherwise, the scorer will only be set if it is a valid scorer application. 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return true if the scorer was changed, or false if the package is not a valid scorer. 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static boolean setActiveScorer(Context context, String packageName) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) String oldPackageName = Settings.Global.getString(context.getContentResolver(), 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Settings.Global.NETWORK_SCORER_APP); 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (TextUtils.equals(oldPackageName, packageName)) { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No change. 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (packageName == null) { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Settings.Global.putString(context.getContentResolver(), 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Settings.Global.NETWORK_SCORER_APP, null); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We only make the change if the new package is valid. 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (getScorer(context, packageName) != null) { 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Settings.Global.putString(context.getContentResolver(), 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Settings.Global.NETWORK_SCORER_APP, packageName); 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.w(TAG, "Requested network scorer is not valid: " + packageName); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** Determine whether the application with the given UID is the enabled scorer. */ 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static boolean isCallerActiveScorer(Context context, int callingUid) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetworkScorerAppData defaultApp = getActiveScorer(context); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (defaultApp == null) { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try { 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) appOpsMgr.checkPackage(callingUid, defaultApp.mPackageName); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } catch (SecurityException e) { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should, since it couldn't become the active scorer otherwise, but this can't hurt. 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return context.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) == 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PackageManager.PERMISSION_GRANTED; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** Returns the {@link NetworkScorerAppData} for the given app, or null if it's not a scorer. */ 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static NetworkScorerAppData getScorer(Context context, String packageName) { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (TextUtils.isEmpty(packageName)) { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return null; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Collection<NetworkScorerAppData> applications = getAllValidScorers(context); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (NetworkScorerAppData app : applications) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (packageName.equals(app.mPackageName)) { 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return app; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return null; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)