1
2package com.android.server.am;
3
4import android.app.AlertDialog;
5import android.app.admin.DevicePolicyManager;
6import android.content.Context;
7import android.content.DialogInterface;
8import android.content.DialogInterface.OnClickListener;
9import android.content.res.Resources;
10import android.os.RemoteException;
11import android.os.ServiceManager;
12import android.provider.Settings;
13import android.provider.Settings.SettingNotFoundException;
14import android.util.Slog;
15import android.view.WindowManager;
16import android.view.accessibility.AccessibilityManager;
17import android.widget.CheckBox;
18
19import com.android.internal.R;
20import com.android.internal.widget.ILockSettings;
21import com.android.internal.widget.LockPatternUtils;
22import com.android.internal.widget.LockPatternUtilsCache;
23
24public class LockToAppRequestDialog implements OnClickListener {
25    private static final String TAG = "ActivityManager";
26
27    final private Context mContext;
28    final private ActivityManagerService mService;
29
30    private AlertDialog mDialog;
31    private TaskRecord mRequestedTask;
32
33    private CheckBox mCheckbox;
34
35    private ILockSettings mLockSettingsService;
36
37    private AccessibilityManager mAccessibilityService;
38
39    public LockToAppRequestDialog(Context context, ActivityManagerService activityManagerService) {
40        mContext = context;
41        mAccessibilityService = (AccessibilityManager)
42                mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
43        mService = activityManagerService;
44    }
45
46    private ILockSettings getLockSettings() {
47        if (mLockSettingsService == null) {
48            mLockSettingsService = LockPatternUtilsCache.getInstance(
49                    ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings")));
50        }
51        return mLockSettingsService;
52    }
53
54    private int getLockString(int userId) {
55        try {
56            int quality = (int) getLockSettings().getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
57                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
58            switch (quality) {
59                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
60                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
61                    return R.string.lock_to_app_unlock_pin;
62                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
63                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
64                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
65                    return R.string.lock_to_app_unlock_password;
66                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
67                    if (getLockSettings().getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, false,
68                            userId)) {
69                        return R.string.lock_to_app_unlock_pattern;
70                    }
71            }
72        } catch (RemoteException e) {
73        }
74        return 0;
75    }
76
77    public void clearPrompt() {
78        if (mDialog != null) {
79            mDialog.dismiss();
80            mDialog = null;
81        }
82    }
83
84    public void showLockTaskPrompt(TaskRecord task) {
85        clearPrompt();
86        mRequestedTask = task;
87        final int unlockStringId = getLockString(task.userId);
88
89        final Resources r = Resources.getSystem();
90        final String description= r.getString(mAccessibilityService.isEnabled()
91                ? R.string.lock_to_app_description_accessible
92                : R.string.lock_to_app_description);
93        AlertDialog.Builder builder = new AlertDialog.Builder(mContext)
94                        .setTitle(r.getString(R.string.lock_to_app_title))
95                        .setMessage(description)
96                        .setPositiveButton(r.getString(R.string.lock_to_app_positive), this)
97                        .setNegativeButton(r.getString(R.string.lock_to_app_negative), this);
98        if (unlockStringId != 0) {
99            builder.setView(R.layout.lock_to_app_checkbox);
100        }
101        mDialog = builder.create();
102
103        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
104        mDialog.getWindow().getAttributes().privateFlags |=
105                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
106        mDialog.show();
107
108        if (unlockStringId != 0) {
109            String unlockString = mContext.getString(unlockStringId);
110            mCheckbox = (CheckBox) mDialog.findViewById(R.id.lock_to_app_checkbox);
111            mCheckbox.setText(unlockString);
112
113            // Remember state.
114            try {
115                boolean useLock = Settings.System.getInt(mContext.getContentResolver(),
116                        Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
117                mCheckbox.setChecked(useLock);
118            } catch (SettingNotFoundException e) {
119            }
120        } else {
121            mCheckbox = null;
122        }
123    }
124
125    @Override
126    public void onClick(DialogInterface dialog, int which) {
127        if (DialogInterface.BUTTON_POSITIVE == which) {
128            Slog.d(TAG, "accept lock-to-app request");
129            // Set whether to use the lock screen when exiting.
130            Settings.System.putInt(mContext.getContentResolver(),
131                    Settings.System.LOCK_TO_APP_EXIT_LOCKED,
132                    mCheckbox != null && mCheckbox.isChecked() ? 1 : 0);
133
134            // Start lock-to-app.
135            mService.startLockTaskMode(mRequestedTask);
136        } else {
137            Slog.d(TAG, "ignore lock-to-app request");
138        }
139    }
140
141}
142