Merge "Disabling the activate button when paused" into oc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b9c0f9f..c596152 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -81,6 +81,7 @@
<uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/>
<uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.DELETE_PACKAGES"/>
+ <uses-permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS"/>
<application android:label="@string/settings_label"
android:icon="@drawable/ic_launcher_settings"
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index e063d13..77063bd 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -24,7 +24,7 @@
android:key="location_mode"
android:title="@string/location_mode_title"
settings:keywords="@string/keywords_location_mode"
- android:summary="@string/location_mode_location_off_title" />
+ android:summary="@string/summary_placeholder" />
<!-- This preference category gets removed if there is no managed profile -->
<com.android.settingslib.RestrictedSwitchPreference
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 0142ea2..9655fd2 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -25,6 +25,7 @@
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AppGlobals;
+import android.app.AppOpsManager;
import android.app.Dialog;
import android.app.Fragment;
import android.app.IActivityManager;
@@ -1272,6 +1273,22 @@
return info.enabled ? R.string.installed : R.string.disabled;
}
+ /**
+ * Control if other apps can display overlays. By default this is allowed. Be sure to
+ * re-enable overlays, as the effect is system-wide.
+ */
+ public static void setOverlayAllowed(Context context, IBinder token, boolean allowed) {
+ AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+ if (appOpsManager != null) {
+ appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
+ !allowed, token);
+ appOpsManager.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW,
+ !allowed, token);
+ }
+ }
+
+
+
private static boolean isVolumeValid(VolumeInfo volume) {
return (volume != null) && (volume.getType() == VolumeInfo.TYPE_PRIVATE)
&& volume.isMountedReadable();
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index e0c58db..e0d2c69 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -48,14 +48,14 @@
.setTitle(parentActivity.getString(R.string.enable_service_title,
getServiceName(parentActivity, info)))
.setView(createEnableDialogContentView(parentActivity, info))
- .setCancelable(true)
.setPositiveButton(android.R.string.ok, listener)
.setNegativeButton(android.R.string.cancel, listener)
.create();
final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
// Filter obscured touches by consuming them.
- if ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0) {
+ if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
+ || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
if (event.getAction() == MotionEvent.ACTION_UP) {
Toast.makeText(v.getContext(), R.string.touch_filtered_warning,
Toast.LENGTH_SHORT).show();
@@ -67,6 +67,8 @@
ad.create();
ad.getButton(AlertDialog.BUTTON_POSITIVE).setOnTouchListener(filterTouchListener);
+ ad.setCanceledOnTouchOutside(true);
+
return ad;
}
diff --git a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
index d7749ea..38e6b0f 100644
--- a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
+++ b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
@@ -17,25 +17,24 @@
import static android.content.DialogInterface.BUTTON_POSITIVE;
+import static com.android.settings.Utils.setOverlayAllowed;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
-import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.ComponentName;
import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
+import android.os.Binder;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
-import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.DialogCreatable;
import com.android.settings.applications.defaultapps.DefaultAppInfo;
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
@@ -118,6 +117,7 @@
implements DialogInterface.OnClickListener {
private static final String EXTRA_KEY = "extra_key";
private static final String TAG = "ConfirmationDialogFragment";
+ private IBinder mToken;
public static ConfirmationDialogFragment newInstance(ShortcutServicePickerFragment parent,
String key) {
@@ -126,6 +126,7 @@
argument.putString(EXTRA_KEY, key);
fragment.setArguments(argument);
fragment.setTargetFragment(parent, 0);
+ fragment.mToken = new Binder();
return fragment;
}
@@ -147,6 +148,22 @@
}
@Override
+ public void onResume() {
+ super.onResume();
+ if (mToken != null) {
+ setOverlayAllowed(getActivity(), mToken, false);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mToken != null) {
+ setOverlayAllowed(getActivity(), mToken, true);
+ }
+ }
+
+ @Override
public void onClick(DialogInterface dialog, int which) {
final Fragment fragment = getTargetFragment();
if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) {
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index 9c01a5f..da4bdcf 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -16,34 +16,30 @@
package com.android.settings.accessibility;
+import static com.android.settings.Utils.setOverlayAllowed;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.text.TextUtils;
-import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
import android.view.accessibility.AccessibilityManager;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
@@ -77,6 +73,8 @@
private int mShownDialogId;
+ private final IBinder mToken = new Binder();
+
@Override
public int getMetricsCategory() {
return MetricsEvent.ACCESSIBILITY_SERVICE;
@@ -107,12 +105,18 @@
public void onResume() {
mSettingsContentObserver.register(getContentResolver());
updateSwitchBarToggleSwitch();
+ if (mToken != null) {
+ setOverlayAllowed(getActivity(), mToken, false);
+ }
super.onResume();
}
@Override
public void onPause() {
mSettingsContentObserver.unregister(getContentResolver());
+ if (mToken != null) {
+ setOverlayAllowed(getActivity(), mToken, true);
+ }
super.onPause();
}
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index be3bdfa..76129b7 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -418,14 +418,14 @@
mFilterAdapter.enableFilter(FILTER_APPS_POWER_WHITELIST_ALL);
}
- AppFilter overrideFilter = getOverrideFilter(mListType, mStorageType, mVolumeUuid);
- if (overrideFilter != null) {
- mApplications.setOverrideFilter(overrideFilter);
+ AppFilter compositeFilter = getCompositeFilter(mListType, mStorageType, mVolumeUuid);
+ if (compositeFilter != null) {
+ mApplications.setCompositeFilter(compositeFilter);
}
}
@VisibleForTesting
- static @Nullable AppFilter getOverrideFilter(int listType, int storageType, String volumeUuid) {
+ static @Nullable AppFilter getCompositeFilter(int listType, int storageType, String volumeUuid) {
AppFilter filter = new VolumeFilter(volumeUuid);
if (listType == LIST_TYPE_STORAGE) {
if (storageType == STORAGE_TYPE_MUSIC) {
@@ -845,7 +845,7 @@
private int mWhichSize = SIZE_TOTAL;
CharSequence mCurFilterPrefix;
private PackageManager mPm;
- private AppFilter mOverrideFilter;
+ private AppFilter mCompositeFilter;
private boolean mHasReceivedLoadEntries;
private boolean mHasReceivedBridgeCallback;
private FileViewHolderController mExtraViewController;
@@ -909,8 +909,8 @@
}
}
- public void setOverrideFilter(AppFilter overrideFilter) {
- mOverrideFilter = overrideFilter;
+ public void setCompositeFilter(AppFilter compositeFilter) {
+ mCompositeFilter = compositeFilter;
rebuild(true);
}
@@ -988,8 +988,8 @@
mWhichSize = SIZE_INTERNAL;
}
filterObj = FILTERS[mFilterMode];
- if (mOverrideFilter != null) {
- filterObj = mOverrideFilter;
+ if (mCompositeFilter != null) {
+ filterObj = new CompoundFilter(filterObj, mCompositeFilter);
}
if (!mManageApplications.mShowSystem) {
if (LIST_TYPES_WITH_INSTANT.contains(mManageApplications.mListType)) {
diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
index 38fed94..7dacaf5 100644
--- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java
+++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
@@ -395,7 +395,10 @@
int wifiApState = wifiManager.getWifiApState();
if (desiredState && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
(wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
- wifiManager.setWifiApEnabled(null, false);
+ final ConnectivityManager connectivityManager =
+ (ConnectivityManager) context.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ connectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
}
wifiManager.setWifiEnabled(desiredState);
diff --git a/tests/unit/src/com/android/settings/applications/ManageApplicationsTest.java b/tests/unit/src/com/android/settings/applications/ManageApplicationsTest.java
index 92e556e..d207701 100644
--- a/tests/unit/src/com/android/settings/applications/ManageApplicationsTest.java
+++ b/tests/unit/src/com/android/settings/applications/ManageApplicationsTest.java
@@ -22,16 +22,20 @@
import android.content.pm.ApplicationInfo;
+import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppFilter;
+import com.android.settingslib.applications.ApplicationsState.CompoundFilter;
+import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
+import java.lang.reflect.Field;
import org.junit.Test;
public class ManageApplicationsTest {
@Test
- public void getOverrideFilter_filtersVolumeForAudio() {
+ public void getCompositeFilter_filtersVolumeForAudio() {
AppFilter filter =
- ManageApplications.getOverrideFilter(
+ ManageApplications.getCompositeFilter(
ManageApplications.LIST_TYPE_STORAGE,
ManageApplications.STORAGE_TYPE_MUSIC,
"uuid");
@@ -45,9 +49,9 @@
}
@Test
- public void getOverrideFilter_filtersVolumeForVideo() {
+ public void getCompositeFilter_filtersVolumeForVideo() {
AppFilter filter =
- ManageApplications.getOverrideFilter(
+ ManageApplications.getCompositeFilter(
ManageApplications.LIST_TYPE_MOVIES,
ManageApplications.STORAGE_TYPE_DEFAULT,
"uuid");
@@ -61,9 +65,9 @@
}
@Test
- public void getOverrideFilter_filtersVolumeForGames() {
+ public void getCompositeFilter_filtersVolumeForGames() {
ApplicationsState.AppFilter filter =
- ManageApplications.getOverrideFilter(
+ ManageApplications.getCompositeFilter(
ManageApplications.LIST_TYPE_GAMES,
ManageApplications.STORAGE_TYPE_DEFAULT,
"uuid");
@@ -77,12 +81,35 @@
}
@Test
- public void getOverrideFilter_isEmptyNormally() {
+ public void getCompositeFilter_isEmptyNormally() {
ApplicationsState.AppFilter filter =
- ManageApplications.getOverrideFilter(
+ ManageApplications.getCompositeFilter(
ManageApplications.LIST_TYPE_MAIN,
ManageApplications.STORAGE_TYPE_DEFAULT,
"uuid");
assertThat(filter).isNull();
}
+
+ @Test
+ public void getCompositeFilter_worksWithInstantApps() throws Exception {
+ Field field = AppUtils.class.getDeclaredField("sInstantAppDataProvider");
+ field.setAccessible(true);
+ field.set(AppUtils.class, (InstantAppDataProvider) (i -> true));
+
+ AppFilter filter =
+ ManageApplications.getCompositeFilter(
+ ManageApplications.LIST_TYPE_STORAGE,
+ ManageApplications.STORAGE_TYPE_MUSIC,
+ "uuid");
+ AppFilter composedFilter = new CompoundFilter(ApplicationsState.FILTER_INSTANT, filter);
+
+ final ApplicationInfo info = new ApplicationInfo();
+ info.volumeUuid = "uuid";
+ info.category = ApplicationInfo.CATEGORY_AUDIO;
+ info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
+ final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
+ appEntry.info = info;
+
+ assertThat(composedFilter.filterApp(appEntry)).isTrue();
+ }
}