field public static final java.lang.String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
}
+ public static final class Settings.Global extends android.provider.Settings.NameValueTable {
+ field public static final java.lang.String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
+ }
+
public static final class Settings.Secure extends android.provider.Settings.NameValueTable {
field public static final java.lang.String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED = "accessibility_display_magnification_enabled";
field public static final java.lang.String AUTOFILL_FEATURE_FIELD_CLASSIFICATION = "autofill_field_classification";
public abstract void setSimCallManagerPackagesProvider(PackagesProvider provider);
/**
+ * Sets the Use Open Wifi packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
+
+ /**
* Sets the sync adapter packages provider.
* @param provider The provider.
*/
int userId);
/**
+ * Requests granting of the default permissions to the current default Use Open Wifi app.
+ * @param packageName The default use open wifi package name.
+ * @param userId The user for which to grant the permissions.
+ */
+ public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName,
+ int userId);
+
+ /**
* Sets a list of apps to keep in PM's internal data structures and as APKs even if no user has
* currently installed it. The apps are not preloaded.
* @param packageList List of package names to keep cached.
* Type: string package name or null if the feature is either not provided or disabled.
* @hide
*/
+ @TestApi
public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
/**
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver;
import android.location.LocationManager;
import android.net.INetworkRecommendationProvider;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings.Global;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.IntArray;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.TransferPipe;
+import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
private final Object mPackageMonitorLock = new Object();
private final Object mServiceConnectionLock = new Object();
private final Handler mHandler;
- private final DispatchingContentObserver mContentObserver;
+ private final DispatchingContentObserver mRecommendationSettingsObserver;
+ private final ContentObserver mUseOpenWifiPackageObserver;
private final Function<NetworkScorerAppData, ScoringServiceConnection> mServiceConnProducer;
@GuardedBy("mPackageMonitorLock")
mContext.registerReceiverAsUser(
mLocationModeReceiver, UserHandle.SYSTEM, locationModeFilter,
null /* broadcastPermission*/, mHandler);
- mContentObserver = new DispatchingContentObserver(context, mHandler);
+ mRecommendationSettingsObserver = new DispatchingContentObserver(context, mHandler);
mServiceConnProducer = serviceConnProducer;
+ mUseOpenWifiPackageObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ Uri useOpenWifiPkgUri = Global.getUriFor(Global.USE_OPEN_WIFI_PACKAGE);
+ if (useOpenWifiPkgUri.equals(uri)) {
+ String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
+ Global.USE_OPEN_WIFI_PACKAGE);
+ if (!TextUtils.isEmpty(useOpenWifiPackage)) {
+ LocalServices.getService(PackageManagerInternal.class)
+ .grantDefaultPermissionsToDefaultUseOpenWifiApp(useOpenWifiPackage,
+ userId);
+ }
+ }
+ }
+ };
+ mContext.getContentResolver().registerContentObserver(
+ Global.getUriFor(Global.USE_OPEN_WIFI_PACKAGE),
+ false /*notifyForDescendants*/,
+ mUseOpenWifiPackageObserver);
+ // Set a callback for the package manager to query the use open wifi app.
+ LocalServices.getService(PackageManagerInternal.class).setUseOpenWifiAppPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
+ Global.USE_OPEN_WIFI_PACKAGE);
+ if (!TextUtils.isEmpty(useOpenWifiPackage)) {
+ return new String[]{useOpenWifiPackage};
+ }
+ return null;
+ }
+ });
}
/** Called when the system is ready to run third-party code but before it actually does so. */
private void registerRecommendationSettingsObserver() {
final Uri packageNameUri = Global.getUriFor(Global.NETWORK_RECOMMENDATIONS_PACKAGE);
- mContentObserver.observe(packageNameUri,
+ mRecommendationSettingsObserver.observe(packageNameUri,
ServiceHandler.MSG_RECOMMENDATIONS_PACKAGE_CHANGED);
final Uri settingUri = Global.getUriFor(Global.NETWORK_RECOMMENDATIONS_ENABLED);
- mContentObserver.observe(settingUri,
+ mRecommendationSettingsObserver.observe(settingUri,
ServiceHandler.MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED);
}
}
@Override
+ public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
+ mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
+ }
+
+ @Override
public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
}
}
@Override
+ public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
+ packageName, userId);
+ }
+
+ @Override
public void setKeepUninstalledPackages(final List<String> packageList) {
Preconditions.checkNotNull(packageList);
List<String> removedFromList = null;
LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
+ private static final Set<String> COARSE_LOCATION_PERMISSIONS = new ArraySet<>();
+ static {
+ COARSE_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
+
private static final Set<String> CALENDAR_PERMISSIONS = new ArraySet<>();
static {
CALENDAR_PERMISSIONS.add(Manifest.permission.READ_CALENDAR);
private PackagesProvider mSmsAppPackagesProvider;
private PackagesProvider mDialerAppPackagesProvider;
private PackagesProvider mSimCallManagerPackagesProvider;
+ private PackagesProvider mUseOpenWifiAppPackagesProvider;
private SyncAdapterPackagesProvider mSyncAdapterPackagesProvider;
private ArrayMap<String, List<DefaultPermissionGrant>> mGrantExceptions;
}
}
+ public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mUseOpenWifiAppPackagesProvider = provider;
+ }
+ }
+
public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
synchronized (mLock) {
mSyncAdapterPackagesProvider = provider;
final PackagesProvider smsAppPackagesProvider;
final PackagesProvider dialerAppPackagesProvider;
final PackagesProvider simCallManagerPackagesProvider;
+ final PackagesProvider useOpenWifiAppPackagesProvider;
final SyncAdapterPackagesProvider syncAdapterPackagesProvider;
synchronized (mLock) {
smsAppPackagesProvider = mSmsAppPackagesProvider;
dialerAppPackagesProvider = mDialerAppPackagesProvider;
simCallManagerPackagesProvider = mSimCallManagerPackagesProvider;
+ useOpenWifiAppPackagesProvider = mUseOpenWifiAppPackagesProvider;
syncAdapterPackagesProvider = mSyncAdapterPackagesProvider;
}
? dialerAppPackagesProvider.getPackages(userId) : null;
String[] simCallManagerPackageNames = (simCallManagerPackagesProvider != null)
? simCallManagerPackagesProvider.getPackages(userId) : null;
+ String[] useOpenWifiAppPackageNames = (useOpenWifiAppPackagesProvider != null)
+ ? useOpenWifiAppPackagesProvider.getPackages(userId) : null;
String[] contactsSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
syncAdapterPackagesProvider.getPackages(ContactsContract.AUTHORITY, userId) : null;
String[] calendarSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
}
}
+ // Use Open Wifi
+ if (useOpenWifiAppPackageNames != null) {
+ for (String useOpenWifiPackageName : useOpenWifiAppPackageNames) {
+ PackageParser.Package useOpenWifiPackage =
+ getSystemPackage(useOpenWifiPackageName);
+ if (useOpenWifiPackage != null) {
+ grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(useOpenWifiPackage,
+ userId);
+ }
+ }
+ }
+
// SMS
if (smsAppPackageNames == null) {
Intent smsIntent = new Intent(Intent.ACTION_MAIN);
}
}
+ private void grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(
+ PackageParser.Package useOpenWifiPackage, int userId) {
+ if (doesPackageSupportRuntimePermissions(useOpenWifiPackage)) {
+ grantRuntimePermissions(useOpenWifiPackage, COARSE_LOCATION_PERMISSIONS, userId);
+ }
+ }
+
public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
Log.i(TAG, "Granting permissions to default sms app for user:" + userId);
if (packageName == null) {
}
}
+ public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
+ Log.i(TAG, "Granting permissions to default Use Open WiFi app for user:" + userId);
+ if (packageName == null) {
+ return;
+ }
+ PackageParser.Package useOpenWifiPackage = getPackage(packageName);
+ if (useOpenWifiPackage != null
+ && doesPackageSupportRuntimePermissions(useOpenWifiPackage)) {
+ grantRuntimePermissions(
+ useOpenWifiPackage, COARSE_LOCATION_PERMISSIONS, false, true, userId);
+ }
+ }
+
private void grantDefaultPermissionsToDefaultSimCallManager(
PackageParser.Package simCallManagerPackage, int userId) {
Log.i(TAG, "Granting permissions to sim call manager for user:" + userId);
}
private void grantRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
- boolean systemFixed, boolean isDefaultPhoneOrSms, int userId) {
+ boolean systemFixed, boolean ignoreSystemPackage, int userId) {
if (pkg.requestedPermissions.isEmpty()) {
return;
}
List<String> requestedPermissions = pkg.requestedPermissions;
Set<String> grantablePermissions = null;
- // If this is the default Phone or SMS app we grant permissions regardless
- // whether the version on the system image declares the permission as used since
- // selecting the app as the default Phone or SMS the user makes a deliberate
+ // In some cases, like for the Phone or SMS app, we grant permissions regardless
+ // of if the version on the system image declares the permission as used since
+ // selecting the app as the default for that function the user makes a deliberate
// choice to grant this app the permissions needed to function. For all other
// apps, (default grants on first boot and user creation) we don't grant default
// permissions if the version on the system image does not declare them.
- if (!isDefaultPhoneOrSms && pkg.isUpdatedSystemApp()) {
+ if (!ignoreSystemPackage && pkg.isUpdatedSystemApp()) {
final PackageParser.Package disabledPkg =
mServiceInternal.getDisabledPackage(pkg.packageName);
if (disabledPkg != null) {
// Unless the caller wants to override user choices. The override is
// to make sure we can grant the needed permission to the default
// sms and phone apps after the user chooses this in the UI.
- if (flags == 0 || isDefaultPhoneOrSms) {
+ if (flags == 0 || ignoreSystemPackage) {
// Never clobber policy or system.
final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
| PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static junit.framework.Assert.fail;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.net.INetworkRecommendationProvider;
import android.net.INetworkScoreCache;
import android.net.NetworkKey;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.Settings;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
@Mock private UnaryOperator<List<ScoredNetwork>> mScanResultsFilter;
@Mock private WifiInfo mWifiInfo;
@Mock private NetworkScoreService.ScoringServiceConnection mServiceConnection;
+ @Mock private PackageManagerInternal mPackageManagerInternal;
@Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
+ @Captor private ArgumentCaptor<PackageManagerInternal.PackagesProvider> mPackagesProviderCaptor;
private ContentResolver mContentResolver;
private NetworkScoreService mNetworkScoreService;
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
mHandlerThread.start();
+ LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager,
networkScorerAppData -> mServiceConnection, mHandlerThread.getLooper());
WifiConfiguration configuration = new WifiConfiguration();
@After
public void tearDown() throws Exception {
mHandlerThread.quitSafely();
+ LocalServices.removeServiceForTest(PackageManagerInternal.class);
+ }
+
+ @Test
+ public void testConstructor_setsUseOpenWifiPackagesProvider() {
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.app");
+
+ verify(mPackageManagerInternal)
+ .setUseOpenWifiAppPackagesProvider(mPackagesProviderCaptor.capture());
+
+ String[] packages = mPackagesProviderCaptor.getValue().getPackages(0);
+ assertEquals(1, packages.length);
+ assertEquals("com.some.app", packages[0]);
+ }
+
+ @Test
+ public void testConstructor_registersUseOpenWifiPackageContentObserver() {
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.other.app");
+
+ verify(mPackageManagerInternal, timeout(500))
+ .grantDefaultPermissionsToDefaultUseOpenWifiApp("com.some.other.app", 0);
}
@Test
}
private static class CountDownHandler extends Handler {
- CountDownLatch latch = new CountDownLatch(1);
- int receivedWhat;
+ final CountDownLatch latch = new CountDownLatch(1);
+ volatile int receivedWhat;
CountDownHandler(Looper looper) {
super(looper);
@Override
public void handleMessage(Message msg) {
- latch.countDown();
receivedWhat = msg.what;
+ latch.countDown();
}
}
}