Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ea138cb authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

More work on device admins:

- You can now show a dynamic message to the user when asking to
  have your DeviceAdmin added.
- A DeviceAdmin can now provide a warning message that is displayed
  before a user disables it.
- Better ordering (and text) of the policy warnings.
- New API to set the maximum failed password attempts before the device
  wipes itself.
- We now store the number of failed unlock attempts in persistent
  storage.
- New managed dialog APIs that will be used by the settings app.

Also a little bit of cleanup as I was working on this - removed the
long unused MailboxNotAvailableException, fixed a java doc in Messenger.
parent 2fc1f4a0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ LOCAL_SRC_FILES += \
	core/java/android/os/IParentalControlCallback.aidl \
	core/java/android/os/IPermissionController.aidl \
	core/java/android/os/IPowerManager.aidl \
    core/java/android/os/IRemoteCallback.aidl \
	core/java/android/os/IVibratorService.aidl \
    core/java/android/service/wallpaper/IWallpaperConnection.aidl \
    core/java/android/service/wallpaper/IWallpaperEngine.aidl \
+110 −0
Original line number Diff line number Diff line
@@ -16169,6 +16169,19 @@
 visibility="public"
>
</method>
<method name="onCreateDialog"
 return="android.app.Dialog"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="deprecated"
 visibility="protected"
>
<parameter name="id" type="int">
</parameter>
</method>
<method name="onCreateDialog"
 return="android.app.Dialog"
 abstract="false"
@@ -16181,6 +16194,8 @@
>
<parameter name="id" type="int">
</parameter>
<parameter name="args" type="android.os.Bundle">
</parameter>
</method>
<method name="onCreateOptionsMenu"
 return="boolean"
@@ -16469,6 +16484,21 @@
 visibility="protected"
>
</method>
<method name="onPrepareDialog"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="deprecated"
 visibility="protected"
>
<parameter name="id" type="int">
</parameter>
<parameter name="dialog" type="android.app.Dialog">
</parameter>
</method>
<method name="onPrepareDialog"
 return="void"
 abstract="false"
@@ -16483,6 +16513,8 @@
</parameter>
<parameter name="dialog" type="android.app.Dialog">
</parameter>
<parameter name="args" type="android.os.Bundle">
</parameter>
</method>
<method name="onPrepareOptionsMenu"
 return="boolean"
@@ -17110,6 +17142,21 @@
<parameter name="id" type="int">
</parameter>
</method>
<method name="showDialog"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="id" type="int">
</parameter>
<parameter name="args" type="android.os.Bundle">
</parameter>
</method>
<method name="startActivityForResult"
 return="void"
 abstract="false"
@@ -19895,6 +19942,21 @@
<parameter name="context" type="android.content.Context">
</parameter>
</method>
<method name="onDisableRequested"
 return="java.lang.CharSequence"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="intent" type="android.content.Intent">
</parameter>
</method>
<method name="onDisabled"
 return="void"
 abstract="false"
@@ -19996,6 +20058,17 @@
 visibility="public"
>
</field>
<field name="ACTION_DEVICE_ADMIN_DISABLE_REQUESTED"
 type="java.lang.String"
 transient="false"
 volatile="false"
 value="&quot;android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED&quot;"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ACTION_DEVICE_ADMIN_ENABLED"
 type="java.lang.String"
 transient="false"
@@ -20051,6 +20124,17 @@
 visibility="public"
>
</field>
<field name="EXTRA_DISABLE_WARNING"
 type="java.lang.String"
 transient="false"
 volatile="false"
 value="&quot;android.app.extra.DISABLE_WARNING&quot;"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
</class>
<class name="DeviceAdminInfo"
 extends="java.lang.Object"
@@ -20420,6 +20504,21 @@
<parameter name="password" type="java.lang.String">
</parameter>
</method>
<method name="setMaximumFailedPasswordsForWipe"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="admin" type="android.content.ComponentName">
</parameter>
<parameter name="num" type="int">
</parameter>
</method>
<method name="setMaximumTimeToLock"
 return="void"
 abstract="false"
@@ -20500,6 +20599,17 @@
 visibility="public"
>
</field>
<field name="EXTRA_ADD_EXPLANATION"
 type="java.lang.String"
 transient="false"
 volatile="false"
 value="&quot;android.app.extra.ADD_EXPLANATION&quot;"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="EXTRA_DEVICE_ADMIN"
 type="java.lang.String"
 transient="false"
+115 −57
Original line number Diff line number Diff line
@@ -609,8 +609,13 @@ public class Activity extends ContextThemeWrapper
    private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds";
    private static final String SAVED_DIALOGS_TAG = "android:savedDialogs";
    private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_";
    private static final String SAVED_DIALOG_ARGS_KEY_PREFIX = "android:dialog_args_";

    private SparseArray<Dialog> mManagedDialogs;
    private static class ManagedDialog {
        Dialog mDialog;
        Bundle mArgs;
    }
    private SparseArray<ManagedDialog> mManagedDialogs;

    // set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called.
    private Instrumentation mInstrumentation;
@@ -851,35 +856,41 @@ public class Activity extends ContextThemeWrapper

        final int[] ids = b.getIntArray(SAVED_DIALOG_IDS_KEY);
        final int numDialogs = ids.length;
        mManagedDialogs = new SparseArray<Dialog>(numDialogs);
        mManagedDialogs = new SparseArray<ManagedDialog>(numDialogs);
        for (int i = 0; i < numDialogs; i++) {
            final Integer dialogId = ids[i];
            Bundle dialogState = b.getBundle(savedDialogKeyFor(dialogId));
            if (dialogState != null) {
                // Calling onRestoreInstanceState() below will invoke dispatchOnCreate
                // so tell createDialog() not to do it, otherwise we get an exception
                final Dialog dialog = createDialog(dialogId, dialogState);
                mManagedDialogs.put(dialogId, dialog);
                onPrepareDialog(dialogId, dialog);
                dialog.onRestoreInstanceState(dialogState);
                final ManagedDialog md = new ManagedDialog();
                md.mArgs = b.getBundle(savedDialogArgsKeyFor(dialogId));
                md.mDialog = createDialog(dialogId, dialogState, md.mArgs);
                if (md.mDialog != null) {
                    mManagedDialogs.put(dialogId, md);
                    onPrepareDialog(dialogId, md.mDialog, md.mArgs);
                    md.mDialog.onRestoreInstanceState(dialogState);
                }
            }
        }
    }

    private Dialog createDialog(Integer dialogId, Bundle state) {
        final Dialog dialog = onCreateDialog(dialogId);
    private Dialog createDialog(Integer dialogId, Bundle state, Bundle args) {
        final Dialog dialog = onCreateDialog(dialogId, args);
        if (dialog == null) {
            throw new IllegalArgumentException("Activity#onCreateDialog did "
                    + "not create a dialog for id " + dialogId);
            return null;
        }
        dialog.dispatchOnCreate(state);
        return dialog;
    }

    private String savedDialogKeyFor(int key) {
    private static String savedDialogKeyFor(int key) {
        return SAVED_DIALOG_KEY_PREFIX + key;
    }

    private static String savedDialogArgsKeyFor(int key) {
        return SAVED_DIALOG_ARGS_KEY_PREFIX + key;
    }

    /**
     * Called when activity start-up is complete (after {@link #onStart}
@@ -1096,8 +1107,11 @@ public class Activity extends ContextThemeWrapper
        for (int i = 0; i < numDialogs; i++) {
            final int key = mManagedDialogs.keyAt(i);
            ids[i] = key;
            final Dialog dialog = mManagedDialogs.valueAt(i);
            dialogState.putBundle(savedDialogKeyFor(key), dialog.onSaveInstanceState());
            final ManagedDialog md = mManagedDialogs.valueAt(i);
            dialogState.putBundle(savedDialogKeyFor(key), md.mDialog.onSaveInstanceState());
            if (md.mArgs != null) {
                dialogState.putBundle(savedDialogArgsKeyFor(key), md.mArgs);
            }
        }

        dialogState.putIntArray(SAVED_DIALOG_IDS_KEY, ids);
@@ -1283,14 +1297,14 @@ public class Activity extends ContextThemeWrapper

        // dismiss any dialogs we are managing.
        if (mManagedDialogs != null) {

            final int numDialogs = mManagedDialogs.size();
            for (int i = 0; i < numDialogs; i++) {
                final Dialog dialog = mManagedDialogs.valueAt(i);
                if (dialog.isShowing()) {
                    dialog.dismiss();
                final ManagedDialog md = mManagedDialogs.valueAt(i);
                if (md.mDialog.isShowing()) {
                    md.mDialog.dismiss();
                }
            }
            mManagedDialogs = null;
        }

        // close any cursors we are managing.
@@ -1301,6 +1315,7 @@ public class Activity extends ContextThemeWrapper
                c.mCursor.close();
            }
        }
        mManagedCursors.clear();
    }

    /**
@@ -2410,37 +2425,58 @@ public class Activity extends ContextThemeWrapper
        }
    }

    /**
     * @deprecated Old no-arguments version of {@link #onCreateDialog(int, Bundle)}.
     */
    @Deprecated
    protected Dialog onCreateDialog(int id) {
        return null;
    }

    /**
     * Callback for creating dialogs that are managed (saved and restored) for you
     * by the activity.
     * by the activity.  The default implementation calls through to
     * {@link #onCreateDialog(int)} for compatibility.
     *
     * If you use {@link #showDialog(int)}, the activity will call through to
     * <p>If you use {@link #showDialog(int)}, the activity will call through to
     * this method the first time, and hang onto it thereafter.  Any dialog
     * that is created by this method will automatically be saved and restored
     * for you, including whether it is showing.
     *
     * If you would like the activity to manage the saving and restoring dialogs
     * <p>If you would like the activity to manage saving and restoring dialogs
     * for you, you should override this method and handle any ids that are
     * passed to {@link #showDialog}.
     *
     * If you would like an opportunity to prepare your dialog before it is shown,
     * override {@link #onPrepareDialog(int, Dialog)}.
     * <p>If you would like an opportunity to prepare your dialog before it is shown,
     * override {@link #onPrepareDialog(int, Dialog, Bundle)}.
     *
     * @param id The id of the dialog.
     * @return The dialog
     * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}.
     * @return The dialog.  If you return null, the dialog will not be created.
     *
     * @see #onPrepareDialog(int, Dialog)
     * @see #showDialog(int)
     * @see #onPrepareDialog(int, Dialog, Bundle)
     * @see #showDialog(int, Bundle)
     * @see #dismissDialog(int)
     * @see #removeDialog(int)
     */
    protected Dialog onCreateDialog(int id) {
        return null;
    protected Dialog onCreateDialog(int id, Bundle args) {
        return onCreateDialog(id);
    }

    /**
     * @deprecated Old no-arguments version of
     * {@link #onPrepareDialog(int, Dialog, Bundle)}.
     */
    @Deprecated
    protected void onPrepareDialog(int id, Dialog dialog) {
        dialog.setOwnerActivity(this);
    }

    /**
     * Provides an opportunity to prepare a managed dialog before it is being
     * shown.
     * shown.  The default implementation calls through to
     * {@link #onPrepareDialog(int, Dialog)} for compatibility.
     * 
     * <p>
     * Override this if you need to update a managed dialog based on the state
     * of the application each time it is shown. For example, a time picker
@@ -2450,43 +2486,66 @@ public class Activity extends ContextThemeWrapper
     * 
     * @param id The id of the managed dialog.
     * @param dialog The dialog.
     * @see #onCreateDialog(int)
     * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}.
     * @see #onCreateDialog(int, Bundle)
     * @see #showDialog(int)
     * @see #dismissDialog(int)
     * @see #removeDialog(int)
     */
    protected void onPrepareDialog(int id, Dialog dialog) {
        dialog.setOwnerActivity(this);
    protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
        onPrepareDialog(id, dialog);
    }

    /**
     * Show a dialog managed by this activity.  A call to {@link #onCreateDialog(int)}
     * Simple version of {@link #showDialog(int, Bundle)} that does not
     * take any arguments.  Simply calls {@link #showDialog(int, Bundle)}
     * with null arguments.
     */
    public final void showDialog(int id) {
        showDialog(id, null);
    }

    /**
     * Show a dialog managed by this activity.  A call to {@link #onCreateDialog(int, Bundle)}
     * will be made with the same id the first time this is called for a given
     * id.  From thereafter, the dialog will be automatically saved and restored.
     *
     * Each time a dialog is shown, {@link #onPrepareDialog(int, Dialog)} will
     * <p>Each time a dialog is shown, {@link #onPrepareDialog(int, Dialog, Bundle)} will
     * be made to provide an opportunity to do any timely preparation.
     *
     * @param id The id of the managed dialog.
     * @param args Arguments to pass through to the dialog.  These will be saved
     * and restored for you.  Note that if the dialog is already created,
     * {@link #onCreateDialog(int, Bundle)} will not be called with the new
     * arguments but {@link #onPrepareDialog(int, Dialog, Bundle)} will be.
     * If you need to rebuild the dialog, call {@link #removeDialog(int)}Êfirst.
     * @return Returns true if the Dialog was created; false is returned if
     * it is not created because {@link #onCreateDialog(int, Bundle)} returns false.
     * 
     * @see Dialog
     * @see #onCreateDialog(int)
     * @see #onPrepareDialog(int, Dialog)
     * @see #onCreateDialog(int, Bundle)
     * @see #onPrepareDialog(int, Dialog, Bundle)
     * @see #dismissDialog(int)
     * @see #removeDialog(int)
     */
    public final void showDialog(int id) {
    public final boolean showDialog(int id, Bundle args) {
        if (mManagedDialogs == null) {
            mManagedDialogs = new SparseArray<Dialog>();
            mManagedDialogs = new SparseArray<ManagedDialog>();
        }
        Dialog dialog = mManagedDialogs.get(id);
        if (dialog == null) {
            dialog = createDialog(id, null);
            mManagedDialogs.put(id, dialog);
        ManagedDialog md = mManagedDialogs.get(id);
        if (md == null) {
            md = new ManagedDialog();
            md.mDialog = createDialog(id, null, args);
            if (md.mDialog == null) {
                return false;
            }
            mManagedDialogs.put(id, md);
        }
        
        onPrepareDialog(id, dialog);
        dialog.show();
        md.mArgs = args;
        onPrepareDialog(id, md.mDialog, args);
        md.mDialog.show();
        return true;
    }

    /**
@@ -2497,21 +2556,21 @@ public class Activity extends ContextThemeWrapper
     * @throws IllegalArgumentException if the id was not previously shown via
     *   {@link #showDialog(int)}.
     *
     * @see #onCreateDialog(int)
     * @see #onPrepareDialog(int, Dialog)
     * @see #onCreateDialog(int, Bundle)
     * @see #onPrepareDialog(int, Dialog, Bundle)
     * @see #showDialog(int)
     * @see #removeDialog(int)
     */
    public final void dismissDialog(int id) {
        if (mManagedDialogs == null) {
            throw missingDialog(id);

        }
        final Dialog dialog = mManagedDialogs.get(id);
        if (dialog == null) {
        
        final ManagedDialog md = mManagedDialogs.get(id);
        if (md == null) {
            throw missingDialog(id);
        }
        dialog.dismiss();
        md.mDialog.dismiss();
    }

    /**
@@ -2527,28 +2586,27 @@ public class Activity extends ContextThemeWrapper
     * Removes any internal references to a dialog managed by this Activity.
     * If the dialog is showing, it will dismiss it as part of the clean up.
     *
     * This can be useful if you know that you will never show a dialog again and
     * <p>This can be useful if you know that you will never show a dialog again and
     * want to avoid the overhead of saving and restoring it in the future.
     *
     * @param id The id of the managed dialog.
     *
     * @see #onCreateDialog(int)
     * @see #onPrepareDialog(int, Dialog)
     * @see #onCreateDialog(int, Bundle)
     * @see #onPrepareDialog(int, Dialog, Bundle)
     * @see #showDialog(int)
     * @see #dismissDialog(int)
     */
    public final void removeDialog(int id) {

        if (mManagedDialogs == null) {
            return;
        }

        final Dialog dialog = mManagedDialogs.get(id);
        if (dialog == null) {
        final ManagedDialog md = mManagedDialogs.get(id);
        if (md == null) {
            return;
        }

        dialog.dismiss();
        md.mDialog.dismiss();
        mManagedDialogs.remove(id);
    }

+43 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

/**
 * Base class for implementing a device administration component.  This
@@ -61,6 +62,27 @@ public class DeviceAdmin extends BroadcastReceiver {
    public static final String ACTION_DEVICE_ADMIN_ENABLED
            = "android.app.action.DEVICE_ADMIN_ENABLED";

    /**
     * Action sent to a device administrator when the user has requested to
     * disable it, but before this has actually been done.  This gives you
     * a chance to supply a message to the user about the impact of
     * disabling your admin, by setting the extra field
     * {@link #EXTRA_DISABLE_WARNING} in the result Intent.  If not set,
     * no warning will be displayed.  If set, the given text will be shown
     * to the user before they disable your admin.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
            = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
    
    /**
     * A CharSequence that can be shown to the user informing them of the
     * impact of disabling your admin.
     *
     * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
     */
    public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
    
    /**
     * Action sent to a device administrator when the user has disabled
     * it.  Upon return, the application no longer has access to the
@@ -165,6 +187,21 @@ public class DeviceAdmin extends BroadcastReceiver {
    public void onEnabled(Context context, Intent intent) {
    }
    
    /**
     * Called when the user has asked to disable the administrator, as a result of
     * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
     * a chance to present a warning message to them.  The message is returned
     * as the result; if null is returned (the default implementation), no
     * message will be displayed.
     * @param context The running context as per {@link #onReceive}.
     * @param intent The received intent as per {@link #onReceive}.
     * @return Return the warning message to display to the user before
     * being disabled; if null is returned, no message is displayed.
     */
    public CharSequence onDisableRequested(Context context, Intent intent) {
        return null;
    }
    
    /**
     * Called prior to the administrator being disabled, as a result of
     * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}.  Upon return, you
@@ -226,6 +263,12 @@ public class DeviceAdmin extends BroadcastReceiver {
            onPasswordSucceeded(context, intent);
        } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
            onEnabled(context, intent);
        } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
            CharSequence res = onDisableRequested(context, intent);
            if (res != null) {
                Bundle extras = getResultExtras(true);
                extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
            }
        } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
            onDisabled(context, intent);
        }
+31 −33
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package android.app;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.R;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -111,48 +110,47 @@ public final class DeviceAdminInfo implements Parcelable {

    /** @hide */
    public static class PolicyInfo {
        public final int ident;
        final public String tag;
        final public int label;
        final public int description;
        
        public PolicyInfo(String tagIn, int labelIn, int descriptionIn) {
        public PolicyInfo(int identIn, String tagIn, int labelIn, int descriptionIn) {
            ident = identIn;
            tag = tagIn;
            label = labelIn;
            description = descriptionIn;
        }
    }
    
    static ArrayList<PolicyInfo> sPoliciesDisplayOrder = new ArrayList<PolicyInfo>();
    static HashMap<String, Integer> sKnownPolicies = new HashMap<String, Integer>();
    static SparseArray<PolicyInfo> sRevKnownPolicies = new SparseArray<PolicyInfo>();
    
    static {
        sRevKnownPolicies.put(USES_POLICY_LIMIT_PASSWORD,
                new PolicyInfo("limit-password",
        sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WIPE_DATA, "wipe-data",
                com.android.internal.R.string.policylab_wipeData,
                com.android.internal.R.string.policydesc_wipeData));
        sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_RESET_PASSWORD, "reset-password",
                com.android.internal.R.string.policylab_resetPassword,
                com.android.internal.R.string.policydesc_resetPassword));
        sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_PASSWORD, "limit-password",
                com.android.internal.R.string.policylab_limitPassword,
                com.android.internal.R.string.policydesc_limitPassword));
        sRevKnownPolicies.put(USES_POLICY_WATCH_LOGIN,
                new PolicyInfo("watch-login",
        sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WATCH_LOGIN, "watch-login",
                com.android.internal.R.string.policylab_watchLogin,
                com.android.internal.R.string.policydesc_watchLogin));
        sRevKnownPolicies.put(USES_POLICY_RESET_PASSWORD,
                new PolicyInfo("reset-password",
                        com.android.internal.R.string.policylab_resetPassword,
                        com.android.internal.R.string.policydesc_resetPassword));
        sRevKnownPolicies.put(USES_POLICY_LIMIT_UNLOCK,
                new PolicyInfo("limit-unlock",
        sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_UNLOCK, "limit-unlock",
                com.android.internal.R.string.policylab_limitUnlock,
                com.android.internal.R.string.policydesc_limitUnlock));
        sRevKnownPolicies.put(USES_POLICY_FORCE_LOCK,
                new PolicyInfo("force-lock",
        sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock",
                com.android.internal.R.string.policylab_forceLock,
                com.android.internal.R.string.policydesc_forceLock));
        sRevKnownPolicies.put(USES_POLICY_WIPE_DATA,
                new PolicyInfo("wipe-data",
                        com.android.internal.R.string.policylab_wipeData,
                        com.android.internal.R.string.policydesc_wipeData));
        for (int i=0; i<sRevKnownPolicies.size(); i++) {
            sKnownPolicies.put(sRevKnownPolicies.valueAt(i).tag,
                    sRevKnownPolicies.keyAt(i));
        
        for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
            PolicyInfo pi = sPoliciesDisplayOrder.get(i);
            sRevKnownPolicies.put(pi.ident, pi);
            sKnownPolicies.put(pi.tag, pi.ident);
        }
    }
    
@@ -335,10 +333,10 @@ public final class DeviceAdminInfo implements Parcelable {
    /** @hide */
    public ArrayList<PolicyInfo> getUsedPolicies() {
        ArrayList<PolicyInfo> res = new ArrayList<PolicyInfo>();
        for (int i=0; i<sRevKnownPolicies.size(); i++) {
            int ident = sRevKnownPolicies.keyAt(i);
            if (usesPolicy(ident)) {
                res.add(sRevKnownPolicies.valueAt(i));
        for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
            PolicyInfo pi = sPoliciesDisplayOrder.get(i);
            if (usesPolicy(pi.ident)) {
                res.add(pi);
            }
        }
        return res;
Loading