From e3f94f6926295fe7217186163ec2d2c264ffacfd Mon Sep 17 00:00:00 2001
From: Bill Yi
Date: Tue, 18 Sep 2018 12:56:34 -0700
Subject: [PATCH 1/6] Import translations. DO NOT MERGE
Change-Id: Ib3aeafee3272f1adf99daac0b15f8dff71867ec3
Auto-generated-cl: translation import
---
res/values-ja/strings.xml | 8 ++++----
res/values-pt-rBR/strings.xml | 1 +
res/values-pt/strings.xml | 1 +
res/values-uz/strings.xml | 8 ++++----
res/values-vi/strings.xml | 4 ++--
5 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 2157034d88c..7e2724d2d0e 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -1123,8 +1123,8 @@
"電池使用量が増えます"
"周囲に合わせて明るさを最適化します。この機能が ON の場合でも、一時的に明るさを調整できます。"
"画面の明るさは環境やアクティビティに応じて自動的に調整されます。スライダーを手動で動かして、明るさの自動調節機能に設定を学習させることもできます。"
- "ナイトライト"
- "読書灯を利用すると画面が黄味がかった色になります。薄明かりの下でも画面を見やすくなり、寝付きを良くする効果も期待できます。"
+ "夜間モード"
+ "夜間モードを利用すると画面が黄味がかった色になります。薄明かりの下でも画面を見やすくなり、寝付きを良くする効果も期待できます。"
"スケジュール"
"使用しない"
"指定した時間に ON"
@@ -3753,9 +3753,9 @@
"スマートフォンはバイブレーションに設定されています"
"着信と通知を端末のバイブレーションで知らせます"
"着信と通知をスマートフォンのバイブレーションで知らせます"
- "読書灯のスケジュールの設定"
+ "夜間モードのスケジュールの設定"
"夜間に画面の色みを自動的に変えて見やすくします"
- "読書灯 ON"
+ "夜間モード ON"
"画面が黄味がかった色になります。寝付きを良くする効果も期待できます。"
"おすすめ"
"候補"
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
index e43671b5a1b..b1a2e712a30 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -399,6 +399,7 @@
"Ok"
"Tempo máximo para registro de rostos atingido. Tente novamente."
"O registro de rostos não funcionou."
+ "Tudo pronto. E bonito."
"Concluído"
"Usar seu rosto para"
"Desbloquear o disp."
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index e43671b5a1b..b1a2e712a30 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -399,6 +399,7 @@
"Ok"
"Tempo máximo para registro de rostos atingido. Tente novamente."
"O registro de rostos não funcionou."
+ "Tudo pronto. E bonito."
"Concluído"
"Usar seu rosto para"
"Desbloquear o disp."
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index bcd8b3a946d..953ee9e7b09 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -1697,7 +1697,7 @@
"Qo‘shimcha sozlamalar tanlamalarini yoqib qo‘yish"
"Ilova haqida"
"Xotira"
- "Birlamchi ilova"
+ "Odatiy tarzda ochish"
"Birlamchi"
"Ekrandagi moslashuv"
"Ruxsatlar"
@@ -3449,9 +3449,9 @@
"IMEI kod ma’lumotlari"
"IMEI raqamiga aloqador ma’lumotlar"
"(%1$d-uya)"
- "Birlamchi ilova"
+ "Odatiy tarzda ochish"
"Havolalarni ochish"
- "Mos havolalar ochilsin"
+ "Mos havolalarni ochish"
"Avtomatik ochilsin"
"Mos havolalar"
"Boshqa birlamchi sozlamalar"
@@ -3520,7 +3520,7 @@
- Mos havolalarni %d ta ilovada ochish mumkin
- Mos havolalarni bitta ilovada ochish mumkin
- "Ushbu ilovada ochilsin"
+ "Shu ilovada ochish"
"Har safar so‘ralsin"
"Bu ilovada ochilmasin"
"Barmoq izi aniqlanmadi"
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 159d086ccd5..68e174fadd2 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -3632,8 +3632,8 @@
"Tần suất"
"Mức sử dụng tối đa"
"Không có dữ liệu nào được sử dụng"
- "Cho phép truy cập vào Không làm phiền cho %1$s?"
- "Ứng dụng có thể bật/tắt Không làm phiền và thực hiện thay đổi đối với các cài đặt liên quan."
+ "Cho phép %1$s truy cập chế độ Không làm phiền?"
+ "Ứng dụng có thể bật/tắt chế độ Không làm phiền và thay đổi các mục cài đặt liên quan."
"Phải luôn bật vì quyền truy cập thông báo được bật"
"Thu hồi quyền truy cập vào chế độ Không làm phiền của %1$s?"
"Mọi quy tắc Không làm phiền do ứng dụng này tạo sẽ đều bị xóa."
From 1bf730093c5460d3d93749bc151e9d3199edea48 Mon Sep 17 00:00:00 2001
From: jackqdyulei
Date: Tue, 18 Sep 2018 15:07:49 -0700
Subject: [PATCH 2/6] Fix incorrect API invoke for BT profiles
When hearing aid device has been set active, we shouldn't invoke
1. a2dpProfile.setActiveDevice()
2. hfpProfile.setActiveDevice()
Change-Id: Ie13dea041dd98d0cb9d913e1f28574b300095db9
Fixes: 113625278
Test: RunSettingsRoboTests
---
.../sound/HandsFreeProfileOutputPreferenceController.java | 7 ++-----
.../settings/sound/MediaOutputPreferenceController.java | 7 ++-----
.../HandsFreeProfileOutputPreferenceControllerTest.java | 3 +++
.../sound/MediaOutputPreferenceControllerTest.java | 3 +++
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java b/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java
index 0b50f5f2d75..a02c0b28b13 100644
--- a/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java
+++ b/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java
@@ -93,12 +93,9 @@ public class HandsFreeProfileOutputPreferenceController extends
if (hapProfile != null && hfpProfile != null && device == null) {
hfpProfile.setActiveDevice(null);
hapProfile.setActiveDevice(null);
- return;
- }
- if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
+ } else if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
hapProfile.setActiveDevice(device);
- }
- if (hfpProfile != null) {
+ } else if (hfpProfile != null) {
hfpProfile.setActiveDevice(device);
}
}
diff --git a/src/com/android/settings/sound/MediaOutputPreferenceController.java b/src/com/android/settings/sound/MediaOutputPreferenceController.java
index 8704243582c..2ac460cf61c 100644
--- a/src/com/android/settings/sound/MediaOutputPreferenceController.java
+++ b/src/com/android/settings/sound/MediaOutputPreferenceController.java
@@ -106,12 +106,9 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
if (hapProfile != null && a2dpProfile != null && device == null) {
hapProfile.setActiveDevice(null);
a2dpProfile.setActiveDevice(null);
- return;
- }
- if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
+ } else if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
hapProfile.setActiveDevice(device);
- }
- if (a2dpProfile != null) {
+ } else if (a2dpProfile != null) {
a2dpProfile.setActiveDevice(device);
}
}
diff --git a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
index e2fc779e201..58df2d2014d 100644
--- a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
@@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -179,6 +180,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
mController.setActiveBluetoothDevice(mLeftBluetoothHapDevice);
verify(mHearingAidProfile).setActiveDevice(mLeftBluetoothHapDevice);
+ verify(mHeadsetProfile, never()).setActiveDevice(mLeftBluetoothHapDevice);
}
/**
@@ -192,6 +194,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
mController.setActiveBluetoothDevice(mBluetoothDevice);
verify(mHeadsetProfile).setActiveDevice(mBluetoothDevice);
+ verify(mHearingAidProfile, never()).setActiveDevice(mBluetoothDevice);
}
/**
diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
index d2f5f1acc88..9e1ac3d6183 100644
--- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -180,6 +181,7 @@ public class MediaOutputPreferenceControllerTest {
mController.setActiveBluetoothDevice(mLeftBluetoothHapDevice);
verify(mHearingAidProfile).setActiveDevice(mLeftBluetoothHapDevice);
+ verify(mA2dpProfile, never()).setActiveDevice(mLeftBluetoothHapDevice);
}
/**
@@ -193,6 +195,7 @@ public class MediaOutputPreferenceControllerTest {
mController.setActiveBluetoothDevice(mBluetoothDevice);
verify(mA2dpProfile).setActiveDevice(mBluetoothDevice);
+ verify(mHearingAidProfile, never()).setActiveDevice(mBluetoothDevice);
}
/**
From 11fa37ebb49e4ec4a975d111bf3512139b905062 Mon Sep 17 00:00:00 2001
From: Matthew Fritze
Date: Tue, 17 Jul 2018 13:47:39 -0700
Subject: [PATCH 3/6] Add Settings Search Regression test
Take a snapshot of the currently available search results, and
verify that search results aren't accidentally removed.
We use 4 items to identify a search result:
- Title
- Data Key
- Slice Uri
We use Title & Key to identify the search result, since they should not change.
The Slice Uri is used to make sure we don't regress on Slice Availability.
Test: runtest --path packages/apps/Settings/tests/unit/src/com/android/settings/search/SettingsSearchResultRegressionTest.java
Change-Id: I22498229bbcd1e90c9e0a026af9df4367a98190a
---
tests/uitests/AndroidManifest.xml | 1 +
tests/uitests/assets/search_results_list | 623 ++++++++++++++++++
.../android/settings/search/SearchData.java | 81 +++
.../SettingsSearchResultRegressionTest.java | 210 ++++++
4 files changed, 915 insertions(+)
create mode 100644 tests/uitests/assets/search_results_list
create mode 100644 tests/uitests/src/com/android/settings/search/SearchData.java
create mode 100644 tests/uitests/src/com/android/settings/search/SettingsSearchResultRegressionTest.java
diff --git a/tests/uitests/AndroidManifest.xml b/tests/uitests/AndroidManifest.xml
index 91e15b8b43d..49a2fd110aa 100644
--- a/tests/uitests/AndroidManifest.xml
+++ b/tests/uitests/AndroidManifest.xml
@@ -28,6 +28,7 @@
+
+ * The data set used here (/tests/unit/assets/search_results_list) needs to be updated
+ * every once in a while so that we can check newly added results.
+ *
+ */
+ @Test
+ @Presubmit
+ public void searchResultsDoNotRegress() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ final Uri uri = getTestProviderUri();
+ final Cursor cursor = resolver.query(uri, null, null, null, null);
+
+ if (cursor == null) {
+ // Assume Settings Intelligence is wrong.
+ return;
+ }
+
+ final Set availableSearchResults = getSearchDataFromCursor(cursor);
+ final Set registeredSearchResults = getRegisteredResults();
+
+ // Seed with results that we expect
+ final Set missingSearchResults = new HashSet<>(registeredSearchResults);
+ // Seed with results that are available
+ final Set newSearchResults = new HashSet<>(availableSearchResults);
+
+ // Remove all available results, leaving results that have been removed.
+ missingSearchResults.removeAll(availableSearchResults);
+ // Remove all results we expect, leaving results that have not yet been registered.
+ newSearchResults.removeAll(registeredSearchResults);
+
+ assertWithMessage(ERROR_RESULTS_MISSING + ERROR_RERUN_TEST)
+ .that(missingSearchResults).isEmpty();
+ assertWithMessage(ERROR_NEW_RESULTS + ERROR_RERUN_TEST).that(newSearchResults).isEmpty();
+ }
+
+ // TODO (b/113907111) add a test to catch duplicate title search results.
+
+ /**
+ * Test to generate a new list of search results. Uncomment the Test annotation and run the
+ * test to generate the list.
+ */
+ @Ignore
+ @Test
+ public void generate_search_result_list() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ final Uri uri = getTestProviderUri();
+ final Cursor cursor = resolver.query(uri, null, null, null, null);
+ final List availableSearchResults =
+ new ArrayList<>(getSearchDataFromCursor(cursor));
+
+ Collections.sort(availableSearchResults, Comparator.comparing(SearchData::getTitle)
+ .thenComparing(SearchData::getKey));
+
+ assertThat(generateListFromSearchData(availableSearchResults)).isNull();
+ }
+
+ private Set getSearchDataFromCursor(Cursor cursor) {
+ final Set searchData = new HashSet<>();
+
+ final int titleIndex = cursor.getColumnIndex(
+ IndexColumns.DATA_TITLE);
+ final int keyIndex = cursor.getColumnIndex(
+ IndexColumns.DATA_KEY_REF);
+
+ while (cursor.moveToNext()) {
+ String title = cursor.getString(titleIndex);
+ String key = cursor.getString(keyIndex);
+
+ if (TextUtils.isEmpty(title)) {
+ title = "";
+ }
+
+ if (TextUtils.isEmpty(key)) {
+ key = "";
+ }
+
+ searchData.add(new SearchData.Builder()
+ .setTitle(title)
+ .setKey(key)
+ .build());
+ }
+
+ return searchData;
+ }
+
+ /**
+ * Utility method to generate the list of search results that this class uses to validate
+ * results.
+ */
+ private String generateListFromSearchData(List searchData) {
+ StringBuilder builder = new StringBuilder();
+ for (SearchData searchResult : searchData) {
+ builder.append(searchResult.title)
+ .append(
+ SearchData.DELIM)
+ .append(searchResult.key)
+ .append("\n");
+ }
+ return builder.toString();
+ }
+
+ private Uri getTestProviderUri() {
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority("com.google.android.settings.intelligence.modules.search.regression")
+ .build();
+ }
+
+ private Set getRegisteredResults() {
+ final String filename = "search_results_list";
+ final Set registeredResults = new HashSet<>();
+
+ try {
+ final InputStream in = mContext.getAssets().open(filename);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ registeredResults.add(
+ SearchData.from(line));
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Error initializing registered result list "
+ + filename, e);
+ }
+
+ return registeredResults;
+ }
+}
\ No newline at end of file
From ba3b68686d8a5cba549d2978d0a86d442498c5f9 Mon Sep 17 00:00:00 2001
From: Jonathan Scott
Date: Wed, 12 Sep 2018 14:40:15 +0100
Subject: [PATCH 4/6] Add policy transparency to disallow remove user.
On the Settings > System -> Multiple users screen, ensures that the"Delete from this device" menu is always available, but is disabled and includes policy information when DISABLE_REMOVE_USER is set.
Change-Id: Ia6c6cfb360f35a6e447bf9d85d2472ac11dde1ac
Fix: 113807450
Test: m ROBOTEST_FILTER=UserSettingsTest -j40 RunSettingsRoboTests; CTS Verifier Device Owner Tests/Policy transparency test/Disallow remove user.
---
.../android/settings/users/UserSettings.java | 12 ++-
.../settings/users/UserSettingsTest.java | 93 ++++++++++++++++++-
2 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 6e3174d8272..5b4055c436b 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -344,14 +344,18 @@ public class UserSettings extends SettingsPreferenceFragment
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
int pos = 0;
- UserManager um = getContext().getSystemService(UserManager.class);
- boolean allowRemoveUser = !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
- boolean canSwitchUsers = um.canSwitchUsers();
- if (!mUserCaps.mIsAdmin && allowRemoveUser && canSwitchUsers) {
+ final boolean canSwitchUsers = mUserManager.canSwitchUsers();
+ if (!mUserCaps.mIsAdmin && canSwitchUsers) {
String nickname = mUserManager.getUserName();
MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++,
getResources().getString(R.string.user_remove_user_menu, nickname));
removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+
+ final EnforcedAdmin disallowRemoveUserAdmin =
+ RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getContext(),
+ UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
+ RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getContext(), removeThisUser,
+ disallowRemoveUserAdmin);
}
super.onCreateOptionsMenu(menu, inflater);
}
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 02c279e4b23..49a4406bcb3 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -18,6 +18,9 @@ package com.android.settings.users;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -26,12 +29,19 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.text.SpannableStringBuilder;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
@@ -44,18 +54,30 @@ import com.android.settings.R;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.testutils.Robolectric;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
+import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedPreference;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.AdditionalMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
+import java.util.Collections;
+import java.util.List;
+
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(
+ shadows = {
+ ShadowUserManager.class,
+ ShadowDevicePolicyManager.class
+ })
public class UserSettingsTest {
private static final String KEY_USER_GUEST = "user_guest";
@@ -91,7 +113,8 @@ public class UserSettingsTest {
mUserCapabilities = UserCapabilities.create(mContext);
when((Object) mActivity.getSystemService(UserManager.class)).thenReturn(mUserManager);
doReturn(mActivity).when(mFragment).getActivity();
-
+ doReturn(mContext).when(mFragment).getContext();
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
mProvisioned = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0);
final SharedPreferences prefs = mock(SharedPreferences .class);
@@ -209,7 +232,75 @@ public class UserSettingsTest {
mFragment.updateUserList();
verify(addUser, never()).setVisible(true);
+ }
+ @Test
+ public void withDisallowRemoveUser_ShouldDisableRemoveUser() {
+ // TODO(b/115781615): Tidy robolectric tests
+ // Arrange
+ final int userId = UserHandle.myUserId();
+ final List enforcingUsers = Collections.singletonList(
+ new UserManager.EnforcingUser(userId,
+ UserManager.RESTRICTION_SOURCE_DEVICE_OWNER)
+ );
+ ShadowUserManager.getShadow().setUserRestrictionSources(
+ UserManager.DISALLOW_REMOVE_USER,
+ UserHandle.of(userId),
+ enforcingUsers);
+
+ ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser(
+ new ComponentName("test", "test"));
+
+ doReturn(true).when(mUserManager).canSwitchUsers();
+ mUserCapabilities.mIsAdmin = false;
+
+ ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
+ ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+
+ Menu menu = mock(Menu.class);
+ MenuItem menuItem = mock(MenuItem.class);
+ final String title = "title";
+
+ doReturn(title).when(menuItem).getTitle();
+ doReturn(menuItem).when(menu).add(
+ anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class));
+
+ // Act
+ mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class));
+
+ // Assert
+ // Expect that the click will be overridden and the color will be faded
+ // (by RestrictedLockUtilsInternal)
+ verify(menuItem).setOnMenuItemClickListener(notNull());
+ SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title);
+ verify(menuItem).setTitle(AdditionalMatchers.not(eq(defaultTitle)));
+ }
+
+ @Test
+ public void withoutDisallowRemoveUser_ShouldNotDisableRemoveUser() {
+ // Arrange
+ doReturn(true).when(mUserManager).canSwitchUsers();
+ mUserCapabilities.mIsAdmin = false;
+
+ ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
+ ReflectionHelpers.setField(mFragment, "mUserManager", mock(UserManager.class));
+
+ Menu menu = mock(Menu.class);
+ MenuItem menuItem = mock(MenuItem.class);
+ final String title = "title";
+
+ doReturn(title).when(menuItem).getTitle();
+ doReturn(menuItem).when(menu).add(
+ anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class));
+
+ // Act
+ mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class));
+
+ // Assert
+ // Expect that a click listener will not be added and the title will not be changed
+ verify(menuItem, never()).setOnMenuItemClickListener(notNull());
+ SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title);
+ verify(menuItem, never()).setTitle(AdditionalMatchers.not(eq(defaultTitle)));
}
@Test
From d5ddae8fc49cba7bac5ed6301452824b030d660f Mon Sep 17 00:00:00 2001
From: Julia Reynolds
Date: Wed, 19 Sep 2018 12:18:13 -0400
Subject: [PATCH 5/6] Reset all notification settings on clear app prefs
Not just the app level 'are these notifications blocked?'
field.
Test: manual
Change-Id: Id77366d0d71e1f0d2507f1a30123d61aa11db252
Fixes: 65476259
---
.../applications/manageapplications/ResetAppsHelper.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java b/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java
index ec4cc1e38ab..3af3500e48c 100644
--- a/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java
+++ b/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java
@@ -117,7 +117,7 @@ public class ResetAppsHelper implements DialogInterface.OnClickListener,
for (int i = 0; i < apps.size(); i++) {
ApplicationInfo app = apps.get(i);
try {
- mNm.setNotificationsEnabledForPackage(app.packageName, app.uid, true);
+ mNm.clearData(app.packageName, app.uid, false);
} catch (android.os.RemoteException ex) {
}
if (!app.enabled) {
From 56966ce8f5100b17283fdaf9eacc4b98a05ba4a6 Mon Sep 17 00:00:00 2001
From: Julia Reynolds
Date: Wed, 19 Sep 2018 12:23:41 -0400
Subject: [PATCH 6/6] Add checks before casting entry.extraInfo.
Test: make, flash
Change-Id: I1a9d6a51b1f236e711fdb49d9c2f795e7023cfce
Fixes: 113309404
---
.../ManageApplications.java | 6 +++--
.../ManageApplicationsTest.java | 22 +++++++++++++++++++
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index eb258ac2ad8..35c6d1c4796 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -1335,7 +1335,8 @@ public class ManageApplications extends InstrumentedFragment
private void updateSummary(ApplicationViewHolder holder, AppEntry entry) {
switch (mManageApplications.mListType) {
case LIST_TYPE_NOTIFICATION:
- if (entry.extraInfo != null) {
+ if (entry.extraInfo != null
+ && entry.extraInfo instanceof NotificationsSentState) {
holder.setSummary(AppStateNotificationBridge.getSummary(mContext,
(NotificationsSentState) entry.extraInfo,
(mLastSortMode == R.id.sort_order_recent_notification)));
@@ -1384,7 +1385,8 @@ public class ManageApplications extends InstrumentedFragment
.getSwitchOnClickListener(entry),
AppStateNotificationBridge.enableSwitch(entry),
AppStateNotificationBridge.checkSwitch(entry));
- if (entry.extraInfo != null) {
+ if (entry.extraInfo != null
+ && entry.extraInfo instanceof NotificationsSentState) {
holder.setSummary(AppStateNotificationBridge.getSummary(mContext,
(NotificationsSentState) entry.extraInfo,
(mLastSortMode == R.id.sort_order_recent_notification)));
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
index da88e543f55..c9ab7c0ebc9 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
@@ -281,6 +281,28 @@ public class ManageApplicationsTest {
verify(adapter).notifyDataSetChanged();
}
+ @Test
+ public void applicationsAdapter_onBindViewHolder_notifications_wrongExtraInfo() {
+ when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
+ ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+ mFragment.mListType = LIST_TYPE_NOTIFICATION;
+ ApplicationViewHolder holder = mock(ApplicationViewHolder.class);
+ ReflectionHelpers.setField(holder, "itemView", mock(View.class));
+ ManageApplications.ApplicationsAdapter adapter =
+ new ManageApplications.ApplicationsAdapter(mState,
+ mFragment, mock(AppFilterItem.class),
+ mock(Bundle.class));
+ final ArrayList appList = new ArrayList<>();
+ final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
+ appEntry.info = mock(ApplicationInfo.class);
+ appEntry.extraInfo = mock(AppFilterItem.class);
+ appList.add(appEntry);
+ ReflectionHelpers.setField(adapter, "mEntries", appList);
+
+ adapter.onBindViewHolder(holder, 0);
+ // no crash? yay!
+ }
+
@Test
public void applicationsAdapter_onBindViewHolder_updateSwitch_notifications() {
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});