diff --git a/res/layout/admin_support_details_dialog.xml b/res/layout/admin_support_details_dialog.xml index 0d857df8425..d9f71ae9f85 100644 --- a/res/layout/admin_support_details_dialog.xml +++ b/res/layout/admin_support_details_dialog.xml @@ -24,7 +24,7 @@ android:orientation="horizontal" android:gravity="center_vertical" android:paddingBottom="@dimen/admin_details_dialog_padding"> - - - \ No newline at end of file + diff --git a/res/layout/device_admin_add.xml b/res/layout/device_admin_add.xml index 25b7f01bbf0..4e8a6aca02c 100644 --- a/res/layout/device_admin_add.xml +++ b/res/layout/device_admin_add.xml @@ -100,8 +100,10 @@ + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index b91a3fc5428..668bd40f795 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4435,7 +4435,6 @@ No available device administrators - To stop %1$s from accessing your work profile, remove the profile under Settings > Accounts Personal @@ -6712,11 +6711,18 @@ Android %1$s + Disabled by policy - Disabled by your %s\'s administrator. - organisation - Contact them to learn more. - List of administrators + + Disabled by your organisation\'s administrator.\nContact them to learn more. + + More details + + Your administrator has the ability to monitor and manage settings, corporate access, apps, permissions, and data associated with the profile, including network activity and your device\'s location information. + + Your administrator has the ability to monitor and manage settings, corporate access, apps, permissions, and data associated with this user, including network activity and your device\'s location information. + + Your administrator has the ability to monitor and manage settings, corporate access, apps, permissions, and data associated with this device, including network activity and your device\'s location information. Turn off diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java index acd8c3b6168..3067ca29558 100644 --- a/src/com/android/settings/DeviceAdminAdd.java +++ b/src/com/android/settings/DeviceAdminAdd.java @@ -34,6 +34,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; +import android.content.pm.UserInfo; import android.content.res.Resources; import android.os.Binder; import android.os.Bundle; @@ -42,6 +43,7 @@ import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; +import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.util.EventLog; import android.util.Log; @@ -55,6 +57,8 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import com.android.settings.users.UserDialogs; + import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; @@ -86,6 +90,7 @@ public class DeviceAdminAdd extends Activity { ImageView mAddMsgExpander; boolean mAddMsgEllipsized = true; TextView mAdminWarning; + TextView mSupportMessage; ViewGroup mAdminPolicies; Button mActionButton; Button mCancelButton; @@ -279,6 +284,7 @@ public class DeviceAdminAdd extends Activity { mAdminWarning = (TextView) findViewById(R.id.admin_warning); mAdminPolicies = (ViewGroup) findViewById(R.id.admin_policies); + mSupportMessage = (TextView) findViewById(R.id.admin_support_message); mCancelButton = (Button) findViewById(R.id.cancel_button); mCancelButton.setFilterTouchesWhenObscured(true); mCancelButton.setOnClickListener(new View.OnClickListener() { @@ -294,6 +300,19 @@ public class DeviceAdminAdd extends Activity { public void onClick(View v) { if (mAdding) { addAndFinish(); + } else if (isManagedProfile(mDeviceAdmin) + && mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner())) { + final int userId = UserHandle.myUserId(); + UserDialogs.createRemoveDialog(DeviceAdminAdd.this, userId, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + UserManager um = UserManager.get(DeviceAdminAdd.this); + um.removeUser(userId); + finish(); + } + } + ).show(); } else if (!mWaitingForRemoveMsg) { try { // Don't allow the admin to put a dialog up in front @@ -451,12 +470,42 @@ public class DeviceAdminAdd extends Activity { } if (!mRefreshing && !mAddingProfileOwner && mDPM.isAdminActive(mDeviceAdmin.getComponent())) { - addDeviceAdminPolicies(false /* showDescription */); - mAdminWarning.setText(getString(R.string.device_admin_status, - mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager()))); - setTitle(getText(R.string.active_device_admin_msg)); - mActionButton.setText(getText(R.string.remove_device_admin)); mAdding = false; + final boolean isProfileOwner = + mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner()); + final boolean isManagedProfile = isManagedProfile(mDeviceAdmin); + if (isProfileOwner && isManagedProfile) { + // Profile owner in a managed profile, user can remove profile to disable admin. + mAdminWarning.setText(R.string.admin_profile_owner_message); + mActionButton.setText(R.string.remove_managed_profile_label); + } else if (isProfileOwner || mDeviceAdmin.getComponent().equals( + mDPM.getDeviceOwnerComponentOnCallingUser())) { + // Profile owner in a user or device owner, user can't disable admin. + if (isProfileOwner) { + // Show profile owner in a user description. + mAdminWarning.setText(R.string.admin_profile_owner_user_message); + } else { + // Show device owner description. + mAdminWarning.setText(R.string.admin_device_owner_message); + } + mActionButton.setText(R.string.remove_device_admin); + mActionButton.setEnabled(false); + } else { + addDeviceAdminPolicies(false /* showDescription */); + mAdminWarning.setText(getString(R.string.device_admin_status, + mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel( + getPackageManager()))); + setTitle(R.string.active_device_admin_msg); + mActionButton.setText(R.string.remove_device_admin); + } + String supportMessage = mDPM.getLongSupportMessageForUser( + mDeviceAdmin.getComponent(), UserHandle.myUserId()); + if (!TextUtils.isEmpty(supportMessage)) { + mSupportMessage.setText(supportMessage); + mSupportMessage.setVisibility(View.VISIBLE); + } else { + mSupportMessage.setVisibility(View.GONE); + } } else { addDeviceAdminPolicies(true /* showDescription */); mAdminWarning.setText(getString(R.string.device_admin_warning, @@ -467,6 +516,7 @@ public class DeviceAdminAdd extends Activity { setTitle(getText(R.string.add_device_admin_msg)); } mActionButton.setText(getText(R.string.add_device_admin)); + mSupportMessage.setVisibility(View.GONE); mAdding = true; } } @@ -505,4 +555,13 @@ public class DeviceAdminAdd extends Activity { MAX_ADD_MSG_LINES_PORTRAIT : MAX_ADD_MSG_LINES_LANDSCAPE; } + /** + * @return true if adminInfo is running in a managed profile. + */ + private boolean isManagedProfile(DeviceAdminInfo adminInfo) { + UserManager um = UserManager.get(this); + UserInfo info = um.getUserInfo( + UserHandle.getUserId(adminInfo.getActivityInfo().applicationInfo.uid)); + return info != null ? info.isManagedProfile() : false; + } } diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java index 532498396eb..326e38c7d01 100644 --- a/src/com/android/settings/DeviceAdminSettings.java +++ b/src/com/android/settings/DeviceAdminSettings.java @@ -59,12 +59,29 @@ public class DeviceAdminSettings extends ListFragment { private DevicePolicyManager mDPM; private UserManager mUm; + + private static class DeviceAdminListItem implements Comparable { + public DeviceAdminInfo info; + + // These aren't updated so they keep a stable sort order if user activates / de-activates + // an admin. + public String name; + public boolean active; + + public int compareTo(DeviceAdminListItem other) { + // Sort active admins first, then by name. + if (this.active != other.active) { + return this.active ? -1 : 1; + } + return this.name.compareTo(other.name); + } + } /** * Internal collection of device admin info objects for all profiles associated with the current * user. */ - private final SparseArray> - mAdminsByProfile = new SparseArray>(); + private final ArrayList + mAdmins = new ArrayList(); private String mDeviceOwnerPkg; private SparseArray mProfileOwnerComponents = new SparseArray(); @@ -133,7 +150,7 @@ public class DeviceAdminSettings extends ListFragment { * current user. */ void updateList() { - mAdminsByProfile.clear(); + mAdmins.clear(); final List profiles = mUm.getUserProfiles(); final int profilesSize = profiles.size(); @@ -141,6 +158,7 @@ public class DeviceAdminSettings extends ListFragment { final int profileId = profiles.get(i).getIdentifier(); updateAvailableAdminsForProfile(profileId); } + Collections.sort(mAdmins); getListView().setAdapter(new PolicyListAdapter()); } @@ -148,25 +166,12 @@ public class DeviceAdminSettings extends ListFragment { @Override public void onListItemClick(ListView l, View v, int position, long id) { Object o = l.getAdapter().getItem(position); - if (!(o instanceof DeviceAdminInfo)) { - // race conditions may cause this - return; - } DeviceAdminInfo dpi = (DeviceAdminInfo) o; + final UserHandle user = new UserHandle(getUserId(dpi)); final Activity activity = getActivity(); - final int userId = getUserId(dpi); - if (userId == UserHandle.myUserId() || !isProfileOwner(dpi)) { - Intent intent = new Intent(); - intent.setClass(activity, DeviceAdminAdd.class); - intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, dpi.getComponent()); - activity.startActivityAsUser(intent, new UserHandle(userId)); - } else { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setMessage(getString(R.string.managed_profile_device_admin_info, - dpi.loadLabel(activity.getPackageManager()))); - builder.setPositiveButton(android.R.string.ok, null); - builder.create().show(); - } + Intent intent = new Intent(activity, DeviceAdminAdd.class); + intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, dpi.getComponent()); + activity.startActivityAsUser(intent, user); } static class ViewHolder { @@ -191,55 +196,17 @@ public class DeviceAdminSettings extends ListFragment { @Override public int getCount() { - int adminCount = 0; - final int profileCount = mAdminsByProfile.size(); - for (int i = 0; i < profileCount; ++i) { - adminCount += mAdminsByProfile.valueAt(i).size(); - } - // Add 'profileCount' for title items. - return adminCount + profileCount; + return mAdmins.size(); } /** * The item for the given position in the list. * - * @return a String object for title items and a DeviceAdminInfo object for actual device - * admins. + * @return DeviceAdminInfo object for actual device admins. */ @Override public Object getItem(int position) { - if (position < 0) { - throw new ArrayIndexOutOfBoundsException(); - } - // The position of the item in the list of admins. - // We start from the given position and discount the length of the upper lists until we - // get the one for the right profile - int adminPosition = position; - final int n = mAdminsByProfile.size(); - int i = 0; - for (; i < n; ++i) { - // The elements in that section including the title item (that's why adding one). - final int listSize = mAdminsByProfile.valueAt(i).size() + 1; - if (adminPosition < listSize) { - break; - } - adminPosition -= listSize; - } - if (i == n) { - throw new ArrayIndexOutOfBoundsException(); - } - // If countdown == 0 that means the title item - if (adminPosition == 0) { - Resources res = getActivity().getResources(); - if (mAdminsByProfile.keyAt(i) == UserHandle.myUserId()) { - return res.getString(R.string.personal_device_admin_title); - } else { - return res.getString(R.string.managed_device_admin_title); - } - } else { - // Subtracting one for the title. - return mAdminsByProfile.valueAt(i).get(adminPosition - 1); - } + return ((DeviceAdminListItem) (mAdmins.get(position))).info; } @Override @@ -257,16 +224,15 @@ public class DeviceAdminSettings extends ListFragment { */ @Override public int getViewTypeCount() { - return 2; + return 1; } /** - * Returns 1 for title items and 0 for anything else. + * Returns 0 for all types. */ @Override public int getItemViewType(int position) { - Object o = getItem(position); - return (o instanceof String) ? 1 : 0; + return 0; } @Override @@ -276,15 +242,7 @@ public class DeviceAdminSettings extends ListFragment { } private boolean isEnabled(Object o) { - if (!(o instanceof DeviceAdminInfo)) { - // Title item - return false; - } DeviceAdminInfo info = (DeviceAdminInfo) o; - if (isActiveAdmin(info) && getUserId(info) == UserHandle.myUserId() - && (isDeviceOwner(info) || isProfileOwner(info))) { - return false; - } // Disable item if admin is being removed if (isRemovingAdmin(info)) { return false; @@ -295,28 +253,20 @@ public class DeviceAdminSettings extends ListFragment { @Override public View getView(int position, View convertView, ViewGroup parent) { Object o = getItem(position); - if (o instanceof DeviceAdminInfo) { - if (convertView == null) { - convertView = newDeviceAdminView(parent); - } - bindView(convertView, (DeviceAdminInfo) o); - } else { - if (convertView == null) { - convertView = Utils.inflateCategoryHeader(mInflater, parent); - } - final TextView title = (TextView) convertView.findViewById(android.R.id.title); - title.setText((String)o); + if (convertView == null) { + convertView = newDeviceAdminView(parent); } + bindView(convertView, (DeviceAdminInfo) o); return convertView; } private View newDeviceAdminView(ViewGroup parent) { View v = mInflater.inflate(R.layout.device_admin_item, parent, false); ViewHolder h = new ViewHolder(); - h.icon = (ImageView)v.findViewById(R.id.icon); - h.name = (TextView)v.findViewById(R.id.name); - h.checkbox = (CheckBox)v.findViewById(R.id.checkbox); - h.description = (TextView)v.findViewById(R.id.description); + h.icon = (ImageView) v.findViewById(R.id.icon); + h.name = (TextView) v.findViewById(R.id.name); + h.checkbox = (CheckBox) v.findViewById(R.id.checkbox); + h.description = (TextView) v.findViewById(R.id.description); v.setTag(h); return v; } @@ -399,10 +349,6 @@ public class DeviceAdminSettings extends ListFragment { enabledForProfile = Collections.emptyList(); } final int n = enabledForProfile.size(); - ArrayList deviceAdmins = mAdminsByProfile.get(profileId); - if (deviceAdmins == null) { - deviceAdmins = new ArrayList(n); - } for (int i = 0; i < n; ++i) { ResolveInfo resolveInfo = enabledForProfile.get(i); ComponentName riComponentName = @@ -410,16 +356,18 @@ public class DeviceAdminSettings extends ListFragment { resolveInfo.activityInfo.name); if (alreadyAddedComponents == null || !alreadyAddedComponents.contains(riComponentName)) { - DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolveInfo); + DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolveInfo); // add only visible ones (note: active admins are added regardless of visibility) if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) { - deviceAdmins.add(deviceAdminInfo); + DeviceAdminListItem item = new DeviceAdminListItem(); + item.info = deviceAdminInfo; + item.name = deviceAdminInfo.loadLabel(pm).toString(); + // Active ones already added. + item.active = false; + mAdmins.add(item); } } } - if (!deviceAdmins.isEmpty()) { - mAdminsByProfile.put(profileId, deviceAdmins); - } } /** @@ -433,7 +381,6 @@ public class DeviceAdminSettings extends ListFragment { if (activeAdmins != null) { final PackageManager packageManager = getActivity().getPackageManager(); final int n = activeAdmins.size(); - ArrayList deviceAdmins = new ArrayList(n); for (int i = 0; i < n; ++i) { ComponentName activeAdmin = activeAdmins.get(i); List resolved = packageManager.queryBroadcastReceivers( @@ -444,14 +391,15 @@ public class DeviceAdminSettings extends ListFragment { for (int j = 0; j < resolvedMax; ++j) { DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolved.get(j)); if (deviceAdminInfo != null) { - deviceAdmins.add(deviceAdminInfo); + DeviceAdminListItem item = new DeviceAdminListItem(); + item.info = deviceAdminInfo; + item.name = deviceAdminInfo.loadLabel(packageManager).toString(); + item.active = true; + mAdmins.add(item); } } } } - if (!deviceAdmins.isEmpty()) { - mAdminsByProfile.put(profileId, deviceAdmins); - } } } diff --git a/src/com/android/settings/RestrictedPreferenceHelper.java b/src/com/android/settings/RestrictedPreferenceHelper.java index 09188876777..385a8a2bb9b 100644 --- a/src/com/android/settings/RestrictedPreferenceHelper.java +++ b/src/com/android/settings/RestrictedPreferenceHelper.java @@ -53,10 +53,7 @@ public class RestrictedPreferenceHelper { mContext = context; mPreference = preference; - mRestrictedPadlock = mContext.getDrawable(R.drawable.ic_settings_lock_outline); - final int iconSize = mContext.getResources().getDimensionPixelSize( - R.dimen.restricted_lock_icon_size); - mRestrictedPadlock.setBounds(0, 0, iconSize, iconSize); + mRestrictedPadlock = getRestrictedPadlock(mContext); mRestrictedPadlockPadding = mContext.getResources().getDimensionPixelSize( R.dimen.restricted_lock_icon_padding); @@ -192,4 +189,15 @@ public class RestrictedPreferenceHelper { public boolean isDisabledByAdmin() { return mDisabledByAdmin; } + + /** + * @return drawables for displaying with settings that are locked by a device admin. + */ + public static Drawable getRestrictedPadlock(Context context) { + Drawable restrictedPadlock = context.getDrawable(R.drawable.ic_settings_lock_outline); + final int iconSize = context.getResources().getDimensionPixelSize( + R.dimen.restricted_lock_icon_size); + restrictedPadlock.setBounds(0, 0, iconSize, iconSize); + return restrictedPadlock; + } } diff --git a/src/com/android/settings/ShowAdminSupportDetailsDialog.java b/src/com/android/settings/ShowAdminSupportDetailsDialog.java index 42e8f052865..85e90cf8d87 100644 --- a/src/com/android/settings/ShowAdminSupportDetailsDialog.java +++ b/src/com/android/settings/ShowAdminSupportDetailsDialog.java @@ -17,24 +17,57 @@ package com.android.settings; import android.app.Activity; +import android.app.ActivityManagerNative; import android.app.AlertDialog; +import android.app.AppGlobals; +import android.app.IActivityManager; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; 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.RemoteException; +import android.os.UserHandle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; +import android.widget.ImageView; import android.widget.TextView; public class ShowAdminSupportDetailsDialog extends Activity implements DialogInterface.OnDismissListener { + private final String TAG = "AdminSupportDialog"; + + private DevicePolicyManager mDpm; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mDpm = getSystemService(DevicePolicyManager.class); + ComponentName admin = null; + int userId = UserHandle.myUserId(); + Intent intent = getIntent(); + if (intent != null) { + IActivityManager am = ActivityManagerNative.getDefault(); + try { + int uid = am.getLaunchedFromUid(getActivityToken()); + // Only allow system to specify admin and user. + if (UserHandle.isSameApp(uid, android.os.Process.myUid())) { + admin = intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN); + userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId()); + } + } catch (RemoteException e) { + Log.e(TAG, "Could not talk to activity manager.", e); + } + } + View rootView = LayoutInflater.from(this).inflate( R.layout.admin_support_details_dialog, null); - setAdminSupportDetails(rootView); + setAdminSupportDetails(rootView, admin, userId); new AlertDialog.Builder(this) .setView(rootView) @@ -43,24 +76,47 @@ public class ShowAdminSupportDetailsDialog extends Activity .show(); } - private void setAdminSupportDetails(View root) { - CharSequence adminDisabledMsg = getString(R.string.disabled_by_admin_msg, - getString(R.string.default_organisation_name)); - TextView textView = (TextView) root.findViewById(R.id.disabled_by_admin_msg); - textView.setText(adminDisabledMsg); + private void setAdminSupportDetails(View root, final ComponentName admin, final int userId) { + if (admin != null) { + CharSequence supportMessage = mDpm.getShortSupportMessageForUser(admin, userId); + if (supportMessage != null) { + TextView textView = (TextView) root.findViewById(R.id.admin_support_msg); + textView.setText(supportMessage); + } - CharSequence adminSupportDetails = getString(R.string.default_admin_support_msg); - textView = (TextView) root.findViewById(R.id.admin_support_msg); - textView.setText(adminSupportDetails); + 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); + } + } root.findViewById(R.id.admins_policies_list).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); - intent.setClass(ShowAdminSupportDetailsDialog.this, - Settings.DeviceAdminSettingsActivity.class); - startActivity(intent); + if (admin != null) { + intent.setClass(ShowAdminSupportDetailsDialog.this, + DeviceAdminAdd.class); + intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin); + // DeviceAdminAdd class may need to run as managed profile. + startActivityAsUser(intent, new UserHandle(userId)); + } else { + intent.setClass(ShowAdminSupportDetailsDialog.this, + Settings.DeviceAdminSettingsActivity.class); + // Activity merges both managed profile and parent users + // admins so show as same user as this activity. + startActivity(intent); + } finish(); } }); @@ -70,4 +126,4 @@ public class ShowAdminSupportDetailsDialog extends Activity public void onDismiss(DialogInterface dialog) { finish(); } -} \ No newline at end of file +} diff --git a/src/com/android/settings/users/UserDialogs.java b/src/com/android/settings/users/UserDialogs.java index 23012b3f3bc..3ed383a6251 100644 --- a/src/com/android/settings/users/UserDialogs.java +++ b/src/com/android/settings/users/UserDialogs.java @@ -55,13 +55,7 @@ public final class UserDialogs { AlertDialog.Builder builder = new AlertDialog.Builder(context) .setPositiveButton(R.string.user_delete_button, onConfirmListener) .setNegativeButton(android.R.string.cancel, null); - if (UserHandle.myUserId() == removingUserId) { - builder.setTitle(R.string.user_confirm_remove_self_title); - builder.setMessage(R.string.user_confirm_remove_self_message); - } else if (userInfo.isRestricted()) { - builder.setTitle(R.string.user_profile_confirm_remove_title); - builder.setMessage(R.string.user_profile_confirm_remove_message); - } else if (userInfo.isManagedProfile()) { + if (userInfo.isManagedProfile()) { builder.setTitle(R.string.work_profile_confirm_remove_title); View view = createRemoveManagedUserDialogView(context, removingUserId); if (view != null) { @@ -69,6 +63,12 @@ public final class UserDialogs { } else { builder.setMessage(R.string.work_profile_confirm_remove_message); } + } else if (UserHandle.myUserId() == removingUserId) { + builder.setTitle(R.string.user_confirm_remove_self_title); + builder.setMessage(R.string.user_confirm_remove_self_message); + } else if (userInfo.isRestricted()) { + builder.setTitle(R.string.user_profile_confirm_remove_title); + builder.setMessage(R.string.user_profile_confirm_remove_message); } else { builder.setTitle(R.string.user_confirm_remove_title); builder.setMessage(R.string.user_confirm_remove_message);