diff --git a/res/drawable/ic_download_for_offline.xml b/res/drawable/ic_download_for_offline.xml
new file mode 100644
index 00000000000..f9ea3050f55
--- /dev/null
+++ b/res/drawable/ic_download_for_offline.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/res/drawable/zen_calls_any.xml b/res/drawable/zen_calls_any.xml
new file mode 100644
index 00000000000..546fd93395a
--- /dev/null
+++ b/res/drawable/zen_calls_any.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/zen_calls_contacts.xml b/res/drawable/zen_calls_contacts.xml
new file mode 100644
index 00000000000..a4c064a76e5
--- /dev/null
+++ b/res/drawable/zen_calls_contacts.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/zen_calls_none.xml b/res/drawable/zen_calls_none.xml
new file mode 100644
index 00000000000..e89da49d7b6
--- /dev/null
+++ b/res/drawable/zen_calls_none.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/zen_calls_starred.xml b/res/drawable/zen_calls_starred.xml
new file mode 100644
index 00000000000..25e9a6193eb
--- /dev/null
+++ b/res/drawable/zen_calls_starred.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/zen_messages_any.xml b/res/drawable/zen_messages_any.xml
new file mode 100644
index 00000000000..edeaea2726c
--- /dev/null
+++ b/res/drawable/zen_messages_any.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/zen_messages_contacts.xml b/res/drawable/zen_messages_contacts.xml
new file mode 100644
index 00000000000..8da80b94a0b
--- /dev/null
+++ b/res/drawable/zen_messages_contacts.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/zen_messages_none.xml b/res/drawable/zen_messages_none.xml
new file mode 100644
index 00000000000..c72cc4f133c
--- /dev/null
+++ b/res/drawable/zen_messages_none.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/res/drawable/zen_messages_starred.xml b/res/drawable/zen_messages_starred.xml
new file mode 100644
index 00000000000..75feb80d711
--- /dev/null
+++ b/res/drawable/zen_messages_starred.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/zen_mode_senders_image.xml b/res/layout/zen_mode_senders_image.xml
new file mode 100644
index 00000000000..bc7cdae2627
--- /dev/null
+++ b/res/layout/zen_mode_senders_image.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 450eb1301a1..834f04c1746 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7004,7 +7004,7 @@
Except when another payment app is open
- At a Tap & pay terminal, pay with:
+ At a contactless terminal, pay with:
Paying at the terminal
@@ -7015,9 +7015,21 @@
More...
- Set as your preference?
- Always use %1$s when you Tap & pay?
- Always use %1$s instead of %2$s when you Tap & pay?
+ Set default payment app
+
+ Update default payment app
+ At a contactless terminal, pay with
+ %1$s
+
+ At a contactless terminal, pay with %1$s.\n\nThis replaces %2$s as your default
+ payment app.
+
+
+ Set default
+
+ Update
@@ -8525,6 +8537,12 @@
When a user connects select work and personal apps, they can access work and personal data together. [CHAR LIMIT=50] -->
Connected work & personal apps
+
+ Connected
+
+
+ Not connected
+
No connected apps
@@ -8591,27 +8609,18 @@
- Install %1$s in your work profile
-
-
- To connect these apps, install the %1$s app in your work profile
+ Install work %1$s to connect these apps
- Install %1$s in your personal profile
+ The placeholder would be the app name (e.g. Calendar). [CHAR LIMIT=NONE]-->
+ Install personal %1$s to connect these apps
- To connect these apps, install the %1$s app in your personal profile
-
-
- Get the app
+ Tap to get the app
Do Not Disturb access
@@ -10548,9 +10557,6 @@
Cross-profile calendar
Show work events on your personal calendar
-
- Your organization doesn\u2019t allow personal apps to access your work calendar
-
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index 4078e824819..3dcddc8eb19 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -140,11 +140,6 @@
android:ringtoneType="notification"
settings:searchable="false"/>
-
-
-
-
+
-
+
-
+
-
+
+
+
diff --git a/res/xml/managed_profile_settings.xml b/res/xml/managed_profile_settings.xml
index 7b65a3d30b0..20f6d3dc3f3 100644
--- a/res/xml/managed_profile_settings.xml
+++ b/res/xml/managed_profile_settings.xml
@@ -32,18 +32,10 @@
settings:useAdditionalSummary="true"
settings:controller="com.android.settings.accounts.ContactSearchPreferenceController"/>
-
-
\ No newline at end of file
diff --git a/res/xml/zen_mode_calls_settings.xml b/res/xml/zen_mode_calls_settings.xml
index cbadc7d7ce4..0b44875a3ec 100644
--- a/res/xml/zen_mode_calls_settings.xml
+++ b/res/xml/zen_mode_calls_settings.xml
@@ -25,6 +25,11 @@
android:key="zen_mode_settings_category_calls"
android:title="@string/zen_mode_calls_header"
settings:allowDividerBelow="true">
+
+
+
diff --git a/res/xml/zen_mode_messages_settings.xml b/res/xml/zen_mode_messages_settings.xml
index c302b02b72e..31cad2a5347 100644
--- a/res/xml/zen_mode_messages_settings.xml
+++ b/res/xml/zen_mode_messages_settings.xml
@@ -23,6 +23,11 @@
+
+
+
diff --git a/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceController.java b/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceController.java
deleted file mode 100644
index c0879823792..00000000000
--- a/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceController.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settings.accounts;
-import static com.android.settings.accounts.CrossProfileCalendarPreferenceController.isCrossProfileCalendarDisallowedByAdmin;
-
-import android.content.Context;
-import android.os.UserHandle;
-
-import com.android.settings.core.BasePreferenceController;
-
-public class CrossProfileCalendarDisabledPreferenceController extends BasePreferenceController {
- private UserHandle mManagedUser;
-
- public void setManagedUser(UserHandle managedUser) {
- mManagedUser = managedUser;
- }
-
- public CrossProfileCalendarDisabledPreferenceController(Context context,
- String preferenceKey) {
- super(context, preferenceKey);
- }
-
- @Override
- public int getAvailabilityStatus() {
- if (mManagedUser != null
- && isCrossProfileCalendarDisallowedByAdmin(
- mContext, mManagedUser.getIdentifier())) {
- return AVAILABLE;
- }
-
- return DISABLED_FOR_USER;
- }
-}
diff --git a/src/com/android/settings/accounts/ManagedProfileSettings.java b/src/com/android/settings/accounts/ManagedProfileSettings.java
index 6591be488a3..f16bc3f49b6 100644
--- a/src/com/android/settings/accounts/ManagedProfileSettings.java
+++ b/src/com/android/settings/accounts/ManagedProfileSettings.java
@@ -79,7 +79,6 @@ public class ManagedProfileSettings extends DashboardFragment {
use(WorkModePreferenceController.class).setManagedUser(mManagedUser);
use(ContactSearchPreferenceController.class).setManagedUser(mManagedUser);
use(CrossProfileCalendarPreferenceController.class).setManagedUser(mManagedUser);
- use(CrossProfileCalendarDisabledPreferenceController.class).setManagedUser(mManagedUser);
}
@Override
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
index ff616268063..474a5b6ec79 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
@@ -15,15 +15,25 @@
*/
package com.android.settings.applications.specialaccess.interactacrossprofiles;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+
import android.Manifest;
+import android.annotation.UserIdInt;
+import android.app.ActionBar;
import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.CrossProfileApps;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -32,13 +42,15 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
-import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
-import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
+import com.android.settings.applications.AppStoreUtil;
+import com.android.settings.widget.CardPreference;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.widget.LayoutPreference;
public class InteractAcrossProfilesDetails extends AppInfoBase
@@ -47,13 +59,21 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
private static final String INTERACT_ACROSS_PROFILES_SETTINGS_SWITCH =
"interact_across_profiles_settings_switch";
private static final String INTERACT_ACROSS_PROFILES_HEADER = "interact_across_profiles_header";
+ public static final String INSTALL_APP_BANNER_KEY = "install_app_banner";
private Context mContext;
private CrossProfileApps mCrossProfileApps;
private UserManager mUserManager;
- private SwitchPreference mSwitchPref;
+ private RestrictedSwitchPreference mSwitchPref;
private LayoutPreference mHeader;
+ private CardPreference mInstallBanner;
private PackageManager mPackageManager;
+ private UserHandle mPersonalProfile;
+ private UserHandle mWorkProfile;
+ private boolean mInstalledInPersonal;
+ private boolean mInstalledInWork;
+ private String mAppLabel;
+ private Intent mInstallAppIntent;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -64,19 +84,30 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
mUserManager = mContext.getSystemService(UserManager.class);
mPackageManager = mContext.getPackageManager();
+ mWorkProfile = InteractAcrossProfilesSettings.getWorkProfile(mUserManager);
+ mPersonalProfile = mUserManager.getProfileParent(mWorkProfile);
+ mInstalledInWork = isPackageInstalled(mPackageName, mWorkProfile.getIdentifier());
+ mInstalledInPersonal = isPackageInstalled(mPackageName, mPersonalProfile.getIdentifier());
+
+ mAppLabel = mPackageInfo.applicationInfo.loadLabel(mPackageManager).toString();
+ mInstallAppIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
+
addPreferencesFromResource(R.xml.interact_across_profiles_permissions_details);
mSwitchPref = findPreference(INTERACT_ACROSS_PROFILES_SETTINGS_SWITCH);
mSwitchPref.setOnPreferenceClickListener(this);
+
mHeader = findPreference(INTERACT_ACROSS_PROFILES_HEADER);
+ mInstallBanner = findPreference(INSTALL_APP_BANNER_KEY);
+ mInstallBanner.setOnPreferenceClickListener(this);
+
// refreshUi checks that the user can still configure the appOp, return to the
// previous page if it can't.
if (!refreshUi()) {
setIntentAndFinish(true/* appChanged */);
}
- final UserHandle workProfile = getWorkProfile();
- final UserHandle personalProfile = mUserManager.getProfileParent(workProfile);
- addAppTitleAndIcons(personalProfile, workProfile);
+ addAppTitleAndIcons(mPersonalProfile, mWorkProfile);
+ styleActionBar();
}
private void addAppTitleAndIcons(UserHandle personalProfile, UserHandle workProfile) {
@@ -89,70 +120,101 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
final ImageView personalIconView = mHeader.findViewById(R.id.entity_header_icon_personal);
if (personalIconView != null) {
- personalIconView.setImageDrawable(IconDrawableFactory.newInstance(mContext)
- .getBadgedIcon(mPackageInfo.applicationInfo, personalProfile.getIdentifier()));
+ Drawable icon = IconDrawableFactory.newInstance(mContext)
+ .getBadgedIcon(mPackageInfo.applicationInfo, personalProfile.getIdentifier())
+ .mutate();
+ if (!mInstalledInPersonal) {
+ icon.setColorFilter(createSuspendedColorMatrix());
+ }
+ personalIconView.setImageDrawable(icon);
}
- final ImageView workIconView2 = mHeader.findViewById(R.id.entity_header_icon_work);
- if (workIconView2 != null) {
- workIconView2.setImageDrawable(IconDrawableFactory.newInstance(mContext)
- .getBadgedIcon(mPackageInfo.applicationInfo, workProfile.getIdentifier()));
+
+ final ImageView workIconView = mHeader.findViewById(R.id.entity_header_icon_work);
+ if (workIconView != null) {
+ Drawable icon = IconDrawableFactory.newInstance(mContext)
+ .getBadgedIcon(mPackageInfo.applicationInfo, workProfile.getIdentifier())
+ .mutate();
+ if (!mInstalledInWork) {
+ icon.setColorFilter(createSuspendedColorMatrix());
+ }
+ workIconView.setImageDrawable(icon);
}
}
- @Nullable
- private UserHandle getWorkProfile() {
- for (UserInfo user : mUserManager.getProfiles(UserHandle.myUserId())) {
- if (mUserManager.isManagedProfile(user.id)) {
- return user.getUserHandle();
- }
+ private void styleActionBar() {
+ final ActionBar actionBar = getActivity().getActionBar();
+ if (actionBar != null) {
+ actionBar.setElevation(0);
}
- return null;
+ }
+
+ private ColorMatrixColorFilter createSuspendedColorMatrix() {
+ int grayValue = 127;
+ float scale = 0.5f; // half bright
+
+ ColorMatrix tempBrightnessMatrix = new ColorMatrix();
+ float[] mat = tempBrightnessMatrix.getArray();
+ mat[0] = scale;
+ mat[6] = scale;
+ mat[12] = scale;
+ mat[4] = grayValue;
+ mat[9] = grayValue;
+ mat[14] = grayValue;
+
+ ColorMatrix matrix = new ColorMatrix();
+ matrix.setSaturation(0.0f);
+ matrix.preConcat(tempBrightnessMatrix);
+ return new ColorMatrixColorFilter(matrix);
}
@Override
public boolean onPreferenceClick(Preference preference) {
- if (preference != mSwitchPref) {
- return false;
- }
// refreshUi checks that the user can still configure the appOp, return to the
// previous page if it can't.
if (!refreshUi()) {
setIntentAndFinish(true/* appChanged */);
}
+ if (preference == mSwitchPref) {
+ handleSwitchPreferenceClick();
+ return true;
+ }
+ if (preference == mInstallBanner) {
+ handleInstallBannerClick();
+ return true;
+ }
+ return false;
+ }
+
+ private void handleSwitchPreferenceClick() {
if (isInteractAcrossProfilesEnabled()) {
enableInteractAcrossProfiles(false);
refreshUi();
- return true;
- }
- if (!isInteractAcrossProfilesEnabled()) {
+ } else {
showConsentDialog();
}
- return true;
}
private void showConsentDialog() {
- final String appLabel = mPackageInfo.applicationInfo.loadLabel(mPackageManager).toString();
-
final View dialogView = getLayoutInflater().inflate(
R.layout.interact_across_profiles_consent_dialog, null);
final TextView dialogTitle = dialogView.findViewById(
R.id.interact_across_profiles_consent_dialog_title);
dialogTitle.setText(
- getString(R.string.interact_across_profiles_consent_dialog_title, appLabel));
+ getString(R.string.interact_across_profiles_consent_dialog_title, mAppLabel));
final TextView dialogSummary = dialogView.findViewById(
R.id.interact_across_profiles_consent_dialog_summary);
dialogSummary.setText(
- getString(R.string.interact_across_profiles_consent_dialog_summary, appLabel));
+ getString(R.string.interact_across_profiles_consent_dialog_summary, mAppLabel));
final TextView appDataSummary = dialogView.findViewById(R.id.app_data_summary);
appDataSummary.setText(getString(
- R.string.interact_across_profiles_consent_dialog_app_data_summary, appLabel));
+ R.string.interact_across_profiles_consent_dialog_app_data_summary, mAppLabel));
final TextView permissionsSummary = dialogView.findViewById(R.id.permissions_summary);
permissionsSummary.setText(getString(
- R.string.interact_across_profiles_consent_dialog_permissions_summary, appLabel));
+ R.string.interact_across_profiles_consent_dialog_permissions_summary, mAppLabel));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(dialogView)
@@ -171,18 +233,38 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
}
private boolean isInteractAcrossProfilesEnabled() {
- return isInteractAcrossProfilesEnabled(
- mContext, mPackageName, mPackageInfo.applicationInfo.uid);
+ return isInteractAcrossProfilesEnabled(mContext, mPackageName);
}
- static boolean isInteractAcrossProfilesEnabled(Context context, String packageName, int uid) {
+ static boolean isInteractAcrossProfilesEnabled(
+ Context context, String packageName) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ UserHandle workProfile = InteractAcrossProfilesSettings.getWorkProfile(userManager);
+ UserHandle personalProfile = userManager.getProfileParent(workProfile);
+ return context.getSystemService(
+ CrossProfileApps.class).canConfigureInteractAcrossProfiles(packageName)
+ && isInteractAcrossProfilesEnabledInProfile(context, packageName, personalProfile)
+ && isInteractAcrossProfilesEnabledInProfile(context, packageName, workProfile);
+
+ }
+
+ private static boolean isInteractAcrossProfilesEnabledInProfile(
+ Context context, String packageName, UserHandle userHandle) {
+ final PackageManager packageManager = context.getPackageManager();
+ final int uid;
+ try {
+ uid = packageManager.getApplicationInfoAsUser(
+ packageName, /* flags= */0, userHandle).uid;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
return PermissionChecker.PERMISSION_GRANTED
== PermissionChecker.checkPermissionForPreflight(
- context,
- Manifest.permission.INTERACT_ACROSS_PROFILES,
- PermissionChecker.PID_UNKNOWN,
- uid,
- packageName);
+ context,
+ Manifest.permission.INTERACT_ACROSS_PROFILES,
+ PermissionChecker.PID_UNKNOWN,
+ uid,
+ packageName);
}
private void enableInteractAcrossProfiles(boolean newState) {
@@ -190,14 +272,28 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
mPackageName, newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
}
+ private void handleInstallBannerClick() {
+ if (mInstallAppIntent == null) {
+ return;
+ }
+ if (!mInstalledInWork) {
+ mContext.startActivityAsUser(mInstallAppIntent, mWorkProfile);
+ return;
+ }
+ if (!mInstalledInPersonal) {
+ mContext.startActivityAsUser(mInstallAppIntent, mPersonalProfile);
+ }
+ }
+
/**
* @return the summary for the current state of whether the app associated with the given
* {@code packageName} is allowed to interact across profiles.
*/
- public static CharSequence getPreferenceSummary(Context context, String packageName, int uid) {
- return context.getString(isInteractAcrossProfilesEnabled(context, packageName, uid)
- ? R.string.app_permission_summary_allowed
- : R.string.app_permission_summary_not_allowed);
+ public static CharSequence getPreferenceSummary(
+ Context context, String packageName) {
+ return context.getString(isInteractAcrossProfilesEnabled(context, packageName)
+ ? R.string.interact_across_profiles_summary_allowed
+ : R.string.interact_across_profiles_summary_not_allowed);
}
@Override
@@ -205,31 +301,99 @@ public class InteractAcrossProfilesDetails extends AppInfoBase
if (mPackageInfo == null || mPackageInfo.applicationInfo == null) {
return false;
}
- if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) {
+ if (!mCrossProfileApps.canUserAttemptToConfigureInteractAcrossProfiles(mPackageName)) {
// Invalid app entry. Should not allow changing permission
mSwitchPref.setEnabled(false);
return false;
}
-
- final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz);
- if (isInteractAcrossProfilesEnabled()) {
- mSwitchPref.setChecked(true);
- mSwitchPref.setTitle(R.string.interact_across_profiles_switch_enabled);
- if (horizontalArrowIcon != null) {
- horizontalArrowIcon.setImageDrawable(
- mContext.getDrawable(R.drawable.ic_swap_horiz_blue));
- }
- } else {
- mSwitchPref.setChecked(false);
- mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled);
- if (horizontalArrowIcon != null) {
- horizontalArrowIcon.setImageDrawable(
- mContext.getDrawable(R.drawable.ic_swap_horiz_grey));
- }
+ if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) {
+ return refreshUiForNonConfigurableApps();
}
+ refreshUiForConfigurableApps();
return true;
}
+ private boolean refreshUiForNonConfigurableApps() {
+ mSwitchPref.setChecked(false);
+ mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled);
+ if (!isCrossProfilePackageWhitelisted(mPackageName)) {
+ mInstallBanner.setVisible(false);
+ mSwitchPref.setDisabledByAdmin(RestrictedLockUtils.getProfileOrDeviceOwner(
+ mContext, mWorkProfile));
+ return true;
+ }
+ mSwitchPref.setEnabled(false);
+ if (!mInstalledInPersonal && !mInstalledInWork) {
+ return false;
+ }
+ if (!mInstalledInPersonal) {
+ mInstallBanner.setTitle(getString(
+ R.string.interact_across_profiles_install_personal_app_title,
+ mAppLabel));
+ mInstallBanner.setSummary(
+ R.string.interact_across_profiles_install_app_summary);
+ mInstallBanner.setVisible(true);
+ return true;
+ }
+ if (!mInstalledInWork) {
+ mInstallBanner.setTitle(getString(
+ R.string.interact_across_profiles_install_work_app_title,
+ mAppLabel));
+ mInstallBanner.setSummary(
+ R.string.interact_across_profiles_install_app_summary);
+ mInstallBanner.setVisible(true);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isCrossProfilePackageWhitelisted(String packageName) {
+ return mContext.getSystemService(DevicePolicyManager.class)
+ .getAllCrossProfilePackages().contains(packageName);
+ }
+
+ private boolean isPackageInstalled(String packageName, @UserIdInt int userId) {
+ final PackageInfo info;
+ try {
+ info = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */0)
+ .getPackageManager().getPackageInfo(packageName,
+ MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ return info != null;
+ }
+
+ private void refreshUiForConfigurableApps() {
+ mInstallBanner.setVisible(false);
+ mSwitchPref.setEnabled(true);
+ if (isInteractAcrossProfilesEnabled()) {
+ enableSwitchPref();
+ } else {
+ disableSwitchPref();
+ }
+ }
+
+ private void enableSwitchPref() {
+ mSwitchPref.setChecked(true);
+ mSwitchPref.setTitle(R.string.interact_across_profiles_switch_enabled);
+ final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz);
+ if (horizontalArrowIcon != null) {
+ horizontalArrowIcon.setImageDrawable(
+ mContext.getDrawable(R.drawable.ic_swap_horiz_blue));
+ }
+ }
+
+ private void disableSwitchPref() {
+ mSwitchPref.setChecked(false);
+ mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled);
+ final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz);
+ if (horizontalArrowIcon != null) {
+ horizontalArrowIcon.setImageDrawable(
+ mContext.getDrawable(R.drawable.ic_swap_horiz_grey));
+ }
+ }
+
@Override
protected AlertDialog createDialog(int id, int errorCode) {
return null;
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsPreferenceController.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsPreferenceController.java
index 41e25a7d1d0..f57a6ed7c25 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsPreferenceController.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsPreferenceController.java
@@ -35,7 +35,7 @@ public class InteractAcrossProfilesDetailsPreferenceController
@Override
public int getAvailabilityStatus() {
- return canConfigureInteractAcrossProfiles() ? AVAILABLE : DISABLED_FOR_USER;
+ return canUserAttemptToConfigureInteractAcrossProfiles() ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
@@ -49,13 +49,12 @@ public class InteractAcrossProfilesDetailsPreferenceController
}
private CharSequence getPreferenceSummary() {
- return InteractAcrossProfilesDetails.getPreferenceSummary(mContext, mPackageName,
- mParent.getPackageInfo().applicationInfo.uid);
+ return InteractAcrossProfilesDetails.getPreferenceSummary(mContext, mPackageName);
}
- private boolean canConfigureInteractAcrossProfiles() {
+ private boolean canUserAttemptToConfigureInteractAcrossProfiles() {
return mContext.getSystemService(CrossProfileApps.class)
- .canConfigureInteractAcrossProfiles(mPackageName);
+ .canUserAttemptToConfigureInteractAcrossProfiles(mPackageName);
}
public void setPackageName(String packageName) {
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java
index d686978fde4..c5d848af7a3 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java
@@ -85,8 +85,8 @@ public class InteractAcrossProfilesSettings extends EmptyTextSettings {
final Preference pref = new AppPreference(prefContext);
pref.setIcon(mIconDrawableFactory.getBadgedIcon(appInfo, user.getIdentifier()));
pref.setTitle(mPackageManager.getUserBadgedLabel(label, user));
- pref.setSummary(InteractAcrossProfilesDetails.getPreferenceSummary(prefContext,
- packageName, appInfo.uid));
+ pref.setSummary(InteractAcrossProfilesDetails.getPreferenceSummary(
+ prefContext, packageName));
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
@@ -127,49 +127,78 @@ public class InteractAcrossProfilesSettings extends EmptyTextSettings {
static ArrayList> collectConfigurableApps(
PackageManager packageManager, UserManager userManager,
CrossProfileApps crossProfileApps) {
- final UserHandle personalProfile = getPersonalProfileForCallingUser(userManager);
+ final UserHandle workProfile = getWorkProfile(userManager);
+ if (workProfile == null) {
+ return new ArrayList<>();
+ }
+ final UserHandle personalProfile = userManager.getProfileParent(workProfile);
if (personalProfile == null) {
return new ArrayList<>();
}
final ArrayList> apps = new ArrayList<>();
- final List installedPackages = packageManager.getInstalledPackagesAsUser(
- GET_ACTIVITIES, personalProfile.getIdentifier());
- for (PackageInfo packageInfo : installedPackages) {
- if (crossProfileApps.canConfigureInteractAcrossProfiles(packageInfo.packageName)) {
+ for (PackageInfo packageInfo : getAllInstalledPackages(
+ packageManager, personalProfile, workProfile)) {
+ if (crossProfileApps.canUserAttemptToConfigureInteractAcrossProfiles(
+ packageInfo.packageName)) {
apps.add(new Pair<>(packageInfo.applicationInfo, personalProfile));
}
}
return apps;
}
+ private static List getAllInstalledPackages(
+ PackageManager packageManager, UserHandle personalProfile, UserHandle workProfile) {
+ List personalPackages = packageManager.getInstalledPackagesAsUser(
+ GET_ACTIVITIES, personalProfile.getIdentifier());
+ List workPackages = packageManager.getInstalledPackagesAsUser(
+ GET_ACTIVITIES, workProfile.getIdentifier());
+ List allPackages = new ArrayList<>(personalPackages);
+ for (PackageInfo workPackage : workPackages) {
+ if (allPackages.stream().noneMatch(
+ p -> workPackage.packageName.equals(p.packageName))) {
+ allPackages.add(workPackage);
+ }
+ }
+ return allPackages;
+ }
+
/**
* @return the number of applications that can interact across profiles.
*/
static int getNumberOfEnabledApps(
Context context, PackageManager packageManager, UserManager userManager,
CrossProfileApps crossProfileApps) {
+ UserHandle workProfile = getWorkProfile(userManager);
+ if (workProfile == null) {
+ return 0;
+ }
+ UserHandle personalProfile = userManager.getProfileParent(workProfile);
+ if (personalProfile == null) {
+ return 0;
+ }
final ArrayList> apps =
collectConfigurableApps(packageManager, userManager, crossProfileApps);
apps.removeIf(
app -> !InteractAcrossProfilesDetails.isInteractAcrossProfilesEnabled(
- context, app.first.packageName, app.first.uid));
+ context, app.first.packageName)
+ || !crossProfileApps.canConfigureInteractAcrossProfiles(
+ app.first.packageName));
return apps.size();
}
/**
- * Returns the personal profile in the profile group of the calling user.
- * Returns null if user is not in a profile group.
+ * Returns the work profile in the profile group of the calling user.
+ * Returns null if not found.
*/
@Nullable
- private static UserHandle getPersonalProfileForCallingUser(UserManager userManager) {
- final int callingUser = UserHandle.myUserId();
- if (userManager.getProfiles(callingUser).isEmpty()) {
- return null;
+ static UserHandle getWorkProfile(UserManager userManager) {
+ for (UserInfo user : userManager.getProfiles(UserHandle.myUserId())) {
+ if (userManager.isManagedProfile(user.id)) {
+ return user.getUserHandle();
+ }
}
- final UserInfo parentProfile = userManager.getProfileParent(callingUser);
- return parentProfile == null
- ? UserHandle.of(callingUser) : parentProfile.getUserHandle();
+ return null;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/media/MediaDeviceUpdateWorker.java b/src/com/android/settings/media/MediaDeviceUpdateWorker.java
index 281d23e9afb..b800c179859 100644
--- a/src/com/android/settings/media/MediaDeviceUpdateWorker.java
+++ b/src/com/android/settings/media/MediaDeviceUpdateWorker.java
@@ -151,7 +151,7 @@ public class MediaDeviceUpdateWorker extends SliceBackgroundWorker
}
MediaDevice getTopDevice() {
- return mTopDevice;
+ return getMediaDeviceById(mTopDevice.getId());
}
boolean addDeviceToPlayMedia(MediaDevice device) {
diff --git a/src/com/android/settings/network/ims/WifiCallingQueryImsState.java b/src/com/android/settings/network/ims/WifiCallingQueryImsState.java
index 6ed0d606590..efa93e5abe5 100644
--- a/src/com/android/settings/network/ims/WifiCallingQueryImsState.java
+++ b/src/com/android/settings/network/ims/WifiCallingQueryImsState.java
@@ -27,10 +27,6 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting;
-import com.android.ims.ImsManager;
-import com.android.settings.network.SubscriptionUtil;
-import com.android.settings.network.telephony.MobileNetworkUtils;
-
/**
* Controller class for querying Wifi calling status
*/
@@ -66,12 +62,6 @@ public class WifiCallingQueryImsState extends ImsQueryController {
return (new ImsQueryWfcUserSetting(subId)).query();
}
- @VisibleForTesting
- ImsManager getImsManager(int subId) {
- return ImsManager.getInstance(mContext,
- SubscriptionUtil.getPhoneId(mContext, subId));
- }
-
/**
* Check whether Wifi Calling is a supported feature on this subscription
*
@@ -107,8 +97,15 @@ public class WifiCallingQueryImsState extends ImsQueryController {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
return false;
}
- return isWifiCallingProvisioned()
- && MobileNetworkUtils.isImsServiceStateReady(getImsManager(mSubId));
+ if (!isWifiCallingProvisioned()) {
+ return false;
+ }
+ try {
+ return isServiceStateReady(mSubId);
+ } catch (InterruptedException | IllegalArgumentException | ImsException exception) {
+ Log.w(LOG_TAG, "fail to get WFC service status. subId=" + mSubId, exception);
+ }
+ return false;
}
/**
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index 076a87b1774..12b71e87120 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -26,8 +26,8 @@ import static com.android.settings.network.telephony.TelephonyConstants.RadioAcc
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_UNKNOWN;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA;
-import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO;
+import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
@@ -54,7 +54,6 @@ import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsRcsManager;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.RcsUceAdapter;
-import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
@@ -63,8 +62,6 @@ import android.view.Gravity;
import androidx.annotation.VisibleForTesting;
-import com.android.ims.ImsException;
-import com.android.ims.ImsManager;
import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -150,7 +147,6 @@ public class MobileNetworkUtils {
final PhoneAccountHandle simCallManager =
context.getSystemService(TelecomManager.class)
.getSimCallManagerForSubscription(subId);
- final int phoneId = SubscriptionManager.getSlotIndex(subId);
boolean isWifiCallingEnabled;
if (simCallManager != null) {
@@ -161,9 +157,7 @@ public class MobileNetworkUtils {
} else {
final WifiCallingQueryImsState queryState =
new WifiCallingQueryImsState(context, subId);
- final ImsManager imsMgr = ImsManager.getInstance(context, phoneId);
- isWifiCallingEnabled = queryState.isWifiCallingProvisioned()
- && isImsServiceStateReady(imsMgr);
+ isWifiCallingEnabled = queryState.isReadyToWifiCalling();
}
return isWifiCallingEnabled;
@@ -280,21 +274,6 @@ public class MobileNetworkUtils {
return intent;
}
- public static boolean isImsServiceStateReady(ImsManager imsMgr) {
- boolean isImsServiceStateReady = false;
-
- try {
- if (imsMgr != null && imsMgr.getImsServiceState() == ImsFeature.STATE_READY) {
- isImsServiceStateReady = true;
- }
- } catch (ImsException ex) {
- Log.e(TAG, "Exception when trying to get ImsServiceStatus: " + ex);
- }
-
- Log.d(TAG, "isImsServiceStateReady=" + isImsServiceStateReady);
- return isImsServiceStateReady;
- }
-
/**
* Whether to show the entry point to eUICC settings.
*
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index 73b92e7b6ba..1aa8dca9bd1 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -111,21 +111,23 @@ public final class PaymentDefaultDialog extends AlertActivity implements
mNewDefault = component;
// Compose dialog; get
final AlertController.AlertParams p = mAlertParams;
- p.mTitle = getString(R.string.nfc_payment_set_default_label);
if (defaultPaymentApp == null) {
+ p.mTitle = getString(R.string.nfc_payment_set_default_label);
String formatString = getString(R.string.nfc_payment_set_default);
String msg = String.format(formatString,
sanitizePaymentAppCaption(requestedPaymentApp.label.toString()));
p.mMessage = msg;
+ p.mPositiveButtonText = getString(R.string.nfc_payment_btn_text_set_deault);
} else {
+ p.mTitle = getString(R.string.nfc_payment_update_default_label);
String formatString = getString(R.string.nfc_payment_set_default_instead_of);
String msg = String.format(formatString,
sanitizePaymentAppCaption(requestedPaymentApp.label.toString()),
sanitizePaymentAppCaption(defaultPaymentApp.label.toString()));
p.mMessage = msg;
+ p.mPositiveButtonText = getString(R.string.nfc_payment_btn_text_update);
}
- p.mPositiveButtonText = getString(R.string.yes);
- p.mNegativeButtonText = getString(R.string.no);
+ p.mNegativeButtonText = getString(R.string.cancel);
p.mPositiveButtonListener = this;
p.mNegativeButtonListener = this;
setupAlert();
diff --git a/src/com/android/settings/notification/NotificationPeopleStripPreferenceController.java b/src/com/android/settings/notification/NotificationPeopleStripPreferenceController.java
deleted file mode 100644
index e16443ec422..00000000000
--- a/src/com/android/settings/notification/NotificationPeopleStripPreferenceController.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification;
-
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.TogglePreferenceController;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
-
-import com.google.common.annotations.VisibleForTesting;
-
-/** Controls toggle setting for people strip in system ui. */
-public class NotificationPeopleStripPreferenceController extends TogglePreferenceController
- implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
- LifecycleObserver, OnResume, OnPause {
-
- @VisibleForTesting
- static final int ON = 1;
- @VisibleForTesting
- static final int OFF = 0;
-
- private final Uri mPeopleStripUri =
- Settings.Secure.getUriFor(Settings.Secure.PEOPLE_STRIP);
-
- private Preference mPreference;
- private Runnable mUnregisterOnPropertiesChangedListener;
-
- public NotificationPeopleStripPreferenceController(Context context, String preferenceKey) {
- super(context, preferenceKey);
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference = screen.findPreference("notification_people_strip");
- }
-
- @Override
- public void onResume() {
- if (mPreference == null) {
- return;
- }
- ContentObserver observer = new ContentObserver(new Handler(Looper.getMainLooper())) {
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
- updateState(mPreference);
- }
- };
- ContentResolver contentResolver = mContext.getContentResolver();
- mUnregisterOnPropertiesChangedListener =
- () -> contentResolver.unregisterContentObserver(observer);
- contentResolver.registerContentObserver(mPeopleStripUri, false, observer);
- }
-
- @Override
- public void onPause() {
- if (mUnregisterOnPropertiesChangedListener != null) {
- mUnregisterOnPropertiesChangedListener.run();
- mUnregisterOnPropertiesChangedListener = null;
- }
- }
-
- @Override
- public int getAvailabilityStatus() {
- return AVAILABLE;
- }
-
- @Override
- public boolean isSliceable() {
- return false;
- }
-
- @Override
- public boolean isChecked() {
- int value = Settings.Secure.getInt(
- mContext.getContentResolver(),
- Settings.Secure.PEOPLE_STRIP,
- OFF);
- return value != OFF;
- }
-
- @Override
- public boolean setChecked(boolean isChecked) {
- return Settings.Secure.putInt(
- mContext.getContentResolver(),
- Settings.Secure.PEOPLE_STRIP,
- isChecked ? ON : OFF);
- }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModeCallsSettings.java b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
index 1b5412e0ec8..82d5cf62765 100644
--- a/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
@@ -45,6 +45,8 @@ public class ZenModeCallsSettings extends ZenModeSettingsBase {
List controllers = new ArrayList<>();
controllers.add(new ZenModePrioritySendersPreferenceController(context,
"zen_mode_settings_category_calls", lifecycle, false));
+ controllers.add(new ZenModeSendersImagePreferenceController(context,
+ "zen_mode_calls_image", lifecycle, false));
controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
context.getResources().getInteger(com.android.internal.R.integer
.config_zen_repeat_callers_threshold)));
diff --git a/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
index d15a4aa428b..f8e4548f53f 100644
--- a/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
@@ -44,6 +44,8 @@ public class ZenModeMessagesSettings extends ZenModeSettingsBase {
private static List buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
List controllers = new ArrayList<>();
+ controllers.add(new ZenModeSendersImagePreferenceController(context,
+ "zen_mode_messages_image", lifecycle, true));
controllers.add(new ZenModePrioritySendersPreferenceController(context,
"zen_mode_settings_category_messages", lifecycle, true));
controllers.add(new ZenModeBehaviorFooterPreferenceController(
diff --git a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
index da7b24d7d33..226ce155af3 100644
--- a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
@@ -58,7 +58,7 @@ public class ZenModePrioritySendersPreferenceController
@VisibleForTesting static final String KEY_NONE = "senders_none";
private static final Intent ALL_CONTACTS_INTENT =
- new Intent(Contacts.Intents.UI.LIST_ALL_CONTACTS_ACTION);
+ new Intent(Contacts.Intents.UI.LIST_DEFAULT);
private static final Intent STARRED_CONTACTS_INTENT =
new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
private static final Intent FALLBACK_INTENT = new Intent(Intent.ACTION_MAIN);
diff --git a/src/com/android/settings/notification/zen/ZenModeSendersImagePreferenceController.java b/src/com/android/settings/notification/zen/ZenModeSendersImagePreferenceController.java
new file mode 100644
index 00000000000..e8cd40db63a
--- /dev/null
+++ b/src/com/android/settings/notification/zen/ZenModeSendersImagePreferenceController.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification.zen;
+
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+
+import android.content.Context;
+import android.widget.ImageView;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
+
+/**
+ * Common preference controller functionality shared by
+ * ZenModeCallsSettings and ZenModeMessagesSettings.
+ *
+ * Changes the image resource based on the selected senders allowed to bypass DND option for
+ * calls or messages.
+ */
+public class ZenModeSendersImagePreferenceController
+ extends AbstractZenModePreferenceController {
+
+ private final boolean mIsMessages; // if this is false, then this preference is for calls
+
+ private ImageView mImageView;
+
+ public ZenModeSendersImagePreferenceController(Context context, String key,
+ Lifecycle lifecycle, boolean isMessages) {
+ super(context, key, lifecycle);
+ mIsMessages = isMessages;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ LayoutPreference pref = (LayoutPreference) screen.findPreference(KEY);
+ mImageView = (ImageView) pref.findViewById(R.id.zen_mode_settings_senders_image);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ final int currSetting = getPrioritySenders();
+ int newImageRes;
+ CharSequence newContentDescription = "";
+ if (PRIORITY_SENDERS_ANY == currSetting) {
+ newImageRes = mIsMessages
+ ? R.drawable.zen_messages_any
+ : R.drawable.zen_calls_any;
+ newContentDescription = mContext.getString(R.string.zen_mode_from_anyone);
+ } else if (PRIORITY_SENDERS_CONTACTS == currSetting) {
+ newImageRes = mIsMessages
+ ? R.drawable.zen_messages_contacts
+ : R.drawable.zen_calls_contacts;
+ newContentDescription = mContext.getString(R.string.zen_mode_from_contacts);
+ } else if (PRIORITY_SENDERS_STARRED == currSetting) {
+ newImageRes = mIsMessages
+ ? R.drawable.zen_messages_starred
+ : R.drawable.zen_calls_starred;
+ newContentDescription = mContext.getString(R.string.zen_mode_from_starred);
+ } else {
+ newImageRes = mIsMessages
+ ? R.drawable.zen_messages_none
+ : R.drawable.zen_calls_none;
+ newContentDescription = mContext.getString(R.string.zen_mode_from_none);
+ }
+
+ mImageView.setImageResource(newImageRes);
+ mImageView.setContentDescription(newContentDescription);
+ }
+
+ private int getPrioritySenders() {
+ if (mIsMessages) {
+ return mBackend.getPriorityMessageSenders();
+ } else {
+ return mBackend.getPriorityCallSenders();
+ }
+ }
+}
diff --git a/src/com/android/settings/wifi/WifiDialog2.java b/src/com/android/settings/wifi/WifiDialog2.java
index acd6f17d36b..dc546f3c231 100644
--- a/src/com/android/settings/wifi/WifiDialog2.java
+++ b/src/com/android/settings/wifi/WifiDialog2.java
@@ -214,4 +214,8 @@ public class WifiDialog2 extends AlertDialog implements WifiConfigUiBase2,
public void setCancelButton(CharSequence text) {
setButton(BUTTON_NEGATIVE, text, this);
}
+
+ public WifiEntry getWifiEntry() {
+ return mWifiEntry;
+ }
}
diff --git a/src/com/android/settings/wifi/WifiSettings2.java b/src/com/android/settings/wifi/WifiSettings2.java
index 13ccdc3695b..f73891dfb53 100644
--- a/src/com/android/settings/wifi/WifiSettings2.java
+++ b/src/com/android/settings/wifi/WifiSettings2.java
@@ -647,6 +647,7 @@ public class WifiSettings2 extends RestrictedSettingsFragment
setOffMessage();
setAdditionalSettingsSummaries();
setProgressBarVisible(false);
+ mClickedConnect = false;
break;
}
}
@@ -739,6 +740,11 @@ public class WifiSettings2 extends RestrictedSettingsFragment
pref.setOnGearClickListener(preference -> {
launchNetworkDetailsFragment(pref);
});
+
+ if (mClickedConnect) {
+ mClickedConnect = false;
+ scrollToPreference(mConnectedWifiEntryPreferenceCategory);
+ }
}
} else {
mConnectedWifiEntryPreferenceCategory.removeAll();
@@ -954,18 +960,30 @@ public class WifiSettings2 extends RestrictedSettingsFragment
@Override
public void onForget(WifiDialog2 dialog) {
- forget(mDialogWifiEntry);
+ forget(dialog.getWifiEntry());
}
@Override
public void onSubmit(WifiDialog2 dialog) {
- final int dialogMode = mDialog.getController().getMode();
+ final int dialogMode = dialog.getMode();
+ final WifiConfiguration config = dialog.getController().getConfig();
+ final WifiEntry wifiEntry = dialog.getWifiEntry();
if (dialogMode == WifiConfigUiBase2.MODE_MODIFY) {
- mWifiManager.save(mDialogWifiEntry.getWifiConfiguration(), mSaveListener);
+ if (config == null) {
+ Toast.makeText(getContext(), R.string.wifi_failed_save_message,
+ Toast.LENGTH_SHORT).show();
+ } else {
+ mWifiManager.save(config, mSaveListener);
+ }
} else if (dialogMode == WifiConfigUiBase2.MODE_CONNECT
- || (dialogMode == WifiConfigUiBase2.MODE_VIEW && mDialogWifiEntry.canConnect())) {
- connect(mDialogWifiEntry, false /* editIfNoConfig */, false /* fullScreenEdit*/);
+ || (dialogMode == WifiConfigUiBase2.MODE_VIEW && wifiEntry.canConnect())) {
+ if (config == null) {
+ connect(wifiEntry, false /* editIfNoConfig */,
+ false /* fullScreenEdit*/);
+ } else {
+ mWifiManager.connect(config, new WifiConnectActionListener());
+ }
}
}
@@ -981,7 +999,8 @@ public class WifiSettings2 extends RestrictedSettingsFragment
wifiEntry.forget(null /* callback */);
}
- private void connect(WifiEntry wifiEntry, boolean editIfNoConfig, boolean fullScreenEdit) {
+ @VisibleForTesting
+ void connect(WifiEntry wifiEntry, boolean editIfNoConfig, boolean fullScreenEdit) {
mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_CONNECT,
wifiEntry.isSaved());
@@ -994,7 +1013,7 @@ public class WifiSettings2 extends RestrictedSettingsFragment
private class WifiConnectActionListener implements WifiManager.ActionListener {
@Override
public void onSuccess() {
- // Do nothing.
+ mClickedConnect = true;
}
@Override
@@ -1028,13 +1047,15 @@ public class WifiSettings2 extends RestrictedSettingsFragment
return;
}
- if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
+ if (status == ConnectCallback.CONNECT_STATUS_SUCCESS) {
+ mClickedConnect = true;
+ } else if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
if (mEditIfNoConfig) {
// Edit an unsaved secure Wi-Fi network.
if (mFullScreenEdit) {
launchConfigNewNetworkFragment(mConnectWifiEntry);
} else {
- showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_MODIFY);
+ showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_CONNECT);
}
}
} else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
index 96aae0ea4bb..735fecc9c9a 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
@@ -54,9 +54,7 @@ import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.ims.WifiCallingQueryImsState;
-import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.widget.SwitchBar;
/**
@@ -100,7 +98,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
private boolean mUseWfcHomeModeForRoaming = false;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private com.android.ims.ImsManager mImsManager;
private ImsMmTelManager mImsMmTelManager;
private ProvisioningManager mProvisioningManager;
private TelephonyManager mTelephonyManager;
@@ -119,8 +116,9 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
queryImsState(WifiCallingSettingsForSub.this.mSubId).isAllowUserControl();
final boolean isWfcEnabled = mSwitchBar.isChecked()
&& isNonTtyOrTtyOnVolteEnabled;
- boolean isCallStateIdle =
- mTelephonyManager.getCallState() == TelephonyManager.CALL_STATE_IDLE;
+ boolean isCallStateIdle = getTelephonyManagerForSub(
+ WifiCallingSettingsForSub.this.mSubId).getCallState()
+ == TelephonyManager.CALL_STATE_IDLE;
mSwitchBar.setEnabled(isCallStateIdle
&& isNonTtyOrTtyOnVolteEnabled);
@@ -201,7 +199,8 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
mSwitchBar.hide();
}
- private void showAlert(Intent intent) {
+ @VisibleForTesting
+ void showAlert(Intent intent) {
final Context context = getActivity();
final CharSequence title = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_TITLE);
@@ -247,6 +246,14 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
return 0;
}
+ @VisibleForTesting
+ TelephonyManager getTelephonyManagerForSub(int subId) {
+ if (mTelephonyManager == null) {
+ mTelephonyManager = getContext().getSystemService(TelephonyManager.class);
+ }
+ return mTelephonyManager.createForSubscriptionId(subId);
+ }
+
@VisibleForTesting
WifiCallingQueryImsState queryImsState(int subId) {
return new WifiCallingQueryImsState(getContext(), subId);
@@ -260,12 +267,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
return ProvisioningManager.createForSubscriptionId(mSubId);
}
- @VisibleForTesting
- com.android.ims.ImsManager getImsManager() {
- return com.android.ims.ImsManager.getInstance(getActivity(),
- SubscriptionUtil.getPhoneId(getActivity(), mSubId));
- }
-
@VisibleForTesting
ImsMmTelManager getImsMmTelManager() {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
@@ -289,12 +290,9 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
- mImsManager = getImsManager();
mProvisioningManager = getImsProvisioningManager();
mImsMmTelManager = getImsMmTelManager();
- mTelephonyManager = getActivity().getSystemService(TelephonyManager.class);
-
mButtonWfcMode = findPreference(BUTTON_WFC_MODE);
mButtonWfcMode.setOnPreferenceChangeListener(this);
@@ -331,7 +329,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
@VisibleForTesting
boolean isWfcProvisionedOnDevice() {
- return MobileNetworkUtils.isWfcProvisionedOnDevice(mSubId);
+ return queryImsState(mSubId).isWifiCallingProvisioned();
}
private void updateBody() {
@@ -420,7 +418,8 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
updateBody();
if (queryImsState(mSubId).isWifiCallingSupported()) {
- mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+ getTelephonyManagerForSub(mSubId).listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_CALL_STATE);
mSwitchBar.addOnSwitchChangeListener(this);
@@ -448,7 +447,8 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
if (mValidListener) {
mValidListener = false;
- mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+ getTelephonyManagerForSub(mSubId).listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_NONE);
mSwitchBar.removeOnSwitchChangeListener(this);
}
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSuggestionActivity.java b/src/com/android/settings/wifi/calling/WifiCallingSuggestionActivity.java
index 0e3b8872d27..6b6eebfe3a0 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSuggestionActivity.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSuggestionActivity.java
@@ -19,10 +19,8 @@ package com.android.settings.wifi.calling;
import android.content.Context;
import android.telephony.SubscriptionManager;
-import com.android.ims.ImsManager;
import com.android.settings.SettingsActivity;
import com.android.settings.network.ims.WifiCallingQueryImsState;
-import com.android.settings.network.telephony.MobileNetworkUtils;
public class WifiCallingSuggestionActivity extends SettingsActivity {
@@ -30,11 +28,7 @@ public class WifiCallingSuggestionActivity extends SettingsActivity {
final WifiCallingQueryImsState queryState =
new WifiCallingQueryImsState(context,
SubscriptionManager.getDefaultVoiceSubscriptionId());
- if (!ImsManager.isWfcEnabledByPlatform(context) ||
- !MobileNetworkUtils.isWfcProvisionedOnDevice(
- SubscriptionManager.getDefaultVoiceSubscriptionId())) {
- return true;
- }
- return queryState.isEnabledByUser() && queryState.isAllowUserControl();
+ return (!queryState.isWifiCallingProvisioned())
+ || (queryState.isEnabledByUser() && queryState.isAllowUserControl());
}
}
diff --git a/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceControllerTest.java
deleted file mode 100644
index 2226e2c4e1d..00000000000
--- a/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceControllerTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accounts;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.robolectric.RuntimeEnvironment.application;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.os.UserHandle;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
-import org.robolectric.shadows.ShadowDevicePolicyManager;
-
-import java.util.Collections;
-
-@RunWith(RobolectricTestRunner.class)
-public class CrossProfileCalendarDisabledPreferenceControllerTest {
-
- private static final String PREF_KEY = "cross_profile_calendar_disabled";
- private static final int MANAGED_USER_ID = 10;
- private static final String TEST_PACKAGE_NAME = "com.test";
- private static final ComponentName TEST_COMPONENT_NAME = new ComponentName("test", "test");
-
- @Mock
- private UserHandle mManagedUser;
-
- private Context mContext;
- private CrossProfileCalendarDisabledPreferenceController mController;
- private ShadowDevicePolicyManager mDpm;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
- mController = new CrossProfileCalendarDisabledPreferenceController(mContext, PREF_KEY);
- mController.setManagedUser(mManagedUser);
- mDpm = Shadows.shadowOf(application.getSystemService(DevicePolicyManager.class));
-
- when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
- doReturn(mContext).when(mContext).createPackageContextAsUser(
- any(String.class), anyInt(), any(UserHandle.class));
- }
-
- @Test
- public void getAvailabilityStatus_noPackageAllowed_shouldBeAvailable() {
- mDpm.setProfileOwner(TEST_COMPONENT_NAME);
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
- }
-
- @Test
- public void getAvailabilityStatus_somePackagesAllowed_shouldBeDisabledForUser() {
- mDpm.setProfileOwner(TEST_COMPONENT_NAME);
- mDpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME,
- Collections.singleton(TEST_PACKAGE_NAME));
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
- }
-
- @Test
- public void getAvailabilityStatus_allPackagesAllowed_shouldBeDisabledForUser() {
- mDpm.setProfileOwner(TEST_COMPONENT_NAME);
- mDpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME, null);
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
- }
-}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
index 9e48b9ea3bb..bae9a12670b 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
@@ -22,14 +22,18 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.AppOpsManager;
import android.content.Context;
+import android.content.pm.CrossProfileApps;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
-import android.os.Process;
+import android.content.pm.UserInfo;
+import android.os.UserManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -37,6 +41,9 @@ import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class InteractAcrossProfilesDetailsTest {
+ private static final int PERSONAL_PROFILE_ID = 0;
+ private static final int WORK_PROFILE_ID = 10;
+ private static final int PACKAGE_UID = 0;
private static final String CROSS_PROFILE_PACKAGE_NAME = "crossProfilePackage";
public static final String INTERACT_ACROSS_PROFILES_PERMISSION =
"android.permission.INTERACT_ACROSS_PROFILES";
@@ -44,29 +51,53 @@ public class InteractAcrossProfilesDetailsTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
private final PackageManager mPackageManager = mContext.getPackageManager();
- private final InteractAcrossProfilesDetails mFragment = new InteractAcrossProfilesDetails();
+ private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
+ private final CrossProfileApps mCrossProfileApps = mContext.getSystemService(
+ CrossProfileApps.class);
@Test
public void getPreferenceSummary_appOpAllowed_returnsAllowed() {
+ shadowOf(mUserManager).addUser(
+ PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
+ shadowOf(mUserManager).addProfile(
+ PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
+ "work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ PERSONAL_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ WORK_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
+ shadowOf(mCrossProfileApps).addCrossProfilePackage(
+ CROSS_PROFILE_PACKAGE_NAME);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
- appOp, Process.myUid(), CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
+ appOp, PACKAGE_UID, CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
- assertThat(mFragment.getPreferenceSummary(
- mContext, CROSS_PROFILE_PACKAGE_NAME, Process.myUid()))
+ assertThat(InteractAcrossProfilesDetails.getPreferenceSummary(
+ mContext, CROSS_PROFILE_PACKAGE_NAME))
.isEqualTo(mContext.getString(R.string.app_permission_summary_allowed));
}
@Test
public void getPreferenceSummary_appOpNotAllowed_returnsNotAllowed() {
+ shadowOf(mUserManager).addUser(
+ PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
+ shadowOf(mUserManager).addProfile(
+ PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
+ "work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ PERSONAL_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ WORK_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
+ shadowOf(mCrossProfileApps).addCrossProfilePackage(
+ CROSS_PROFILE_PACKAGE_NAME);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
- appOp, Process.myUid(), CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
+ appOp, PACKAGE_UID, CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
- assertThat(mFragment.getPreferenceSummary(
- mContext, CROSS_PROFILE_PACKAGE_NAME, Process.myUid()))
+ assertThat(InteractAcrossProfilesDetails.getPreferenceSummary(
+ mContext, CROSS_PROFILE_PACKAGE_NAME))
.isEqualTo(mContext.getString(R.string.app_permission_summary_not_allowed));
}
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesPreferenceControllerTest.java
index bac7437d81d..8479035804b 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesPreferenceControllerTest.java
@@ -21,12 +21,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
-import android.content.pm.CrossProfileApps;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -36,25 +39,34 @@ public class InteractAcrossProfilesPreferenceControllerTest {
private static final String CROSS_PROFILE_PACKAGE_NAME = "crossProfilePackage";
private static final String NOT_CROSS_PROFILE_PACKAGE_NAME = "notCrossProfilePackage";
+ public static final String INTERACT_ACROSS_PROFILES_PERMISSION =
+ "android.permission.INTERACT_ACROSS_PROFILES";
+ private static final int PROFILE_ID = 0;
private final Context mContext = ApplicationProvider.getApplicationContext();
- private final CrossProfileApps mCrossProfileApps =
- mContext.getSystemService(CrossProfileApps.class);
+ private final PackageManager mPackageManager = mContext.getPackageManager();
private final InteractAcrossProfilesDetailsPreferenceController mController =
new InteractAcrossProfilesDetailsPreferenceController(mContext, "test_key");
@Test
- public void getAvailabilityStatus_crossProfilePackage_returnsAvailable() {
+ public void getAvailabilityStatus_requestedCrossProfilePermission_returnsAvailable() {
mController.setPackageName(CROSS_PROFILE_PACKAGE_NAME);
- shadowOf(mCrossProfileApps).addCrossProfilePackage(CROSS_PROFILE_PACKAGE_NAME);
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
+ PackageInfo packageInfo = shadowOf(mPackageManager).getInternalMutablePackageInfo(
+ CROSS_PROFILE_PACKAGE_NAME);
+ packageInfo.requestedPermissions = new String[]{
+ INTERACT_ACROSS_PROFILES_PERMISSION};
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
- public void getAvailabilityStatus_notCrossProfilePackage_returnsDisabled() {
+ public void getAvailabilityStatus_notRequestedCrossProfilePermission_returnsDisabled() {
mController.setPackageName(NOT_CROSS_PROFILE_PACKAGE_NAME);
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ PROFILE_ID, ImmutableList.of(NOT_CROSS_PROFILE_PACKAGE_NAME));
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.DISABLED_FOR_USER);
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java
index 19ea50b6572..dac3e22913f 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java
@@ -18,14 +18,17 @@ package com.android.settings.applications.specialaccess.interactacrossprofiles;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.CrossProfileApps;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
+import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Pair;
@@ -68,49 +71,56 @@ public class InteractAcrossProfilesSettingsTest {
private final CrossProfileApps mCrossProfileApps =
mContext.getSystemService(CrossProfileApps.class);
private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
- private final InteractAcrossProfilesSettings mFragment = new InteractAcrossProfilesSettings();
@Test
- public void collectConfigurableApps_fromPersonal_returnsPersonalPackages() {
+ public void collectConfigurableApps_fromPersonal_returnsCombinedPackages() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
- "work-profile"/* profileName */, 0/* profileFlags */);
+ "work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
- shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
- shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
+ installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
+ installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
- List> apps = mFragment.collectConfigurableApps(
- mPackageManager, mUserManager, mCrossProfileApps);
+ List> apps =
+ InteractAcrossProfilesSettings.collectConfigurableApps(
+ mPackageManager, mUserManager, mCrossProfileApps);
- assertThat(apps.size()).isEqualTo(1);
- assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
+ assertThat(apps.size()).isEqualTo(2);
+ assertTrue(apps.stream().anyMatch(
+ app -> app.first.packageName.equals(PERSONAL_CROSS_PROFILE_PACKAGE)));
+ assertTrue(apps.stream().anyMatch(
+ app -> app.first.packageName.equals(WORK_CROSS_PROFILE_PACKAGE)));
}
@Test
- public void collectConfigurableApps_fromWork_returnsPersonalPackages() {
+ public void collectConfigurableApps_fromWork_returnsCombinedPackages() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
- "work-profile"/* profileName */, 0/* profileFlags */);
+ "work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
ShadowProcess.setUid(WORK_UID);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
- shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
- shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
+ installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
+ installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
- List> apps = mFragment.collectConfigurableApps(
- mPackageManager, mUserManager, mCrossProfileApps);
+ List> apps =
+ InteractAcrossProfilesSettings.collectConfigurableApps(
+ mPackageManager, mUserManager, mCrossProfileApps);
- assertThat(apps.size()).isEqualTo(1);
- assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
+ assertThat(apps.size()).isEqualTo(2);
+ assertTrue(apps.stream().anyMatch(
+ app -> app.first.packageName.equals(PERSONAL_CROSS_PROFILE_PACKAGE)));
+ assertTrue(apps.stream().anyMatch(
+ app -> app.first.packageName.equals(WORK_CROSS_PROFILE_PACKAGE)));
}
@Test
@@ -119,10 +129,11 @@ public class InteractAcrossProfilesSettingsTest {
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
- shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
+ installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
- List> apps = mFragment.collectConfigurableApps(
- mPackageManager, mUserManager, mCrossProfileApps);
+ List> apps =
+ InteractAcrossProfilesSettings.collectConfigurableApps(
+ mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps).isEmpty();
}
@@ -133,11 +144,14 @@ public class InteractAcrossProfilesSettingsTest {
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
- "work-profile"/* profileName */, 0/* profileFlags */);
+ "work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
+ installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
+ installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
- shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_NON_CROSS_PROFILE_PACKAGE);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
appOp, PACKAGE_UID, PERSONAL_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_ALLOWED);
@@ -145,12 +159,19 @@ public class InteractAcrossProfilesSettingsTest {
appOp, PACKAGE_UID, PERSONAL_NON_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_IGNORED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
- int numOfApps = mFragment.getNumberOfEnabledApps(
+ int numOfApps = InteractAcrossProfilesSettings.getNumberOfEnabledApps(
mContext, mPackageManager, mUserManager, mCrossProfileApps);
assertThat(numOfApps).isEqualTo(1);
}
+ private void installCrossProfilePackage(int profileId, String packageName) {
+ PackageInfo personalPackageInfo = shadowOf(mPackageManager).getInternalMutablePackageInfo(
+ packageName);
+ personalPackageInfo.requestedPermissions = new String[]{
+ INTERACT_ACROSS_PROFILES_PERMISSION};
+ }
+
private PermissionInfo createCrossProfilesPermissionInfo() {
PermissionInfo permissionInfo = new PermissionInfo();
permissionInfo.name = INTERACT_ACROSS_PROFILES_PERMISSION;
diff --git a/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java
index af1031da07f..abea839791e 100644
--- a/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java
+++ b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java
@@ -19,9 +19,6 @@ package com.android.settings.network.ims;
import android.content.Context;
import android.telephony.ims.ImsException;
-import com.android.ims.ImsManager;
-
-
/**
* Controller class for mock Wifi calling status
*/
@@ -30,6 +27,7 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsEnabledOnPlatform;
private Boolean mIsProvisionedOnDevice;
+ private Boolean mIsServiceStateReady;
private Boolean mIsEnabledByUser;
/**
@@ -42,10 +40,6 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
super(context, subId);
}
- public ImsManager getImsManager(int subId) {
- return super.getImsManager(subId);
- }
-
public void setIsTtyOnVolteEnabled(boolean enabled) {
mIsTtyOnVolteEnabled = enabled;
}
@@ -84,6 +78,19 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
return super.isProvisionedOnDevice(subId);
}
+ public void setServiceStateReady(boolean isReady) {
+ mIsServiceStateReady = isReady;
+ }
+
+ @Override
+ boolean isServiceStateReady(int subId) throws InterruptedException, ImsException,
+ IllegalArgumentException {
+ if (mIsServiceStateReady != null) {
+ return mIsServiceStateReady;
+ }
+ return super.isServiceStateReady(subId);
+ }
+
public void setIsEnabledByUser(boolean enabled) {
mIsEnabledByUser = enabled;
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
index b91f7188aef..dbfd3b24766 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
@@ -37,7 +37,6 @@ import android.telephony.ims.ImsMmTelManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import com.android.ims.ImsManager;
import com.android.internal.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.ims.MockWifiCallingQueryImsState;
@@ -60,8 +59,6 @@ public class WifiCallingPreferenceControllerTest {
@Mock
private TelephonyManager mTelephonyManager;
@Mock
- private ImsManager mImsManager;
- @Mock
private ImsMmTelManager mImsMmTelManager;
@Mock
private PreferenceScreen mPreferenceScreen;
@@ -79,9 +76,8 @@ public class WifiCallingPreferenceControllerTest {
mContext = spy(RuntimeEnvironment.application);
- mQueryImsState = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID));
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- doReturn(mImsManager).when(mQueryImsState).getImsManager(anyInt());
+ mQueryImsState = new MockWifiCallingQueryImsState(mContext, SUB_ID);
+ mQueryImsState.setIsEnabledByUser(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mPreference = new Preference(mContext);
@@ -109,7 +105,7 @@ public class WifiCallingPreferenceControllerTest {
@Test
public void updateState_noSimCallManager_setCorrectSummary() {
mController.mSimCallManager = null;
- doReturn(true).when(mQueryImsState).isEnabledByUser();
+ mQueryImsState.setIsEnabledByUser(true);
when(mImsMmTelManager.getVoWiFiRoamingModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_ONLY);
when(mImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
@@ -149,7 +145,7 @@ public class WifiCallingPreferenceControllerTest {
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED);
- doReturn(true).when(mQueryImsState).isEnabledByUser();
+ mQueryImsState.setIsEnabledByUser(true);
when(mTelephonyManager.isNetworkRoaming()).thenReturn(true);
mController.updateState(mPreference);
@@ -166,7 +162,7 @@ public class WifiCallingPreferenceControllerTest {
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED);
- doReturn(true).when(mQueryImsState).isEnabledByUser();
+ mQueryImsState.setIsEnabledByUser(true);
when(mTelephonyManager.isNetworkRoaming()).thenReturn(true);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationPeopleStripPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationPeopleStripPreferenceControllerTest.java
deleted file mode 100644
index 786ffb37ae7..00000000000
--- a/tests/robotests/src/com/android/settings/notification/NotificationPeopleStripPreferenceControllerTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification;
-
-import static android.provider.Settings.Secure.PEOPLE_STRIP;
-
-import static com.android.settings.notification.NotificationPeopleStripPreferenceController.OFF;
-import static com.android.settings.notification.NotificationPeopleStripPreferenceController.ON;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.TwoStatePreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class NotificationPeopleStripPreferenceControllerTest {
-
- private static final String KEY_PEOPLE_STRIP = "notification_people_strip";
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private PreferenceScreen mScreen;
-
- private NotificationPeopleStripPreferenceController mController;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mController = new NotificationPeopleStripPreferenceController(mContext, KEY_PEOPLE_STRIP);
- Preference preference = new Preference(RuntimeEnvironment.application);
- preference.setKey(mController.getPreferenceKey());
- when(mScreen.findPreference(preference.getKey())).thenReturn(preference);
- }
-
- @Test
- public void updateState_preferenceSetCheckedWhenSettingIsOn() {
- final TwoStatePreference preference = mock(TwoStatePreference.class);
- final Context context = RuntimeEnvironment.application;
- Settings.Secure.putInt(context.getContentResolver(), PEOPLE_STRIP, ON);
-
- mController = new NotificationPeopleStripPreferenceController(context, KEY_PEOPLE_STRIP);
- mController.updateState(preference);
-
- verify(preference).setChecked(true);
- }
-
- @Test
- public void updateState_preferenceSetUncheckedWhenSettingIsOff() {
- final TwoStatePreference preference = mock(TwoStatePreference.class);
- final Context context = RuntimeEnvironment.application;
- Settings.Secure.putInt(context.getContentResolver(), PEOPLE_STRIP, OFF);
-
- mController = new NotificationPeopleStripPreferenceController(context, KEY_PEOPLE_STRIP);
- mController.updateState(preference);
-
- verify(preference).setChecked(false);
- }
-
- @Test
- public void isChecked_settingIsOff_shouldReturnFalse() {
- Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, OFF);
-
- assertThat(mController.isChecked()).isFalse();
- }
-
- @Test
- public void isChecked_settingIsOn_shouldReturnTrue() {
- Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, ON);
-
- assertThat(mController.isChecked()).isTrue();
- }
-
- @Test
- public void setChecked_setFalse_disablesSetting() {
- Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, ON);
-
- mController.setChecked(false);
- int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(), PEOPLE_STRIP, -1);
-
- assertThat(updatedValue).isEqualTo(OFF);
- }
-
- @Test
- public void setChecked_setTrue_enablesSetting() {
- Settings.Secure.putInt(mContext.getContentResolver(), PEOPLE_STRIP, OFF);
-
- mController.setChecked(true);
- int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(), PEOPLE_STRIP, -1);
-
- assertThat(updatedValue).isEqualTo(ON);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java
index bd6b20f71d0..b259cc39b4f 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java
@@ -15,6 +15,9 @@
*/
package com.android.settings.wifi;
+import static com.android.settings.wifi.WifiConfigUiBase2.MODE_CONNECT;
+import static com.android.settings.wifi.WifiConfigUiBase2.MODE_MODIFY;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -34,6 +37,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.PowerManager;
@@ -64,6 +68,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowToast;
@RunWith(RobolectricTestRunner.class)
public class WifiSettings2Test {
@@ -303,4 +308,57 @@ public class WifiSettings2Test {
mWifiSettings2.onNumSavedSubscriptionsChanged();
}
+
+ @Test
+ public void onSubmit_modeModifyNoConfig_toastErrorMessage() {
+ WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, null /* config */);
+
+ mWifiSettings2.onSubmit(dialog);
+
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_failed_save_message));
+ }
+
+ @Test
+ public void onSubmit_modeModifyHasConfig_saveWifiManager() {
+ final WifiConfiguration config = mock(WifiConfiguration.class);
+ WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, config);
+
+ mWifiSettings2.onSubmit(dialog);
+
+ verify(mWifiManager).save(eq(config), any());
+ }
+
+ @Test
+ public void onSubmit_modeConnectNoConfig_connectWifiEntry() {
+ WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, null /* config */);
+ final WifiEntry wifiEntry = dialog.getWifiEntry();
+
+ mWifiSettings2.onAttach(mContext);
+ mWifiSettings2.onSubmit(dialog);
+
+ verify(mWifiSettings2).connect(wifiEntry, false /* editIfNoConfig */,
+ false /* fullScreenEdit*/);
+ }
+
+ @Test
+ public void onSubmit_modeConnectHasConfig_connectWifiManager() {
+ final WifiConfiguration config = mock(WifiConfiguration.class);
+ WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, config);
+
+ mWifiSettings2.onSubmit(dialog);
+
+ verify(mWifiManager).connect(eq(config), any(WifiManager.ActionListener.class));
+ }
+
+ private WifiDialog2 createWifiDialog2(int mode, WifiConfiguration config) {
+ final WifiEntry wifiEntry = mock(WifiEntry.class);
+ when(wifiEntry.canConnect()).thenReturn(true);
+ final WifiConfigController2 controller = mock(WifiConfigController2.class);
+ when(controller.getConfig()).thenReturn(config);
+ final WifiDialog2 wifiDialog2 = spy(WifiDialog2.createModal(mContext, null /* listener */,
+ wifiEntry, mode));
+ when(wifiDialog2.getController()).thenReturn(controller);
+ return wifiDialog2;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
index 5b76adc84c5..2e93faac27e 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
@@ -50,16 +50,15 @@ import android.widget.TextView;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsManager;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
+import com.android.settings.network.ims.MockWifiCallingQueryImsState;
+import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.widget.SwitchBar;
import com.android.settings.widget.ToggleSwitch;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -73,6 +72,8 @@ import org.robolectric.util.ReflectionHelpers;
@Config(shadows = ShadowFragment.class)
@RunWith(RobolectricTestRunner.class)
public class WifiCallingSettingsForSubTest {
+ private static final int SUB_ID = 2;
+
private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode";
private static final String TEST_EMERGENCY_ADDRESS_CARRIER_APP =
@@ -83,9 +84,10 @@ public class WifiCallingSettingsForSubTest {
private TextView mEmptyView;
private final PersistableBundle mBundle = new PersistableBundle();
+ private MockWifiCallingQueryImsState mQueryImsState;
+
@Mock private static CarrierConfigManager sCarrierConfigManager;
@Mock private CarrierConfigManager mMockConfigManager;
- @Mock private ImsManager mImsManager;
@Mock private ImsMmTelManager mImsMmTelManager;
@Mock private TelephonyManager mTelephonyManager;
@Mock private PreferenceScreen mPreferenceScreen;
@@ -93,7 +95,6 @@ public class WifiCallingSettingsForSubTest {
@Mock private SwitchBar mSwitchBar;
@Mock private ToggleSwitch mToggleSwitch;
@Mock private View mView;
- @Mock private ImsConfig mImsConfig;
@Mock private ListWithEntrySummaryPreference mButtonWfcMode;
@Mock private ListWithEntrySummaryPreference mButtonWfcRoamingMode;
@Mock private Preference mUpdateAddress;
@@ -127,12 +128,13 @@ public class WifiCallingSettingsForSubTest {
ReflectionHelpers.setField(mSwitchBar, "mSwitch", mToggleSwitch);
doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar);
- doReturn(mImsManager).when(mFragment).getImsManager();
+ mQueryImsState = new MockWifiCallingQueryImsState(mContext, SUB_ID);
+
doReturn(mImsMmTelManager).when(mFragment).getImsMmTelManager();
- doReturn(mImsConfig).when(mImsManager).getConfigInterface();
- doReturn(true).when(mFragment).isWfcProvisionedOnDevice();
- doReturn(true).when(mImsManager).isWfcEnabledByUser();
- doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByPlatform(true);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager).getVoWiFiModeSetting();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
@@ -178,7 +180,7 @@ public class WifiCallingSettingsForSubTest {
@Test
public void onResume_provisioningDisallowed_shouldFinish() {
// Call onResume while provisioning is disallowed.
- doReturn(false).when(mFragment).isWfcProvisionedOnDevice();
+ mQueryImsState.setIsProvisionedOnDevice(false);
mFragment.onResume();
// Verify that finish() is called
@@ -197,7 +199,6 @@ public class WifiCallingSettingsForSubTest {
}
@Test
- @Ignore
public void onResume_useWfcHomeModeConfigFalseAndEditable_shouldShowWfcRoaming() {
// Call onResume to update the WFC roaming preference.
mFragment.onResume();
@@ -351,5 +352,18 @@ public class WifiCallingSettingsForSubTest {
return null;
}
}
+
+ @Override
+ TelephonyManager getTelephonyManagerForSub(int subId) {
+ return mTelephonyManager;
+ }
+
+ @Override
+ WifiCallingQueryImsState queryImsState(int subId) {
+ return mQueryImsState;
+ }
+
+ @Override
+ void showAlert(Intent intent) {}
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java
index 90633cb8d6b..1ba8e7a44fa 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java
@@ -18,7 +18,6 @@ package com.android.settings.wifi.calling;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -72,12 +71,10 @@ public class WifiCallingSettingsTest {
mContext = spy(RuntimeEnvironment.application);
- mQueryImsState1 = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID1));
- mQueryImsState2 = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID2));
- doReturn(true).when(mQueryImsState1).isEnabledByUser();
- doReturn(true).when(mQueryImsState2).isEnabledByUser();
- doReturn(mImsManager).when(mQueryImsState1).getImsManager(anyInt());
- doReturn(mImsManager).when(mQueryImsState2).getImsManager(anyInt());
+ mQueryImsState1 = new MockWifiCallingQueryImsState(mContext, SUB_ID1);
+ mQueryImsState2 = new MockWifiCallingQueryImsState(mContext, SUB_ID2);
+ mQueryImsState1.setIsEnabledByUser(true);
+ mQueryImsState2.setIsEnabledByUser(true);
mQueryImsState1.setIsEnabledByPlatform(true);
mQueryImsState2.setIsEnabledByPlatform(true);
mQueryImsState1.setIsProvisionedOnDevice(true);
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
index f537be32c3e..0013234c950 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
@@ -47,7 +47,7 @@ import androidx.slice.widget.SliceLiveData;
import com.android.ims.ImsManager;
import com.android.settings.R;
-import com.android.settings.network.ims.WifiCallingQueryImsState;
+import com.android.settings.network.ims.MockWifiCallingQueryImsState;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.SettingsSliceProvider;
import com.android.settings.slices.SliceBroadcastReceiver;
@@ -81,7 +81,7 @@ public class WifiCallingSliceHelperTest {
@Mock
private ImsMmTelManager mMockImsMmTelManager;
- private WifiCallingQueryImsState mQueryImsState;
+ private MockWifiCallingQueryImsState mQueryImsState;
private FakeWifiCallingSliceHelper mWfcSliceHelper;
private SettingsSliceProvider mProvider;
@@ -105,9 +105,10 @@ public class WifiCallingSliceHelperTest {
mFeatureFactory = FakeFeatureFactory.setupForTest();
mSlicesFeatureProvider = mFeatureFactory.getSlicesFeatureProvider();
- mQueryImsState = spy(new WifiCallingQueryImsState(mContext, SUB_ID));
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
+ mQueryImsState = new MockWifiCallingQueryImsState(mContext, SUB_ID);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsEnabledByPlatform(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
mWfcSliceHelper = spy(new FakeWifiCallingSliceHelper(mContext));
doReturn(mQueryImsState).when(mWfcSliceHelper).queryImsState(anyInt());
@@ -118,8 +119,8 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingSlice_invalidSubId() {
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- doReturn(false).when(mQueryImsState).isWifiCallingProvisioned();
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsProvisionedOnDevice(false);
mWfcSliceHelper.setDefaultVoiceSubId(-1);
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
@@ -130,7 +131,7 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingSlice_wfcNotSupported() {
- doReturn(false).when(mQueryImsState).isWifiCallingProvisioned();
+ mQueryImsState.setIsProvisionedOnDevice(false);
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
CustomSliceRegistry.WIFI_CALLING_URI);
@@ -146,9 +147,9 @@ public class WifiCallingSliceHelperTest {
turned off) we need to guide the user to wifi calling settings
activity so the user can perform the activation there.(PrimaryAction)
*/
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(false).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(false);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(false);
+ mQueryImsState.setIsTtyOnVolteEnabled(false);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
mWfcSliceHelper.setActivationAppIntent(new Intent()); // dummy Intent
@@ -163,9 +164,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingSlice_success() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
@@ -177,9 +178,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_SettingSliceProvider_getsRightSliceWifiCalling() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
.thenReturn(mWfcSliceHelper);
@@ -192,9 +193,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_SliceBroadcastReceiver_toggleOnWifiCalling() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(false).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(false);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
.thenReturn(mWfcSliceHelper);
mWfcSliceHelper.setActivationAppIntent(null);
@@ -216,9 +217,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingPreferenceSlice_prefNotEditable() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
mWfcSliceHelper.setIsWifiCallingPrefEditable(false);
final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
@@ -230,9 +231,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingPreferenceSlice_wfcOff() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(false).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(false);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
@@ -246,9 +247,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_CreateWifiCallingPreferenceSlice_success() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
@@ -263,9 +264,9 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_SettingsSliceProvider_getWfcPreferenceSlice() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
@@ -281,9 +282,9 @@ public class WifiCallingSliceHelperTest {
}
@Test
public void test_SliceBroadcastReceiver_setWfcPrefCellularPref() {
- doReturn(true).when(mQueryImsState).isWifiCallingProvisioned();
- doReturn(true).when(mQueryImsState).isEnabledByUser();
- when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mQueryImsState.setIsProvisionedOnDevice(true);
+ mQueryImsState.setIsEnabledByUser(true);
+ mQueryImsState.setIsTtyOnVolteEnabled(true);
when(mMockImsMmTelManager.getVoWiFiModeSetting()).thenReturn(
ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED);
when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
@@ -447,14 +448,6 @@ public class WifiCallingSliceHelperTest {
mSubId = id;
}
- boolean isWfcProvisionedOnDevice(int subId) {
- return true;
- }
-
- WifiCallingQueryImsState queryImsState(int subId) {
- return super.queryImsState(subId);
- }
-
@Override
protected Intent getWifiCallingCarrierActivityIntent(int subId) {
return mActivationAppIntent;
diff --git a/tests/uitests/assets/search_results_list b/tests/uitests/assets/search_results_list
index a6dafe2e98e..f8694636767 100644
--- a/tests/uitests/assets/search_results_list
+++ b/tests/uitests/assets/search_results_list
@@ -150,7 +150,6 @@ Cool color temperature;color_temperature
Copyright;copyright
Correction mode;type
Cross-profile calendar;cross_profile_calendar
-Cross-profile calendar;cross_profile_calendar_disabled
Current screen saver;current_screensaver
Custom;zen_custom
Custom restrictions;zen_mode_block_settings_page