Improve content of existing managed profile deletion dialog.

The profile deletion confirmation dialog now contains:
* Icon for the MDM managing the profile.
* Name of the MDM.

Bug: 19070402
Change-Id: Ie280d7c5eb8a464be96843f61195c2e2bf5b8ec1
diff --git a/res/layout/delete_managed_profile_dialog.xml b/res/layout/delete_managed_profile_dialog.xml
new file mode 100644
index 0000000..795d3eb
--- /dev/null
+++ b/res/layout/delete_managed_profile_dialog.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/DialogFragmentTextContainer">
+
+    <ScrollView
+        android:layout_weight="1"
+        android:layout_height="0dp"
+        style="@style/ScrollView">
+
+        <LinearLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:orientation="vertical">
+
+            <TextView
+                android:id="@+id/delete_managed_profile_opening_paragraph"
+                android:text="@string/opening_paragraph_delete_profile_unknown_company"
+                style="@style/MainText"/>
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/row_height"
+                android:paddingTop="@dimen/row_padding_top"
+                android:layout_alignParentLeft="true"
+                android:layout_centerInParent="true"
+                android:layout_gravity="center_vertical">
+                <ImageView
+                    android:id="@+id/delete_managed_profile_mdm_icon_view"
+                    android:layout_width="@dimen/icon_width_height"
+                    android:layout_height="@dimen/icon_width_height"
+                    android:scaleType="center"/>
+                <TextView
+                    android:id="@+id/delete_managed_profile_device_manager_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:paddingLeft="@dimen/main_text_padding_left_right"
+                    android:gravity="center_vertical"
+                    android:textColor="@color/text_black"
+                    android:textSize="@dimen/main_text_size"/>
+            </LinearLayout>
+
+            <TextView
+                android:id="@+id/delete_managed_profile_read_more_link"
+                android:text="@string/read_more_delete_profile"
+                android:visibility="gone"
+                style="@style/MainText"/>
+
+            <TextView
+                android:id="@+id/delete_managed_profile_closing_paragraph"
+                android:text="@string/sure_you_want_to_delete_profile"
+                style="@style/MainText"/>
+
+        </LinearLayout>
+
+    </ScrollView>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/row_height"
+        android:paddingTop="@dimen/row_padding_top">
+
+        <Button
+            android:id="@+id/delete_managed_profile_positive_button"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentBottom="true"
+            android:text="@string/delete_profile"
+            android:textColor="@color/colored_button"
+            style="@style/TransparentButton" />
+
+        <Button
+            android:id="@+id/delete_managed_profile_negative_button"
+            android:layout_alignParentBottom="true"
+            android:layout_toLeftOf="@id/delete_managed_profile_positive_button"
+            android:text="@string/cancel_delete_profile"
+            style="@style/TransparentButton" />
+
+    </RelativeLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b366e19..7bde082 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -53,10 +53,23 @@
   <!-- Default profile name used for the creation of work profiles. [CHAR LIMIT=NONE] -->
   <string name="default_managed_profile_name">Work profile</string>
 
+  <!-- Title on the dialog that prompts the user to confirm that they really want to delete their existing work profile-->
+  <string name="delete_profile_title">Remove work profile?</string>
+  <!-- Opening string on the dialog that prompts the user to confirm that they really want to delete
+       their existing work profile. The administration app icon and name appear after the final
+       colon. [CHAR LIMIT=NONE] -->
+  <string name="opening_paragraph_delete_profile_unknown_company">This work profile is managed by:</string>
+    <!-- Opening string on the dialog that prompts the user to confirm that they really want to delete
+         their existing work profile. The administration app icon and name appear after the final
+         colon, the %s is replaced by the domain name of the organization that owns the work
+         profile. [CHAR LIMIT=NONE] -->
+  <string name="opening_paragraph_delete_profile_known_company">This work profile is managed for %s using:</string>
+  <!-- String on the dialog that links through to more information about the profile management application. -->
+  <string name="read_more_delete_profile">Please <a href="#read_this_link">read this</a> before proceeding.</string>
   <!-- String on the dialog that prompts the user to confirm that they really want to delete their existing work profile-->
-  <string name="sure_you_want_to_delete_profile">You already have a work profile on your device, it must be removed to setup a new profile. All apps and data in this profile will be deleted if you continue.</string>
+  <string name="sure_you_want_to_delete_profile">All apps and data in this profile will be deleted if you continue.</string>
   <!-- String on the button that triggers the deletion of a work profile.-->
-  <string name="delete_profile">Remove</string>
+  <string name="delete_profile">Delete</string>
   <!-- String on the button that cancels out of the deletion of a work profile.-->
   <string name="cancel_delete_profile">Cancel</string>
 
diff --git a/src/com/android/managedprovisioning/DeleteManagedProfileDialog.java b/src/com/android/managedprovisioning/DeleteManagedProfileDialog.java
new file mode 100644
index 0000000..f32787f
--- /dev/null
+++ b/src/com/android/managedprovisioning/DeleteManagedProfileDialog.java
@@ -0,0 +1,142 @@
+package com.android.managedprovisioning;
+/*
+ * Copyright 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.
+ */
+
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.managedprovisioning.Utils.MdmPackageInfo;
+
+/**
+ * Displays information about an existing managed profile and asks the user if it should be deleted.
+ *
+ * <p>Expects parent component to implement {@link DeleteManagedProfileCallback} for user-response
+ * handling.
+ */
+public class DeleteManagedProfileDialog extends DialogFragment {
+    private static final String KEY_USER_PROFILE_CALLBACK_ID = "user_profile_callback_id";
+    private static final String KEY_MDM_PACKAGE_NAME = "mdm_package_name";
+    private static final String KEY_PROFILE_OWNER_DOMAIN = "profile_owner_domain";
+
+    /**
+     * @param managedProfileUserId user-id for the managed profile which will be passed back to the
+     *     parent component in the {@link DeleteManagedProfileCallback#onRemoveProfileApproval(int)}
+     *     call
+     * @param mdmPackagename package name of the MDM application for the current managed profile
+     * @param profileOwnerDomain domain name of the organization which owns the managed profile, or
+     *     null if not known
+     * @return initialized dialog
+     */
+    public static DeleteManagedProfileDialog newInstance(
+            int managedProfileUserId, ComponentName mdmPackagename, String profileOwnerDomain) {
+        Bundle args = new Bundle();
+        args.putInt(KEY_USER_PROFILE_CALLBACK_ID, managedProfileUserId);
+        args.putString(KEY_MDM_PACKAGE_NAME, mdmPackagename.getPackageName());
+        args.putString(KEY_PROFILE_OWNER_DOMAIN, profileOwnerDomain);
+
+        DeleteManagedProfileDialog dialog = new DeleteManagedProfileDialog();
+        dialog.setArguments(args);
+        return dialog;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        if (!(getActivity() instanceof DeleteManagedProfileCallback)) {
+            throw new IllegalStateException("Calling activity must implement " +
+                    "DeleteManagedProfileCallback, found: " + getActivity().getLocalClassName());
+        }
+
+        Bundle arguments = getArguments();
+        final int callbackUserProfileId = arguments.getInt(KEY_USER_PROFILE_CALLBACK_ID);
+        String mdmPackageName = arguments.getString(KEY_MDM_PACKAGE_NAME);
+
+        MdmPackageInfo mdmPackageInfo = Utils.getMdmPackageInfo(
+                getActivity().getPackageManager(), mdmPackageName);
+
+        final Dialog dialog = new Dialog(getActivity(), R.style.ManagedProvisioningDialogTheme);
+        dialog.setTitle(R.string.delete_profile_title);
+        dialog.setContentView(R.layout.delete_managed_profile_dialog);
+        dialog.setCanceledOnTouchOutside(false);
+
+        ImageView imageView = (ImageView) dialog.findViewById(
+                R.id.delete_managed_profile_mdm_icon_view);
+        imageView.setImageDrawable(mdmPackageInfo.getPackageIcon());
+
+        TextView deviceManagerName = (TextView) dialog.findViewById(
+                R.id.delete_managed_profile_device_manager_name);
+        deviceManagerName.setText(mdmPackageInfo.getAppLabel());
+
+        Button positiveButton = (Button) dialog.findViewById(
+                R.id.delete_managed_profile_positive_button);
+        positiveButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    dialog.dismiss();
+                    ((DeleteManagedProfileCallback) getActivity())
+                            .onRemoveProfileApproval(callbackUserProfileId);
+                }
+            });
+
+        Button negativeButton = (Button) dialog.findViewById(
+                R.id.delete_managed_profile_negative_button);
+        negativeButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    dialog.dismiss();
+                    ((DeleteManagedProfileCallback) getActivity()).onRemoveProfileCancel();
+                }
+            });
+
+        dialog.getWindow().getDecorView().setSystemUiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+        return dialog;
+    }
+
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        dialog.dismiss();
+        ((DeleteManagedProfileCallback) getActivity()).onRemoveProfileCancel();
+    }
+
+    /**
+     * Callback interface for outcome of {@link DeleteManagedProfileDialog} presentation.
+     */
+    public interface DeleteManagedProfileCallback {
+
+        /**
+         * Invoked if the user hits the positive response (perform removal) button.
+         *
+         * @param managedProfileUserId user-id of the managed-profile that the dialog was presented
+         *                             for
+         */
+        public abstract void onRemoveProfileApproval(int managedProfileUserId);
+
+        /**
+         * Invoked if the user hits the negative response (DO NOT perform removal) button, or the
+         * dialog was otherwise dismissed.
+         */
+        public abstract void onRemoveProfileCancel();
+    }
+}
diff --git a/src/com/android/managedprovisioning/ProfileOwnerPreProvisioningActivity.java b/src/com/android/managedprovisioning/ProfileOwnerPreProvisioningActivity.java
index efac6e0..c77777c 100644
--- a/src/com/android/managedprovisioning/ProfileOwnerPreProvisioningActivity.java
+++ b/src/com/android/managedprovisioning/ProfileOwnerPreProvisioningActivity.java
@@ -16,27 +16,17 @@
 
 package com.android.managedprovisioning;
 
-import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
-import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
-import static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME;
-import static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME_TARGET;
-import static com.android.managedprovisioning.EncryptDeviceActivity.TARGET_PROFILE_OWNER;
-
 import android.app.Activity;
-import android.app.admin.DevicePolicyManager;
 import android.app.AlertDialog;
+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.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
-import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.PersistableBundle;
@@ -44,26 +34,34 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
-import android.widget.Button;
 
+import com.android.managedprovisioning.DeleteManagedProfileDialog.DeleteManagedProfileCallback;
+import com.android.managedprovisioning.UserConsentDialog.ConsentCallback;
 import com.android.managedprovisioning.Utils.IllegalProvisioningArgumentException;
+import com.android.managedprovisioning.Utils.MdmPackageInfo;
 import com.android.setupwizard.navigationbar.SetupWizardNavBar;
 import com.android.setupwizard.navigationbar.SetupWizardNavBar.NavigationBarListener;
 
 import java.util.List;
 
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
+import static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME;
+import static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME_TARGET;
+import static com.android.managedprovisioning.EncryptDeviceActivity.TARGET_PROFILE_OWNER;
+
 /**
  * The activity sets up the environment in which the {@link ProfileOwnerProvisioningActivity} can be run.
  * It makes sure the device is encrypted, the current launcher supports managed profiles, the
  * provisioning intent extras are valid, and that the already present managed profile is removed.
  */
 public class ProfileOwnerPreProvisioningActivity extends Activity
-        implements UserConsentDialog.ConsentCallback, NavigationBarListener {
+        implements ConsentCallback, DeleteManagedProfileCallback, NavigationBarListener {
 
     private static final String MANAGE_USERS_PERMISSION = "android.permission.MANAGE_USERS";
 
@@ -93,6 +91,8 @@
 
     private Button mSetupButton;
 
+    private DeleteManagedProfileDialog mDeleteDialog;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -157,11 +157,11 @@
             return;
         }
 
-        // If there is already a managed profile, allow the user to cancel or delete it.
+        // If there is already a managed profile, setup the profile deletion dialog.
         // Otherwise, check whether system has reached maximum user limit.
         int existingManagedProfileUserId = alreadyHasManagedProfile();
         if (existingManagedProfileUserId != -1) {
-            showManagedProfileExistsDialog(existingManagedProfileUserId);
+            createDeleteManagedProfileDialog(dpm, existingManagedProfileUserId);
         } else if (isMaximumUserLimitReached()) {
             showErrorAndClose(R.string.maximum_user_limit_reached,
                     "Exiting managed profile provisioning, cannot add more users.");
@@ -170,6 +170,22 @@
         }
     }
 
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        if (alreadyHasManagedProfile() != -1) {
+            showDeleteManagedProfileDialog();
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        hideDeleteManagedProfileDialog();
+    }
+
     private void showStartProvisioningButton() {
         mSetupButton.setVisibility(View.VISIBLE);
     }
@@ -217,23 +233,13 @@
     }
 
     private void setMdmIcon(String packageName) {
-        if (packageName != null) {
-            PackageManager pm = getPackageManager();
-            try {
-                ApplicationInfo ai = pm.getApplicationInfo(packageName, /* default flags */ 0);
-                if (ai != null) {
-                    Drawable packageIcon = pm.getApplicationIcon(packageName);
-                    ImageView imageView = (ImageView) findViewById(R.id.mdm_icon_view);
-                    imageView.setImageDrawable(packageIcon);
+        MdmPackageInfo packageInfo = Utils.getMdmPackageInfo(getPackageManager(), packageName);
+        if (packageInfo != null) {
+            ImageView imageView = (ImageView) findViewById(R.id.mdm_icon_view);
+            imageView.setImageDrawable(packageInfo.getPackageIcon());
 
-                    String appLabel = pm.getApplicationLabel(ai).toString();
-                    TextView deviceManagerName = (TextView) findViewById(R.id.device_manager_name);
-                    deviceManagerName.setText(appLabel);
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                // Package does not exist, ignore. Should never happen.
-                ProvisionLogger.loge("Package does not exist. Should never happen.");
-            }
+            TextView deviceManagerName = (TextView) findViewById(R.id.device_manager_name);
+            deviceManagerName.setText(packageInfo.getAppLabel());
         }
     }
 
@@ -292,6 +298,19 @@
         // Do nothing.
     }
 
+    @Override
+    public void onRemoveProfileApproval(int existingManagedProfileUserId) {
+        mDeleteDialog = null;
+        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        userManager.removeUser(existingManagedProfileUserId);
+        showStartProvisioningButton();
+    }
+
+    @Override
+    public void onRemoveProfileCancel() {
+        finish();
+    }
+
     private void setupEnvironmentAndProvision() {
         // Remove any pre-provisioning UI in favour of progress display
         BootReminder.cancelProvisioningReminder(this);
@@ -410,35 +429,36 @@
     /**
      * Builds a dialog that allows the user to remove an existing managed profile.
      */
-    private void showManagedProfileExistsDialog(
-            final int existingManagedProfileUserId) {
+    private void createDeleteManagedProfileDialog(DevicePolicyManager dpm,
+            int existingManagedProfileUserId) {
+        if (mDeleteDialog != null) {
+            return;
+        }
 
-        DialogInterface.OnClickListener deleteListener =
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                UserManager userManager =
-                        (UserManager) getSystemService(Context.USER_SERVICE);
-                userManager.removeUser(existingManagedProfileUserId);
-                showStartProvisioningButton();
-            }
-        };
+        ComponentName mdmPackageName = dpm.getProfileOwnerAsUser(existingManagedProfileUserId);
+        String domainName = dpm.getProfileOwnerNameAsUser(existingManagedProfileUserId);
 
-        DialogInterface.OnClickListener cancelListener =
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                ProfileOwnerPreProvisioningActivity.this.finish();
-            }
-        };
+        mDeleteDialog = DeleteManagedProfileDialog.newInstance(existingManagedProfileUserId,
+                mdmPackageName, domainName);
+    }
 
-        AlertDialog.Builder builder = new AlertDialog.Builder(this);
-        builder.setMessage(getString(R.string.sure_you_want_to_delete_profile))
-                .setCancelable(false)
-                .setPositiveButton(getString(R.string.delete_profile), deleteListener)
-                .setNegativeButton(getString(R.string.cancel_delete_profile), cancelListener)
-                .show()
-                .getWindow().getDecorView().setSystemUiVisibility(IMMERSIVE_FLAGS);
+    private void showDeleteManagedProfileDialog() {
+        if (mDeleteDialog == null) {
+            return;
+        }
+
+        if (!mDeleteDialog.isVisible()) {
+            mDeleteDialog.show(getFragmentManager(), "DeleteManagedProfileDialogFragment");
+        }
+    }
+
+    private void hideDeleteManagedProfileDialog() {
+        if (mDeleteDialog == null) {
+            return;
+        }
+
+        mDeleteDialog.dismiss();
+        mDeleteDialog = null;
     }
 
     @Override
diff --git a/src/com/android/managedprovisioning/Utils.java b/src/com/android/managedprovisioning/Utils.java
index bd05bc5..f69d64d 100644
--- a/src/com/android/managedprovisioning/Utils.java
+++ b/src/com/android/managedprovisioning/Utils.java
@@ -16,30 +16,33 @@
 
 package com.android.managedprovisioning;
 
-import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
-import static  android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
-
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.ComponentName;
-import android.content.Intent;
+import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.text.TextUtils;
 
-import java.util.List;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
+
 /**
  * Class containing various auxiliary methods.
  */
 public class Utils {
+    private Utils() {}
+
     public static Set<String> getCurrentSystemApps(int userId) {
         IPackageManager ipm = IPackageManager.Stub.asInterface(ServiceManager
                 .getService("package"));
@@ -174,4 +177,42 @@
         }
         return mdmComponentName;
     }
+
+    public static MdmPackageInfo getMdmPackageInfo(PackageManager pm, String packageName) {
+        if (packageName != null) {
+            try {
+                ApplicationInfo ai = pm.getApplicationInfo(packageName, /* default flags */ 0);
+                if (ai != null) {
+                    return new MdmPackageInfo(pm.getApplicationIcon(packageName),
+                            pm.getApplicationLabel(ai).toString());
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                // Package does not exist, ignore. Should never happen.
+                ProvisionLogger.loge("Package does not exist. Should never happen.");
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Information relating to the currently installed MDM package manager.
+     */
+    public static final class MdmPackageInfo {
+        private final Drawable packageIcon;
+        private final String appLabel;
+
+        private MdmPackageInfo(Drawable packageIcon, String appLabel) {
+            this.packageIcon = packageIcon;
+            this.appLabel = appLabel;
+        }
+
+        public String getAppLabel() {
+            return appLabel;
+        }
+
+        public Drawable getPackageIcon() {
+            return packageIcon;
+        }
+    }
 }