diff --git a/AndroidManifest.xml b/AndroidManifest.xml index dbe231b5255..feb1b05f32a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2955,7 +2955,7 @@ android:value="com.android.settings.applications.appinfo.ExternalSourcesDetails" /> - diff --git a/res/layout/admin_support_details_content.xml b/res/layout/admin_support_details_content.xml deleted file mode 100644 index 7c756c4d397..00000000000 --- a/res/layout/admin_support_details_content.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/res/layout/admin_support_details_dialog.xml b/res/layout/admin_support_details_dialog.xml index c83add323f9..7de91d0d939 100644 --- a/res/layout/admin_support_details_dialog.xml +++ b/res/layout/admin_support_details_dialog.xml @@ -23,7 +23,7 @@ android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" - android:paddingBottom="@dimen/admin_details_dialog_padding"> + android:paddingBottom="@dimen/admin_details_dialog_title_bottom_padding"> - + diff --git a/res/layout/admin_support_details_empty_view.xml b/res/layout/admin_support_details_empty_view.xml deleted file mode 100644 index bbbbbbcbc7c..00000000000 --- a/res/layout/admin_support_details_empty_view.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/res/layout/preference_list_fragment.xml b/res/layout/preference_list_fragment.xml index b84aa3822ba..eeea9c492f1 100644 --- a/res/layout/preference_list_fragment.xml +++ b/res/layout/preference_list_fragment.xml @@ -62,8 +62,6 @@ android:gravity="center_vertical" android:visibility="gone" /> - - 24dp + 20dp 48dp 36dp + 24dp + 8dp + 88dp 8dp diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java index 9ad32e267d2..46e0d41cfac 100644 --- a/src/com/android/settings/MasterClear.java +++ b/src/com/android/settings/MasterClear.java @@ -57,6 +57,7 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ConfirmLockPattern; import com.android.settingslib.RestrictedLockUtils; @@ -503,10 +504,11 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL if (disallow && !Utils.isDemoUser(context)) { return inflater.inflate(R.layout.master_clear_disallowed_screen, null); } else if (admin != null) { - View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); - ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); - view.setVisibility(View.VISIBLE); - return view; + new ActionDisabledByAdminDialogHelper(getActivity()) + .prepareDialogBuilder(UserManager.DISALLOW_FACTORY_RESET, admin) + .setOnDismissListener(__ -> getActivity().finish()) + .show(); + return new View(getContext()); } mContentView = inflater.inflate(R.layout.master_clear, null); diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java index 59736fd4cf5..a92c8f85c7e 100644 --- a/src/com/android/settings/MasterClearConfirm.java +++ b/src/com/android/settings/MasterClearConfirm.java @@ -34,6 +34,7 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.core.InstrumentedFragment; +import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settingslib.RestrictedLockUtils; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; @@ -151,10 +152,11 @@ public class MasterClearConfirm extends InstrumentedFragment { UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) { return inflater.inflate(R.layout.master_clear_disallowed_screen, null); } else if (admin != null) { - View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); - ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); - view.setVisibility(View.VISIBLE); - return view; + new ActionDisabledByAdminDialogHelper(getActivity()) + .prepareDialogBuilder(UserManager.DISALLOW_FACTORY_RESET, admin) + .setOnDismissListener(__ -> getActivity().finish()) + .show(); + return new View(getActivity()); } mContentView = inflater.inflate(R.layout.master_clear_confirm, null); establishFinalConfirmationState(); @@ -167,9 +169,9 @@ public class MasterClearConfirm extends InstrumentedFragment { TextView confirmationMessage = (TextView) mContentView.findViewById(R.id.master_clear_confirm); if (confirmationMessage != null) { - String accessibileText = new StringBuilder(currentTitle).append(",").append( + String accessibleText = new StringBuilder(currentTitle).append(",").append( confirmationMessage.getText()).toString(); - getActivity().setTitle(Utils.createAccessibleSequence(currentTitle, accessibileText)); + getActivity().setTitle(Utils.createAccessibleSequence(currentTitle, accessibleText)); } } diff --git a/src/com/android/settings/ResetNetwork.java b/src/com/android/settings/ResetNetwork.java index 8043750a743..591ce0ab689 100644 --- a/src/com/android/settings/ResetNetwork.java +++ b/src/com/android/settings/ResetNetwork.java @@ -45,6 +45,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.PhoneConstants; import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ConfirmLockPattern; import com.android.settingslib.RestrictedLockUtils; @@ -245,10 +246,11 @@ public class ResetNetwork extends InstrumentedFragment { UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) { return inflater.inflate(R.layout.network_reset_disallowed_screen, null); } else if (admin != null) { - View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); - ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); - view.setVisibility(View.VISIBLE); - return view; + new ActionDisabledByAdminDialogHelper(getActivity()) + .prepareDialogBuilder(UserManager.DISALLOW_NETWORK_RESET, admin) + .setOnDismissListener(__ -> getActivity().finish()) + .show(); + return new View(getContext()); } mContentView = inflater.inflate(R.layout.reset_network, null); diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java index edded11c8fc..d735c0666a2 100644 --- a/src/com/android/settings/ResetNetworkConfirm.java +++ b/src/com/android/settings/ResetNetworkConfirm.java @@ -27,7 +27,6 @@ import android.net.Uri; import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Bundle; -import android.os.RecoverySystem; import android.os.UserHandle; import android.os.UserManager; import android.support.annotation.VisibleForTesting; @@ -42,6 +41,7 @@ import android.widget.Toast; import com.android.ims.ImsManager; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.PhoneConstants; +import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settings.wrapper.RecoverySystemWrapper; import com.android.settings.core.InstrumentedFragment; import com.android.settingslib.RestrictedLockUtils; @@ -197,10 +197,11 @@ public class ResetNetworkConfirm extends InstrumentedFragment { UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) { return inflater.inflate(R.layout.network_reset_disallowed_screen, null); } else if (admin != null) { - View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); - ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); - view.setVisibility(View.VISIBLE); - return view; + new ActionDisabledByAdminDialogHelper(getActivity()) + .prepareDialogBuilder(UserManager.DISALLOW_NETWORK_RESET, admin) + .setOnDismissListener(__ -> getActivity().finish()) + .show(); + return new View(getContext()); } mContentView = inflater.inflate(R.layout.reset_network_confirm, null); establishFinalConfirmationState(); diff --git a/src/com/android/settings/RestrictedSettingsFragment.java b/src/com/android/settings/RestrictedSettingsFragment.java index bbb317ba420..b17ca84650f 100644 --- a/src/com/android/settings/RestrictedSettingsFragment.java +++ b/src/com/android/settings/RestrictedSettingsFragment.java @@ -17,6 +17,7 @@ package com.android.settings; import android.app.Activity; +import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -30,6 +31,7 @@ import android.view.View; import android.widget.TextView; import com.android.settings.dashboard.RestrictedDashboardFragment; +import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settingslib.RestrictedLockUtils; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; @@ -67,7 +69,6 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm private RestrictionsManager mRestrictionsManager; private final String mRestrictionKey; - private View mAdminSupportDetails; private EnforcedAdmin mEnforcedAdmin; private TextView mEmptyTextView; @@ -85,6 +86,8 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm } }; + private AlertDialog mActionDisabledDialog; + /** * @param restrictionKey The restriction key to check before pin protecting * this settings page. Pass in {@link RESTRICT_IF_OVERRIDABLE} if it should @@ -116,7 +119,6 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mAdminSupportDetails = initAdminSupportDetailsView(); mEmptyTextView = initEmptyTextView(); } @@ -204,10 +206,6 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm return restricted && mRestrictionsManager.hasRestrictionsProvider(); } - private View initAdminSupportDetailsView() { - return getActivity().findViewById(R.id.admin_support_details); - } - protected TextView initEmptyTextView() { TextView emptyView = (TextView) getActivity().findViewById(android.R.id.empty); return emptyView; @@ -229,11 +227,14 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm @Override protected void onDataSetChanged() { highlightPreferenceIfNeeded(); - if (mAdminSupportDetails != null && isUiRestrictedByOnlyAdmin()) { + if (isUiRestrictedByOnlyAdmin() + && (mActionDisabledDialog == null || !mActionDisabledDialog.isShowing())) { final EnforcedAdmin admin = getRestrictionEnforcedAdmin(); - ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), - mAdminSupportDetails, admin, false); - setEmptyView(mAdminSupportDetails); + mActionDisabledDialog = new ActionDisabledByAdminDialogHelper(getActivity()) + .prepareDialogBuilder(mRestrictionKey, admin) + .setOnDismissListener(__ -> getActivity().finish()) + .show(); + setEmptyView(new View(getContext())); } else if (mEmptyTextView != null) { setEmptyView(mEmptyTextView); } diff --git a/src/com/android/settings/ShowAdminSupportDetailsDialog.java b/src/com/android/settings/ShowAdminSupportDetailsDialog.java deleted file mode 100644 index 321f93d10c3..00000000000 --- a/src/com/android/settings/ShowAdminSupportDetailsDialog.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2015 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; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.AppGlobals; -import android.app.admin.DevicePolicyManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Process; -import android.os.RemoteException; -import android.os.UserHandle; -import android.os.UserManager; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import com.android.settingslib.RestrictedLockUtils; -import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; - -import java.util.Objects; - -public class ShowAdminSupportDetailsDialog extends Activity - implements DialogInterface.OnDismissListener { - - private static final String TAG = "AdminSupportDialog"; - - private EnforcedAdmin mEnforcedAdmin; - private View mDialogView; - private String mRestriction = null; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mEnforcedAdmin = getAdminDetailsFromIntent(getIntent()); - mRestriction = getRestrictionFromIntent(getIntent()); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - mDialogView = LayoutInflater.from(builder.getContext()).inflate( - R.layout.admin_support_details_dialog, null); - initializeDialogViews(mDialogView, mEnforcedAdmin.component, mEnforcedAdmin.userId, - mRestriction); - builder.setOnDismissListener(this) - .setPositiveButton(R.string.okay, null) - .setView(mDialogView) - .show(); - } - - @Override - public void onNewIntent(Intent intent) { - super.onNewIntent(intent); - EnforcedAdmin admin = getAdminDetailsFromIntent(intent); - String restriction = getRestrictionFromIntent(intent); - if (!mEnforcedAdmin.equals(admin) || !Objects.equals(mRestriction, restriction)) { - mEnforcedAdmin = admin; - mRestriction = restriction; - initializeDialogViews(mDialogView, mEnforcedAdmin.component, mEnforcedAdmin.userId, - mRestriction); - } - } - - private EnforcedAdmin getAdminDetailsFromIntent(Intent intent) { - EnforcedAdmin admin = new EnforcedAdmin(null, UserHandle.myUserId()); - if (intent == null) { - return admin; - } - admin.component = intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN); - admin.userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId()); - return admin; - } - - private String getRestrictionFromIntent(Intent intent) { - if (intent == null) return null; - return intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION); - } - - private void initializeDialogViews(View root, ComponentName admin, int userId, - String restriction) { - if (admin != null) { - if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(this, admin) - || !RestrictedLockUtils.isCurrentUserOrProfile(this, userId)) { - admin = null; - } else { - ActivityInfo ai = null; - try { - ai = AppGlobals.getPackageManager().getReceiverInfo(admin, 0 /* flags */, - userId); - } catch (RemoteException e) { - Log.w(TAG, "Missing reciever info", e); - } - if (ai != null) { - Drawable icon = ai.loadIcon(getPackageManager()); - Drawable badgedIcon = getPackageManager().getUserBadgedIcon( - icon, new UserHandle(userId)); - ((ImageView) root.findViewById(R.id.admin_support_icon)).setImageDrawable( - badgedIcon); - } - } - } - - setAdminSupportTitle(root, restriction); - setAdminSupportDetails(this, root, new EnforcedAdmin(admin, userId), true); - } - - private void setAdminSupportTitle(View root, String restriction) { - final TextView titleView = (TextView) root.findViewById(R.id.admin_support_dialog_title); - if (titleView == null) { - return; - } - if (restriction == null) { - titleView.setText(R.string.disabled_by_policy_title); - return; - } - switch(restriction) { - case UserManager.DISALLOW_ADJUST_VOLUME: - titleView.setText(R.string.disabled_by_policy_title_adjust_volume); - break; - case UserManager.DISALLOW_OUTGOING_CALLS: - titleView.setText(R.string.disabled_by_policy_title_outgoing_calls); - break; - case UserManager.DISALLOW_SMS: - titleView.setText(R.string.disabled_by_policy_title_sms); - break; - case DevicePolicyManager.POLICY_DISABLE_CAMERA: - titleView.setText(R.string.disabled_by_policy_title_camera); - break; - case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE: - titleView.setText(R.string.disabled_by_policy_title_screen_capture); - break; - case DevicePolicyManager.POLICY_MANDATORY_BACKUPS: - titleView.setText(R.string.disabled_by_policy_title_turn_off_backups); - break; - default: - // Use general text if no specialized title applies - titleView.setText(R.string.disabled_by_policy_title); - } - } - - public static void setAdminSupportDetails(final Activity activity, View root, - final EnforcedAdmin enforcedAdmin, final boolean finishActivity) { - if (enforcedAdmin == null) { - return; - } - - if (enforcedAdmin.component != null) { - DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( - Context.DEVICE_POLICY_SERVICE); - if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(activity, - enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile( - activity, enforcedAdmin.userId)) { - enforcedAdmin.component = null; - } else { - if (enforcedAdmin.userId == UserHandle.USER_NULL) { - enforcedAdmin.userId = UserHandle.myUserId(); - } - CharSequence supportMessage = null; - if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) { - supportMessage = dpm.getShortSupportMessageForUser( - enforcedAdmin.component, enforcedAdmin.userId); - } - if (supportMessage != null) { - TextView textView = (TextView) root.findViewById(R.id.admin_support_msg); - textView.setText(supportMessage); - } - } - } - - root.findViewById(R.id.admins_policies_list).setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(); - if (enforcedAdmin.component != null) { - intent.setClass(activity, DeviceAdminAdd.class); - intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, - enforcedAdmin.component); - intent.putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true); - // DeviceAdminAdd class may need to run as managed profile. - activity.startActivityAsUser(intent, - new UserHandle(enforcedAdmin.userId)); - } else { - intent.setClass(activity, Settings.DeviceAdminSettingsActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // Activity merges both managed profile and parent users - // admins so show as same user as this activity. - activity.startActivity(intent); - } - if (finishActivity) { - activity.finish(); - } - } - }); - } - - @Override - public void onDismiss(DialogInterface dialog) { - finish(); - } -} diff --git a/src/com/android/settings/dashboard/RestrictedDashboardFragment.java b/src/com/android/settings/dashboard/RestrictedDashboardFragment.java index 99aaff433a4..de0b39667de 100644 --- a/src/com/android/settings/dashboard/RestrictedDashboardFragment.java +++ b/src/com/android/settings/dashboard/RestrictedDashboardFragment.java @@ -19,6 +19,7 @@ package com.android.settings.dashboard; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.Activity; +import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -31,9 +32,9 @@ import android.os.UserManager; import android.view.View; import android.widget.TextView; +import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; -import com.android.settings.ShowAdminSupportDetailsDialog; import com.android.settingslib.RestrictedLockUtils; /** @@ -69,7 +70,6 @@ public abstract class RestrictedDashboardFragment extends DashboardFragment { private RestrictionsManager mRestrictionsManager; private final String mRestrictionKey; - private View mAdminSupportDetails; private EnforcedAdmin mEnforcedAdmin; private TextView mEmptyTextView; @@ -86,6 +86,7 @@ public abstract class RestrictedDashboardFragment extends DashboardFragment { } } }; + private AlertDialog mActionDisabledDialog; /** * @param restrictionKey The restriction key to check before pin protecting @@ -118,7 +119,6 @@ public abstract class RestrictedDashboardFragment extends DashboardFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mAdminSupportDetails = initAdminSupportDetailsView(); mEmptyTextView = initEmptyTextView(); } @@ -206,10 +206,6 @@ public abstract class RestrictedDashboardFragment extends DashboardFragment { return restricted && mRestrictionsManager.hasRestrictionsProvider(); } - private View initAdminSupportDetailsView() { - return getActivity().findViewById(R.id.admin_support_details); - } - protected TextView initEmptyTextView() { TextView emptyView = (TextView) getActivity().findViewById(android.R.id.empty); return emptyView; @@ -231,11 +227,14 @@ public abstract class RestrictedDashboardFragment extends DashboardFragment { @Override protected void onDataSetChanged() { highlightPreferenceIfNeeded(); - if (mAdminSupportDetails != null && isUiRestrictedByOnlyAdmin()) { + if (isUiRestrictedByOnlyAdmin() + && (mActionDisabledDialog == null || !mActionDisabledDialog.isShowing())) { final EnforcedAdmin admin = getRestrictionEnforcedAdmin(); - ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), - mAdminSupportDetails, admin, false); - setEmptyView(mAdminSupportDetails); + mActionDisabledDialog = new ActionDisabledByAdminDialogHelper(getActivity()) + .prepareDialogBuilder(mRestrictionKey, admin) + .setOnDismissListener(__ -> getActivity().finish()) + .show(); + setEmptyView(new View(getContext())); } else if (mEmptyTextView != null) { setEmptyView(mEmptyTextView); } diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialog.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialog.java new file mode 100644 index 00000000000..37c51248873 --- /dev/null +++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialog.java @@ -0,0 +1,75 @@ +/* + * 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.enterprise; + +import android.app.Activity; +import android.app.admin.DevicePolicyManager; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.os.UserHandle; + +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + +public class ActionDisabledByAdminDialog extends Activity + implements DialogInterface.OnDismissListener { + + private ActionDisabledByAdminDialogHelper mDialogHelper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final RestrictedLockUtils.EnforcedAdmin enforcedAdmin = + getAdminDetailsFromIntent(getIntent()); + final String restriction = getRestrictionFromIntent(getIntent()); + mDialogHelper = new ActionDisabledByAdminDialogHelper(this); + mDialogHelper.prepareDialogBuilder(restriction, enforcedAdmin) + .setOnDismissListener(this) + .show(); + } + + @Override + public void onNewIntent(Intent intent) { + super.onNewIntent(intent); + final EnforcedAdmin admin = getAdminDetailsFromIntent(intent); + final String restriction = getRestrictionFromIntent(intent); + mDialogHelper.updateDialog(restriction, admin); + } + + @android.support.annotation.VisibleForTesting + EnforcedAdmin getAdminDetailsFromIntent(Intent intent) { + final EnforcedAdmin admin = new EnforcedAdmin(null, UserHandle.myUserId()); + if (intent == null) { + return admin; + } + admin.component = intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN); + admin.userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId()); + return admin; + } + + @android.support.annotation.VisibleForTesting + String getRestrictionFromIntent(Intent intent) { + if (intent == null) return null; + return intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION); + } + + @Override + public void onDismiss(DialogInterface dialog) { + finish(); + } +} diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java new file mode 100644 index 00000000000..3429957b016 --- /dev/null +++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java @@ -0,0 +1,204 @@ +/* + * 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.enterprise; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.AppGlobals; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.graphics.drawable.Drawable; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; +import android.support.annotation.VisibleForTesting; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.settings.DeviceAdminAdd; +import com.android.settings.R; +import com.android.settings.Settings; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + +import java.util.Objects; + +/** + * Helper class for {@link ActionDisabledByAdminDialog} which sets up the dialog. + */ +public class ActionDisabledByAdminDialogHelper { + + private static final String TAG = ActionDisabledByAdminDialogHelper.class.getName(); + private EnforcedAdmin mEnforcedAdmin; + private ViewGroup mDialogView; + private String mRestriction = null; + private Activity mActivity; + + public ActionDisabledByAdminDialogHelper(Activity activity) { + mActivity = activity; + } + + public AlertDialog.Builder prepareDialogBuilder(String restriction, + EnforcedAdmin enforcedAdmin) { + mEnforcedAdmin = enforcedAdmin; + mRestriction = restriction; + + final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); + mDialogView = (ViewGroup) LayoutInflater.from(builder.getContext()).inflate( + R.layout.admin_support_details_dialog, null); + initializeDialogViews(mDialogView, mEnforcedAdmin.component, mEnforcedAdmin.userId, + mRestriction); + return builder + .setPositiveButton(R.string.okay, null) + .setNeutralButton(R.string.admin_more_details, + (dialog, which) -> { + showAdminPolicies(mEnforcedAdmin, mActivity); + mActivity.finish(); + }) + .setView(mDialogView); + } + + public void updateDialog(String restriction, EnforcedAdmin admin) { + if (mEnforcedAdmin.equals(admin) && Objects.equals(mRestriction, restriction)) { + return; + } + mEnforcedAdmin = admin; + mRestriction = restriction; + initializeDialogViews(mDialogView, mEnforcedAdmin.component, mEnforcedAdmin.userId, + mRestriction); + } + + private void initializeDialogViews(View root, ComponentName admin, int userId, + String restriction) { + if (admin == null) { + return; + } + if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(mActivity, admin) + || !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)) { + admin = null; + } else { + ActivityInfo ai = null; + try { + ai = AppGlobals.getPackageManager().getReceiverInfo(admin, 0 /* flags */, + userId); + } catch (RemoteException e) { + Log.w(TAG, "Missing reciever info", e); + } + if (ai != null) { + final Drawable icon = ai.loadIcon(mActivity.getPackageManager()); + final Drawable badgedIcon = mActivity.getPackageManager().getUserBadgedIcon( + icon, new UserHandle(userId)); + ((ImageView) root.findViewById(R.id.admin_support_icon)).setImageDrawable( + badgedIcon); + } + } + + setAdminSupportTitle(root, restriction); + setAdminSupportDetails(mActivity, root, new EnforcedAdmin(admin, userId)); + } + + @VisibleForTesting + void setAdminSupportTitle(View root, String restriction) { + final TextView titleView = root.findViewById(R.id.admin_support_dialog_title); + if (titleView == null) { + return; + } + if (restriction == null) { + titleView.setText(R.string.disabled_by_policy_title); + return; + } + switch (restriction) { + case UserManager.DISALLOW_ADJUST_VOLUME: + titleView.setText(R.string.disabled_by_policy_title_adjust_volume); + break; + case UserManager.DISALLOW_OUTGOING_CALLS: + titleView.setText(R.string.disabled_by_policy_title_outgoing_calls); + break; + case UserManager.DISALLOW_SMS: + titleView.setText(R.string.disabled_by_policy_title_sms); + break; + case DevicePolicyManager.POLICY_DISABLE_CAMERA: + titleView.setText(R.string.disabled_by_policy_title_camera); + break; + case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE: + titleView.setText(R.string.disabled_by_policy_title_screen_capture); + break; + case DevicePolicyManager.POLICY_MANDATORY_BACKUPS: + titleView.setText(R.string.disabled_by_policy_title_turn_off_backups); + break; + default: + // Use general text if no specialized title applies + titleView.setText(R.string.disabled_by_policy_title); + } + } + + @VisibleForTesting + void setAdminSupportDetails(final Activity activity, final View root, + final EnforcedAdmin enforcedAdmin) { + if (enforcedAdmin == null || enforcedAdmin.component == null) { + return; + } + final DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( + Context.DEVICE_POLICY_SERVICE); + if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(activity, + enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile( + activity, enforcedAdmin.userId)) { + enforcedAdmin.component = null; + } else { + if (enforcedAdmin.userId == UserHandle.USER_NULL) { + enforcedAdmin.userId = UserHandle.myUserId(); + } + CharSequence supportMessage = null; + if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) { + supportMessage = dpm.getShortSupportMessageForUser( + enforcedAdmin.component, enforcedAdmin.userId); + } + if (supportMessage != null) { + final TextView textView = root.findViewById(R.id.admin_support_msg); + textView.setText(supportMessage); + } + } + } + + @VisibleForTesting + void showAdminPolicies(final EnforcedAdmin enforcedAdmin, final Activity activity) { + final Intent intent = new Intent(); + if (enforcedAdmin.component != null) { + intent.setClass(activity, DeviceAdminAdd.class); + intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, + enforcedAdmin.component); + intent.putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true); + // DeviceAdminAdd class may need to run as managed profile. + activity.startActivityAsUser(intent, + new UserHandle(enforcedAdmin.userId)); + } else { + intent.setClass(activity, Settings.DeviceAdminSettingsActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // Activity merges both managed profile and parent users + // admins so show as same user as this activity. + activity.startActivity(intent); + } + } +} diff --git a/src/com/android/settings/enterprise/OWNERS b/src/com/android/settings/enterprise/OWNERS index bab2fe2d1b9..58116739828 100644 --- a/src/com/android/settings/enterprise/OWNERS +++ b/src/com/android/settings/enterprise/OWNERS @@ -1,4 +1,7 @@ # Default reviewers for this and subdirectories. sandness@google.com +tonymak@google.com +yuemingw@google.com +arangelov@google.com # Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/nfc/AndroidBeam.java b/src/com/android/settings/nfc/AndroidBeam.java index 8377f143f08..4e90680aac9 100644 --- a/src/com/android/settings/nfc/AndroidBeam.java +++ b/src/com/android/settings/nfc/AndroidBeam.java @@ -28,11 +28,11 @@ import android.view.ViewGroup; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settingslib.HelpUtils; import com.android.settings.core.InstrumentedFragment; import com.android.settings.R; import com.android.settings.SettingsActivity; -import com.android.settings.ShowAdminSupportDetailsDialog; import com.android.settings.widget.SwitchBar; import com.android.settingslib.RestrictedLockUtils; @@ -70,11 +70,10 @@ public class AndroidBeam extends InstrumentedFragment mBeamDisallowedByBase = RestrictedLockUtils.hasBaseUserRestriction(getActivity(), UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId()); if (!mBeamDisallowedByBase && admin != null) { - View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); - ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); - view.setVisibility(View.VISIBLE); + new ActionDisabledByAdminDialogHelper(getActivity()) + .prepareDialogBuilder(UserManager.DISALLOW_OUTGOING_BEAM, admin).show(); mBeamDisallowedByOnlyAdmin = true; - return view; + return new View(getContext()); } mView = inflater.inflate(R.layout.android_beam, container, false); return mView; diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java new file mode 100644 index 00000000000..981ce135d7c --- /dev/null +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java @@ -0,0 +1,186 @@ +/* + * 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.enterprise; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.app.Activity; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.UserInfo; +import android.os.Process; +import android.os.UserManager; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.TextView; + +import com.android.settings.DeviceAdminAdd; +import com.android.settings.R; +import com.android.settings.Settings; +import com.android.settings.testutils.CustomActivity; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowActivity; +import com.android.settings.testutils.shadow.ShadowDevicePolicyManager; +import com.android.settings.testutils.shadow.ShadowProcess; +import com.android.settings.testutils.shadow.ShadowUserManager; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = { + ShadowDevicePolicyManager.class, + ShadowUserManager.class, + ShadowActivity.class, + ShadowProcess.class +}) +public class ActionDisabledByAdminDialogHelperTest { + private ActionDisabledByAdminDialogHelper mHelper; + private Activity mActivity; + private org.robolectric.shadows.ShadowActivity mActivityShadow; + + @Before + public void setUp() { + mActivity = Robolectric.buildActivity(CustomActivity.class).get(); + mActivityShadow = Shadow.extract(mActivity); + mHelper = new ActionDisabledByAdminDialogHelper(mActivity); + } + + @Test + public void testShowAdminPoliciesWithComponent() { + final int userId = 123; + final ComponentName component = new ComponentName("some.package.name", + "some.package.name.SomeClass"); + final EnforcedAdmin admin = new EnforcedAdmin(component, userId); + + mHelper.showAdminPolicies(admin, mActivity); + + final Intent intent = mActivityShadow.getNextStartedActivity(); + assertTrue( + intent.getBooleanExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, false)); + assertEquals(component, + intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN)); + } + + @Test + public void testShowAdminPoliciesWithoutComponent() { + final int userId = 123; + final EnforcedAdmin admin = new EnforcedAdmin(null, userId); + mHelper.showAdminPolicies(admin, mActivity); + final Intent intent = mActivityShadow.getNextStartedActivity(); + assertEquals(intent.getComponent(), new ComponentName(mActivity, + Settings.DeviceAdminSettingsActivity.class.getName())); + } + + @Test + public void testSetAdminSupportTitle() { + final ViewGroup view = new FrameLayout(mActivity); + final TextView textView = new TextView(mActivity); + textView.setId(R.id.admin_support_dialog_title); + view.addView(textView); + + mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_ADJUST_VOLUME); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title_adjust_volume)); + + mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_OUTGOING_CALLS); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title_outgoing_calls)); + + mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_SMS); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title_sms)); + + mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_DISABLE_CAMERA); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title_camera)); + + mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title_screen_capture)); + + mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_MANDATORY_BACKUPS); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title_turn_off_backups)); + + mHelper.setAdminSupportTitle(view, "another restriction"); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title)); + + mHelper.setAdminSupportTitle(view, null); + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title)); + } + + @Test + public void testSetAdminSupportDetails() { + final DevicePolicyManager dpm = RuntimeEnvironment.application.getSystemService( + DevicePolicyManager.class); + final ShadowDevicePolicyManager dpmShadow = Shadow.extract(dpm); + final UserManager userManager = RuntimeEnvironment.application.getSystemService( + UserManager.class); + final ShadowUserManager userManagerShadow = Shadow.extract(userManager); + final ViewGroup view = new FrameLayout(mActivity); + final ComponentName component = new ComponentName("some.package.name", + "some.package.name.SomeClass"); + final EnforcedAdmin admin = new EnforcedAdmin(component, 123); + final TextView textView = new TextView(mActivity); + + textView.setId(R.id.admin_support_msg); + view.addView(textView); + dpmShadow.setShortSupportMessageForUser(component, 123, "some message"); + dpmShadow.setIsAdminActiveAsUser(true); + userManagerShadow.addProfile(new UserInfo(123, null, 0)); + ShadowProcess.setMyUid(Process.SYSTEM_UID); + + mHelper.setAdminSupportDetails(mActivity, view, admin); + assertNotNull(admin.component); + assertEquals("some message", Shadows.shadowOf(textView).innerText()); + } + + @Test + public void testSetAdminSupportDetailsNotAdmin() { + final DevicePolicyManager dpm = RuntimeEnvironment.application.getSystemService( + DevicePolicyManager.class); + final ShadowDevicePolicyManager dpmShadow = Shadow.extract(dpm); + final UserManager userManager = RuntimeEnvironment.application.getSystemService( + UserManager.class); + final ShadowUserManager userManagerShadow = Shadow.extract(userManager); + final ComponentName component = new ComponentName("some.package.name", + "some.package.name.SomeClass"); + final EnforcedAdmin admin = new EnforcedAdmin(component, 123); + + dpmShadow.setShortSupportMessageForUser(component, 123, "some message"); + dpmShadow.setIsAdminActiveAsUser(false); + userManagerShadow.addProfile(new UserInfo(123, null, 0)); + + mHelper.setAdminSupportDetails(mActivity, null, admin); + assertNull(admin.component); + } +} + diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogTest.java new file mode 100644 index 00000000000..ebdfad695fb --- /dev/null +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogTest.java @@ -0,0 +1,75 @@ +/* + * 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.enterprise; + +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Intent; +import android.os.UserHandle; + +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(SettingsRobolectricTestRunner.class) +public class ActionDisabledByAdminDialogTest { + + private ActionDisabledByAdminDialog mDialog; + + @Before + public void setUp() { + mDialog = new ActionDisabledByAdminDialog(); + } + + @Test + public void testGetAdminDetailsFromIntent() { + final int userId = 123; + final ComponentName component = new ComponentName("com.some.package", ".SomeClass"); + final EnforcedAdmin expectedAdmin = new EnforcedAdmin(component, userId); + + final Intent intent = new Intent(); + intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, component); + intent.putExtra(Intent.EXTRA_USER_ID, userId); + Assert.assertEquals(expectedAdmin, mDialog.getAdminDetailsFromIntent(intent)); + } + + @Test + public void testGetAdminDetailsFromNullIntent() { + final int userId = UserHandle.myUserId(); + final EnforcedAdmin expectedAdmin = new EnforcedAdmin(null, userId); + + Assert.assertEquals(expectedAdmin, mDialog.getAdminDetailsFromIntent(null)); + } + + @Test + public void testGetRestrictionFromIntent() { + final String restriction = "someRestriction"; + final Intent intent = new Intent(); + + intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, restriction); + Assert.assertEquals(restriction, mDialog.getRestrictionFromIntent(intent)); + } + + @Test + public void testGetRestrictionFromNullIntent() { + Assert.assertEquals(null, mDialog.getRestrictionFromIntent(null)); + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/CustomActivity.java b/tests/robotests/src/com/android/settings/testutils/CustomActivity.java new file mode 100644 index 00000000000..d4c73412deb --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/CustomActivity.java @@ -0,0 +1,26 @@ +/* + * 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.testutils; + +import android.app.Activity; +import android.content.Intent; +import android.os.UserHandle; + +public class CustomActivity extends Activity { + @Override + public void startActivityAsUser(Intent intent, UserHandle user) {} +} diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowActivity.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowActivity.java new file mode 100644 index 00000000000..0f67bbf045e --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowActivity.java @@ -0,0 +1,35 @@ +/* + * 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.testutils.shadow; + +import android.content.Intent; +import android.os.UserHandle; + +import com.android.settings.testutils.CustomActivity; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.shadows.ShadowApplication; + +@Implements(CustomActivity.class) +public class ShadowActivity extends org.robolectric.shadows.ShadowActivity { + + @Implementation + public void startActivityAsUser(Intent intent, UserHandle user) { + ShadowApplication.getInstance().startActivity(intent); + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java new file mode 100644 index 00000000000..77daae00c5a --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java @@ -0,0 +1,41 @@ +package com.android.settings.testutils.shadow; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * This shadow if using {@link ShadowDevicePolicyManagerWrapper} is not possible. + */ +@Implements(DevicePolicyManager.class) +public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDevicePolicyManager { + private Map mSupportMessagesMap = new HashMap<>(); + private boolean mIsAdminActiveAsUser = false; + + public void setShortSupportMessageForUser(ComponentName admin, int userHandle, String message) { + mSupportMessagesMap.put(Objects.hash(admin, userHandle), message); + } + + @Implementation + public @Nullable CharSequence getShortSupportMessageForUser(@NonNull ComponentName admin, + int userHandle) { + return mSupportMessagesMap.get(Objects.hash(admin, userHandle)); + } + + @Implementation + public boolean isAdminActiveAsUser(@NonNull ComponentName admin, int userId) { + return mIsAdminActiveAsUser; + } + + public void setIsAdminActiveAsUser(boolean active) { + mIsAdminActiveAsUser = active; + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowProcess.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowProcess.java new file mode 100644 index 00000000000..eea3ee896e7 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowProcess.java @@ -0,0 +1,18 @@ +package com.android.settings.testutils.shadow; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(android.os.Process.class) +public class ShadowProcess { + private static int sUid; + + public static void setMyUid(int uid) { + sUid = uid; + } + + @Implementation + public static int myUid() { + return sUid; + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java index dfd4b7f3bc6..9979ddbb2f6 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java @@ -17,7 +17,6 @@ package com.android.settings.testutils.shadow; import android.annotation.UserIdInt; -import android.content.Context; import android.content.pm.UserInfo; import android.os.UserHandle; import android.os.UserManager; @@ -31,7 +30,6 @@ import org.robolectric.annotation.Resetter; import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,10 +40,12 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager private SparseArray mUserInfos = new SparseArray<>(); private final List mRestrictions = new ArrayList<>(); private final Map> mRestrictionSources = new HashMap<>(); + private List mUserProfileInfos = new ArrayList<>(); @Resetter public void reset() { mRestrictions.clear(); + mUserProfileInfos.clear(); } public void setUserInfo(int userHandle, UserInfo userInfo) { @@ -57,9 +57,13 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager return mUserInfos.get(userHandle); } + public void addProfile(UserInfo userInfo) { + mUserProfileInfos.add(userInfo); + } + @Implementation public List getProfiles(@UserIdInt int userHandle) { - return Collections.emptyList(); + return mUserProfileInfos; } @Implementation